Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(478)

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 78733002: Generalize if-conversion to arbitrary smi comparisons. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_
6 #define VM_INTERMEDIATE_LANGUAGE_H_ 6 #define VM_INTERMEDIATE_LANGUAGE_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/ast.h" 9 #include "vm/ast.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
(...skipping 2132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 locs_ = MakeLocationSummary(); 2143 locs_ = MakeLocationSummary();
2144 } 2144 }
2145 return locs_; 2145 return locs_;
2146 } 2146 }
2147 2147
2148 protected: 2148 protected:
2149 EmbeddedArray<Value*, N> inputs_; 2149 EmbeddedArray<Value*, N> inputs_;
2150 2150
2151 private: 2151 private:
2152 friend class BranchInstr; 2152 friend class BranchInstr;
2153 friend class IfThenElseInstr;
2153 2154
2154 virtual void RawSetInputAt(intptr_t i, Value* value) { 2155 virtual void RawSetInputAt(intptr_t i, Value* value) {
2155 inputs_[i] = value; 2156 inputs_[i] = value;
2156 } 2157 }
2157 2158
2158 LocationSummary* locs_; 2159 LocationSummary* locs_;
2159 }; 2160 };
2160 2161
2161 2162
2163 struct BranchLabels {
2164 Label* true_label;
2165 Label* false_label;
2166 Label* fall_through;
2167 };
2168
2169
2162 class ComparisonInstr : public TemplateDefinition<2> { 2170 class ComparisonInstr : public TemplateDefinition<2> {
2163 public: 2171 public:
2164 Value* left() const { return inputs_[0]; } 2172 Value* left() const { return inputs_[0]; }
2165 Value* right() const { return inputs_[1]; } 2173 Value* right() const { return inputs_[1]; }
2166 2174
2167 virtual ComparisonInstr* AsComparison() { return this; } 2175 virtual ComparisonInstr* AsComparison() { return this; }
2168 2176
2169 intptr_t token_pos() const { return token_pos_; } 2177 intptr_t token_pos() const { return token_pos_; }
2170 Token::Kind kind() const { return kind_; } 2178 Token::Kind kind() const { return kind_; }
2171 2179
2180 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
2181
2172 virtual void EmitBranchCode(FlowGraphCompiler* compiler, 2182 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
2173 BranchInstr* branch) = 0; 2183 BranchInstr* branch) = 0;
2174 2184
2185 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
2186 BranchLabels labels) = 0;
2187
2175 void SetDeoptId(intptr_t deopt_id) { 2188 void SetDeoptId(intptr_t deopt_id) {
2176 deopt_id_ = deopt_id; 2189 deopt_id_ = deopt_id;
2177 } 2190 }
2178 2191
2179 // Operation class id is computed from collected ICData. 2192 // Operation class id is computed from collected ICData.
2180 void set_operation_cid(intptr_t value) { operation_cid_ = value; } 2193 void set_operation_cid(intptr_t value) { operation_cid_ = value; }
2181 intptr_t operation_cid() const { return operation_cid_; } 2194 intptr_t operation_cid() const { return operation_cid_; }
2182 2195
2183 void NegateComparison() { 2196 void NegateComparison() {
2184 kind_ = Token::NegateComparison(kind_); 2197 kind_ = Token::NegateComparison(kind_);
(...skipping 13 matching lines...) Expand all
2198 const intptr_t token_pos_; 2211 const intptr_t token_pos_;
2199 Token::Kind kind_; 2212 Token::Kind kind_;
2200 intptr_t operation_cid_; // Set by optimizer. 2213 intptr_t operation_cid_; // Set by optimizer.
2201 2214
2202 DISALLOW_COPY_AND_ASSIGN(ComparisonInstr); 2215 DISALLOW_COPY_AND_ASSIGN(ComparisonInstr);
2203 }; 2216 };
2204 2217
2205 2218
2206 class BranchInstr : public Instruction { 2219 class BranchInstr : public Instruction {
2207 public: 2220 public:
2208 explicit BranchInstr(ComparisonInstr* comparison, bool is_checked = false); 2221 explicit BranchInstr(ComparisonInstr* comparison, bool is_checked = false)
2222 : comparison_(comparison),
2223 is_checked_(is_checked),
2224 constrained_type_(NULL),
2225 constant_target_(NULL) {
2226 ASSERT(comparison->env() == NULL);
2227 for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) {
2228 comparison->InputAt(i)->set_instruction(this);
2229 }
2230 }
2209 2231
2210 DECLARE_INSTRUCTION(Branch) 2232 DECLARE_INSTRUCTION(Branch)
2211 2233
2212 virtual intptr_t ArgumentCount() const { 2234 virtual intptr_t ArgumentCount() const {
2213 return comparison()->ArgumentCount(); 2235 return comparison()->ArgumentCount();
2214 } 2236 }
2215 2237
2216 intptr_t InputCount() const { return comparison()->InputCount(); } 2238 intptr_t InputCount() const { return comparison()->InputCount(); }
2217 2239
2218 Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); } 2240 Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); }
(...skipping 15 matching lines...) Expand all
2234 ComparisonInstr* comparison() const { return comparison_; } 2256 ComparisonInstr* comparison() const { return comparison_; }
2235 void SetComparison(ComparisonInstr* comp); 2257 void SetComparison(ComparisonInstr* comp);
2236 2258
2237 bool is_checked() const { return is_checked_; } 2259 bool is_checked() const { return is_checked_; }
2238 2260
2239 virtual LocationSummary* locs() { 2261 virtual LocationSummary* locs() {
2240 if (comparison()->locs_ == NULL) { 2262 if (comparison()->locs_ == NULL) {
2241 LocationSummary* summary = comparison()->MakeLocationSummary(); 2263 LocationSummary* summary = comparison()->MakeLocationSummary();
2242 // Branches don't produce a result. 2264 // Branches don't produce a result.
2243 summary->set_out(Location::NoLocation()); 2265 summary->set_out(Location::NoLocation());
2266 // The back-end expects the location summary to be stored in the
2267 // comparison.
2244 comparison()->locs_ = summary; 2268 comparison()->locs_ = summary;
2245 } 2269 }
2246 return comparison()->locs_; 2270 return comparison()->locs_;
2247 } 2271 }
2248 2272
2249 virtual intptr_t DeoptimizationTarget() const { 2273 virtual intptr_t DeoptimizationTarget() const {
2250 return comparison()->DeoptimizationTarget(); 2274 return comparison()->DeoptimizationTarget();
2251 } 2275 }
2252 2276
2253 virtual Representation RequiredInputRepresentation(intptr_t i) const { 2277 virtual Representation RequiredInputRepresentation(intptr_t i) const {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2287 TargetEntryInstr* true_successor() const { return true_successor_; } 2311 TargetEntryInstr* true_successor() const { return true_successor_; }
2288 TargetEntryInstr* false_successor() const { return false_successor_; } 2312 TargetEntryInstr* false_successor() const { return false_successor_; }
2289 2313
2290 TargetEntryInstr** true_successor_address() { return &true_successor_; } 2314 TargetEntryInstr** true_successor_address() { return &true_successor_; }
2291 TargetEntryInstr** false_successor_address() { return &false_successor_; } 2315 TargetEntryInstr** false_successor_address() { return &false_successor_; }
2292 2316
2293 virtual intptr_t SuccessorCount() const; 2317 virtual intptr_t SuccessorCount() const;
2294 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 2318 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
2295 2319
2296 private: 2320 private:
2297 virtual void RawSetInputAt(intptr_t i, Value* value); 2321 virtual void RawSetInputAt(intptr_t i, Value* value) {
2322 comparison()->RawSetInputAt(i, value);
2323 }
2298 2324
2299 TargetEntryInstr* true_successor_; 2325 TargetEntryInstr* true_successor_;
2300 TargetEntryInstr* false_successor_; 2326 TargetEntryInstr* false_successor_;
2301 ComparisonInstr* comparison_; 2327 ComparisonInstr* comparison_;
2302 const bool is_checked_; 2328 const bool is_checked_;
2303 ConstrainedCompileType* constrained_type_; 2329 ConstrainedCompileType* constrained_type_;
2304 TargetEntryInstr* constant_target_; 2330 TargetEntryInstr* constant_target_;
2305 2331
2306 DISALLOW_COPY_AND_ASSIGN(BranchInstr); 2332 DISALLOW_COPY_AND_ASSIGN(BranchInstr);
2307 }; 2333 };
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
2879 2905
2880 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); 2906 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr);
2881 }; 2907 };
2882 2908
2883 2909
2884 class StrictCompareInstr : public ComparisonInstr { 2910 class StrictCompareInstr : public ComparisonInstr {
2885 public: 2911 public:
2886 StrictCompareInstr(intptr_t token_pos, 2912 StrictCompareInstr(intptr_t token_pos,
2887 Token::Kind kind, 2913 Token::Kind kind,
2888 Value* left, 2914 Value* left,
2889 Value* right); 2915 Value* right,
2916 bool needs_number_check);
2890 2917
2891 DECLARE_INSTRUCTION(StrictCompare) 2918 DECLARE_INSTRUCTION(StrictCompare)
2919
2920 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
2921
2892 virtual CompileType ComputeType() const; 2922 virtual CompileType ComputeType() const;
2893 2923
2894 virtual void PrintOperandsTo(BufferFormatter* f) const; 2924 virtual void PrintOperandsTo(BufferFormatter* f) const;
2895 2925
2896 virtual bool CanBecomeDeoptimizationTarget() const { 2926 virtual bool CanBecomeDeoptimizationTarget() const {
2897 // StrictCompare can be merged into Branch and thus needs an environment. 2927 // StrictCompare can be merged into Branch and thus needs an environment.
2898 return true; 2928 return true;
2899 } 2929 }
2900 2930
2901 virtual bool CanDeoptimize() const { return false; } 2931 virtual bool CanDeoptimize() const { return false; }
2902 2932
2903 virtual Definition* Canonicalize(FlowGraph* flow_graph); 2933 virtual Definition* Canonicalize(FlowGraph* flow_graph);
2904 2934
2905 virtual void EmitBranchCode(FlowGraphCompiler* compiler, 2935 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
2906 BranchInstr* branch); 2936 BranchInstr* branch);
2907 2937
2938 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
2939 BranchLabels labels);
2940
2908 bool needs_number_check() const { return needs_number_check_; } 2941 bool needs_number_check() const { return needs_number_check_; }
2909 void set_needs_number_check(bool value) { needs_number_check_ = value; } 2942 void set_needs_number_check(bool value) { needs_number_check_ = value; }
2910 2943
2911 virtual bool AllowsCSE() const { return true; } 2944 virtual bool AllowsCSE() const { return true; }
2912 virtual EffectSet Effects() const { return EffectSet::None(); } 2945 virtual EffectSet Effects() const { return EffectSet::None(); }
2913 virtual EffectSet Dependencies() const { return EffectSet::None(); } 2946 virtual EffectSet Dependencies() const { return EffectSet::None(); }
2914 virtual bool AttributesEqual(Instruction* other) const; 2947 virtual bool AttributesEqual(Instruction* other) const;
2915 2948
2916 virtual bool MayThrow() const { return false; } 2949 virtual bool MayThrow() const { return false; }
2917 2950
2918 private: 2951 private:
2919 // True if the comparison must check for double, Mint or Bigint and 2952 // True if the comparison must check for double, Mint or Bigint and
2920 // use value comparison instead. 2953 // use value comparison instead.
2921 bool needs_number_check_; 2954 bool needs_number_check_;
2922 2955
2923 DISALLOW_COPY_AND_ASSIGN(StrictCompareInstr); 2956 DISALLOW_COPY_AND_ASSIGN(StrictCompareInstr);
2924 }; 2957 };
2925 2958
2926 2959
2927 // Comparison instruction that is equivalent to the (left & right) == 0 2960 // Comparison instruction that is equivalent to the (left & right) == 0
2928 // comparison pattern. 2961 // comparison pattern.
2929 class TestSmiInstr : public ComparisonInstr { 2962 class TestSmiInstr : public ComparisonInstr {
2930 public: 2963 public:
2931 TestSmiInstr(intptr_t token_pos, Token::Kind kind, Value* left, Value* right) 2964 TestSmiInstr(intptr_t token_pos, Token::Kind kind, Value* left, Value* right)
2932 : ComparisonInstr(token_pos, kind, left, right) { 2965 : ComparisonInstr(token_pos, kind, left, right) {
2933 ASSERT(kind == Token::kEQ || kind == Token::kNE); 2966 ASSERT(kind == Token::kEQ || kind == Token::kNE);
2934 } 2967 }
2935 2968
2936 DECLARE_INSTRUCTION(TestSmi); 2969 DECLARE_INSTRUCTION(TestSmi);
2970
2971 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
2972
2937 virtual CompileType ComputeType() const; 2973 virtual CompileType ComputeType() const;
2938 2974
2939 virtual bool CanDeoptimize() const { return false; } 2975 virtual bool CanDeoptimize() const { return false; }
2940 2976
2941 virtual bool CanBecomeDeoptimizationTarget() const { 2977 virtual bool CanBecomeDeoptimizationTarget() const {
2942 // TestSmi can be merged into Branch and thus needs an environment. 2978 // TestSmi can be merged into Branch and thus needs an environment.
2943 return true; 2979 return true;
2944 } 2980 }
2945 2981
2946 virtual intptr_t DeoptimizationTarget() const { 2982 virtual intptr_t DeoptimizationTarget() const {
2947 return GetDeoptId(); 2983 return GetDeoptId();
2948 } 2984 }
2949 2985
2950 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 2986 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
2951 return kTagged; 2987 return kTagged;
2952 } 2988 }
2953 2989
2954 virtual EffectSet Effects() const { return EffectSet::None(); } 2990 virtual EffectSet Effects() const { return EffectSet::None(); }
2955 2991
2956 virtual bool MayThrow() const { return false; } 2992 virtual bool MayThrow() const { return false; }
2957 2993
2958 virtual void EmitBranchCode(FlowGraphCompiler* compiler, 2994 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
2959 BranchInstr* branch); 2995 BranchInstr* branch);
2960 2996
2997 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
2998 BranchLabels labels);
2999
2961 private: 3000 private:
2962 DISALLOW_COPY_AND_ASSIGN(TestSmiInstr); 3001 DISALLOW_COPY_AND_ASSIGN(TestSmiInstr);
2963 }; 3002 };
2964 3003
2965 3004
2966 class EqualityCompareInstr : public ComparisonInstr { 3005 class EqualityCompareInstr : public ComparisonInstr {
2967 public: 3006 public:
2968 EqualityCompareInstr(intptr_t token_pos, 3007 EqualityCompareInstr(intptr_t token_pos,
2969 Token::Kind kind, 3008 Token::Kind kind,
2970 Value* left, 3009 Value* left,
2971 Value* right, 3010 Value* right,
2972 intptr_t cid, 3011 intptr_t cid,
2973 intptr_t deopt_id) 3012 intptr_t deopt_id)
2974 : ComparisonInstr(token_pos, kind, left, right) { 3013 : ComparisonInstr(token_pos, kind, left, right) {
2975 ASSERT(Token::IsEqualityOperator(kind)); 3014 ASSERT(Token::IsEqualityOperator(kind));
2976 set_operation_cid(cid); 3015 set_operation_cid(cid);
2977 deopt_id_ = deopt_id; // Override generated deopt-id. 3016 deopt_id_ = deopt_id; // Override generated deopt-id.
2978 } 3017 }
2979 3018
2980 DECLARE_INSTRUCTION(EqualityCompare) 3019 DECLARE_INSTRUCTION(EqualityCompare)
3020
3021 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
3022
2981 virtual CompileType ComputeType() const; 3023 virtual CompileType ComputeType() const;
2982 3024
2983 virtual void PrintOperandsTo(BufferFormatter* f) const; 3025 virtual void PrintOperandsTo(BufferFormatter* f) const;
2984 3026
2985 virtual bool CanDeoptimize() const { return false; } 3027 virtual bool CanDeoptimize() const { return false; }
2986 3028
2987 virtual bool CanBecomeDeoptimizationTarget() const { 3029 virtual bool CanBecomeDeoptimizationTarget() const {
2988 // EqualityCompare can be merged into Branch and thus needs an environment. 3030 // EqualityCompare can be merged into Branch and thus needs an environment.
2989 return true; 3031 return true;
2990 } 3032 }
2991 3033
2992 virtual void EmitBranchCode(FlowGraphCompiler* compiler, 3034 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
2993 BranchInstr* branch); 3035 BranchInstr* branch);
2994 3036
3037 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
3038 BranchLabels labels);
3039
2995 virtual intptr_t DeoptimizationTarget() const { 3040 virtual intptr_t DeoptimizationTarget() const {
2996 return GetDeoptId(); 3041 return GetDeoptId();
2997 } 3042 }
2998 3043
2999 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 3044 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
3000 ASSERT((idx == 0) || (idx == 1)); 3045 ASSERT((idx == 0) || (idx == 1));
3001 if (operation_cid() == kDoubleCid) return kUnboxedDouble; 3046 if (operation_cid() == kDoubleCid) return kUnboxedDouble;
3002 if (operation_cid() == kMintCid) return kUnboxedMint; 3047 if (operation_cid() == kMintCid) return kUnboxedMint;
3003 return kTagged; 3048 return kTagged;
3004 } 3049 }
(...skipping 15 matching lines...) Expand all
3020 Value* right, 3065 Value* right,
3021 intptr_t cid, 3066 intptr_t cid,
3022 intptr_t deopt_id) 3067 intptr_t deopt_id)
3023 : ComparisonInstr(token_pos, kind, left, right) { 3068 : ComparisonInstr(token_pos, kind, left, right) {
3024 ASSERT(Token::IsRelationalOperator(kind)); 3069 ASSERT(Token::IsRelationalOperator(kind));
3025 set_operation_cid(cid); 3070 set_operation_cid(cid);
3026 deopt_id_ = deopt_id; // Override generated deopt-id. 3071 deopt_id_ = deopt_id; // Override generated deopt-id.
3027 } 3072 }
3028 3073
3029 DECLARE_INSTRUCTION(RelationalOp) 3074 DECLARE_INSTRUCTION(RelationalOp)
3075
3076 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
3077
3030 virtual CompileType ComputeType() const; 3078 virtual CompileType ComputeType() const;
3031 3079
3032 virtual void PrintOperandsTo(BufferFormatter* f) const; 3080 virtual void PrintOperandsTo(BufferFormatter* f) const;
3033 3081
3034 virtual bool CanDeoptimize() const { return false; } 3082 virtual bool CanDeoptimize() const { return false; }
3035 3083
3036 virtual bool CanBecomeDeoptimizationTarget() const { 3084 virtual bool CanBecomeDeoptimizationTarget() const {
3037 // RelationalOp can be merged into Branch and thus needs an environment. 3085 // RelationalOp can be merged into Branch and thus needs an environment.
3038 return true; 3086 return true;
3039 } 3087 }
3040 3088
3041 virtual void EmitBranchCode(FlowGraphCompiler* compiler, 3089 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
3042 BranchInstr* branch); 3090 BranchInstr* branch);
3043 3091
3092 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
3093 BranchLabels labels);
3044 3094
3045 virtual intptr_t DeoptimizationTarget() const { 3095 virtual intptr_t DeoptimizationTarget() const {
3046 return GetDeoptId(); 3096 return GetDeoptId();
3047 } 3097 }
3048 3098
3049 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 3099 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
3050 ASSERT((idx == 0) || (idx == 1)); 3100 ASSERT((idx == 0) || (idx == 1));
3051 if (operation_cid() == kDoubleCid) return kUnboxedDouble; 3101 if (operation_cid() == kDoubleCid) return kUnboxedDouble;
3052 if (operation_cid() == kMintCid) return kUnboxedMint; 3102 if (operation_cid() == kMintCid) return kUnboxedMint;
3053 return kTagged; 3103 return kTagged;
3054 } 3104 }
3055 3105
3056 virtual EffectSet Effects() const { 3106 virtual EffectSet Effects() const {
3057 return EffectSet::None(); 3107 return EffectSet::None();
3058 } 3108 }
3059 3109
3060 virtual bool MayThrow() const { return false; } 3110 virtual bool MayThrow() const { return false; }
3061 3111
3062 private: 3112 private:
3063 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr); 3113 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr);
3064 }; 3114 };
3065 3115
3066 3116
3067 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for 3117 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for
3068 // materialization of true and false constants. 3118 // materialization of true and false constants.
3069 class IfThenElseInstr : public TemplateDefinition<2> { 3119 class IfThenElseInstr : public Definition {
3070 public: 3120 public:
3071 IfThenElseInstr(Token::Kind kind, 3121 IfThenElseInstr(ComparisonInstr* comparison,
3072 Value* left,
3073 Value* right,
3074 Value* if_true, 3122 Value* if_true,
3075 Value* if_false) 3123 Value* if_false)
3076 : kind_(kind), 3124 : comparison_(comparison),
3077 if_true_(Smi::Cast(if_true->BoundConstant()).Value()), 3125 if_true_(Smi::Cast(if_true->BoundConstant()).Value()),
3078 if_false_(Smi::Cast(if_false->BoundConstant()).Value()) { 3126 if_false_(Smi::Cast(if_false->BoundConstant()).Value()) {
3079 ASSERT(Token::IsEqualityOperator(kind)); 3127 // Adjust uses at the comparison.
3080 SetInputAt(0, left); 3128 ASSERT(comparison->env() == NULL);
3081 SetInputAt(1, right); 3129 for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) {
3130 comparison->InputAt(i)->set_instruction(this);
3131 }
3082 } 3132 }
3083 3133
3084 // Returns true if this combination of comparison and values flowing on 3134 // Returns true if this combination of comparison and values flowing on
3085 // the true and false paths is supported on the current platform. 3135 // the true and false paths is supported on the current platform.
3086 static bool Supports(ComparisonInstr* comparison, Value* v1, Value* v2); 3136 static bool Supports(ComparisonInstr* comparison, Value* v1, Value* v2);
3087 3137
3088 DECLARE_INSTRUCTION(IfThenElse) 3138 DECLARE_INSTRUCTION(IfThenElse)
3089 3139
3140 intptr_t InputCount() const { return comparison()->InputCount(); }
3141
3142 Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); }
3143
3144 virtual bool CanDeoptimize() const {
3145 return comparison()->CanDeoptimize();
3146 }
3147
3148 virtual bool CanBecomeDeoptimizationTarget() const {
3149 return comparison()->CanBecomeDeoptimizationTarget();
3150 }
3151
3152 virtual LocationSummary* locs() {
3153 if (comparison()->locs_ == NULL) {
3154 LocationSummary* summary = MakeLocationSummary();
3155 // The back-end expects the location summary to be stored in the
3156 // comparison.
3157 comparison()->locs_ = summary;
3158 }
3159 return comparison()->locs_;
3160 }
3161
3162 virtual intptr_t DeoptimizationTarget() const {
3163 return comparison()->DeoptimizationTarget();
3164 }
3165
3166 virtual Representation RequiredInputRepresentation(intptr_t i) const {
3167 return comparison()->RequiredInputRepresentation(i);
3168 }
3169
3090 virtual void PrintOperandsTo(BufferFormatter* f) const; 3170 virtual void PrintOperandsTo(BufferFormatter* f) const;
3091 3171
3092 virtual CompileType ComputeType() const; 3172 virtual CompileType ComputeType() const;
3093 3173
3094 virtual void InferRange(); 3174 virtual void InferRange();
3095 3175
3096 virtual bool CanDeoptimize() const { return false; } 3176 ComparisonInstr* comparison() const { return comparison_; }
3097
3098 Value* left() const { return inputs_[0]; }
3099 Value* right() const { return inputs_[1]; }
3100 intptr_t if_true() const { return if_true_; } 3177 intptr_t if_true() const { return if_true_; }
3101 intptr_t if_false() const { return if_false_; } 3178 intptr_t if_false() const { return if_false_; }
3102 3179
3103 Token::Kind kind() const { return kind_; } 3180 virtual bool AllowsCSE() const { return comparison()->AllowsCSE(); }
3104 3181 virtual EffectSet Effects() const { return comparison()->Effects(); }
3105 virtual bool AllowsCSE() const { return true; } 3182 virtual EffectSet Dependencies() const {
3106 virtual EffectSet Effects() const { return EffectSet::None(); } 3183 return comparison()->Dependencies();
3107 virtual EffectSet Dependencies() const { return EffectSet::None(); } 3184 }
3108 virtual bool AttributesEqual(Instruction* other) const { 3185 virtual bool AttributesEqual(Instruction* other) const {
3109 IfThenElseInstr* other_if_then_else = other->AsIfThenElse(); 3186 IfThenElseInstr* other_if_then_else = other->AsIfThenElse();
3110 return (kind_ == other_if_then_else->kind_) && 3187 return comparison()->AttributesEqual(other_if_then_else->comparison()) &&
3111 (if_true_ == other_if_then_else->if_true_) && 3188 (if_true_ == other_if_then_else->if_true_) &&
3112 (if_false_ == other_if_then_else->if_false_); 3189 (if_false_ == other_if_then_else->if_false_);
3113 } 3190 }
3114 3191
3115 virtual bool MayThrow() const { return false; } 3192 virtual bool MayThrow() const { return comparison()->MayThrow(); }
3116 3193
3117 private: 3194 private:
3118 const Token::Kind kind_; 3195 virtual void RawSetInputAt(intptr_t i, Value* value) {
3196 comparison()->RawSetInputAt(i, value);
3197 }
3198
3199 ComparisonInstr* comparison_;
3119 const intptr_t if_true_; 3200 const intptr_t if_true_;
3120 const intptr_t if_false_; 3201 const intptr_t if_false_;
3121 3202
3122 DISALLOW_COPY_AND_ASSIGN(IfThenElseInstr); 3203 DISALLOW_COPY_AND_ASSIGN(IfThenElseInstr);
3123 }; 3204 };
3124 3205
3125 3206
3126 class StaticCallInstr : public TemplateDefinition<0> { 3207 class StaticCallInstr : public TemplateDefinition<0> {
3127 public: 3208 public:
3128 StaticCallInstr(intptr_t token_pos, 3209 StaticCallInstr(intptr_t token_pos,
(...skipping 3766 matching lines...) Expand 10 before | Expand all | Expand 10 after
6895 ForwardInstructionIterator* current_iterator_; 6976 ForwardInstructionIterator* current_iterator_;
6896 6977
6897 private: 6978 private:
6898 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 6979 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
6899 }; 6980 };
6900 6981
6901 6982
6902 } // namespace dart 6983 } // namespace dart
6903 6984
6904 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 6985 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698