| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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_ |
| OLD | NEW |