| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 virtual ComparisonComp* AsComparison() { return NULL; } | 219 virtual ComparisonComp* AsComparison() { return NULL; } |
| 220 | 220 |
| 221 // Create a location summary for this computation. | 221 // Create a location summary for this computation. |
| 222 // TODO(fschneider): Temporarily returns NULL for instructions | 222 // TODO(fschneider): Temporarily returns NULL for instructions |
| 223 // that are not yet converted to the location based code generation. | 223 // that are not yet converted to the location based code generation. |
| 224 virtual LocationSummary* MakeLocationSummary() const = 0; | 224 virtual LocationSummary* MakeLocationSummary() const = 0; |
| 225 | 225 |
| 226 // TODO(fschneider): Make EmitNativeCode and locs const. | 226 // TODO(fschneider): Make EmitNativeCode and locs const. |
| 227 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; | 227 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; |
| 228 | 228 |
| 229 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 230 BranchInstr* branch) { |
| 231 UNREACHABLE(); |
| 232 } |
| 233 |
| 229 static LocationSummary* MakeCallSummary(); | 234 static LocationSummary* MakeCallSummary(); |
| 230 | 235 |
| 231 // Declare an enum value used to define kind-test predicates. | 236 // Declare an enum value used to define kind-test predicates. |
| 232 enum ComputationKind { | 237 enum ComputationKind { |
| 233 #define DECLARE_COMPUTATION_KIND(ShortName, ClassName) k##ShortName, | 238 #define DECLARE_COMPUTATION_KIND(ShortName, ClassName) k##ShortName, |
| 234 | 239 |
| 235 FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_KIND) | 240 FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_KIND) |
| 236 | 241 |
| 237 #undef DECLARE_COMPUTATION_KIND | 242 #undef DECLARE_COMPUTATION_KIND |
| 238 }; | 243 }; |
| 239 | 244 |
| 240 virtual ComputationKind computation_kind() const = 0; | 245 virtual ComputationKind computation_kind() const = 0; |
| 241 | 246 |
| 242 virtual Representation representation() const { | 247 virtual Representation representation() const { |
| 243 return kTagged; | 248 return kTagged; |
| 244 } | 249 } |
| 245 | 250 |
| 246 // Declare predicate for each computation. | 251 // Declare predicate for each computation. |
| 247 #define DECLARE_PREDICATE(ShortName, ClassName) \ | 252 #define DECLARE_PREDICATE(ShortName, ClassName) \ |
| 248 inline bool Is##ShortName() const; \ | 253 inline bool Is##ShortName() const; \ |
| 249 inline const ClassName* As##ShortName() const; \ | 254 inline const ClassName* As##ShortName() const; \ |
| 250 inline ClassName* As##ShortName(); | 255 inline ClassName* As##ShortName(); |
| 251 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) | 256 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) |
| 252 #undef DECLARE_PREDICATE | 257 #undef DECLARE_PREDICATE |
| 253 | 258 |
| 254 private: | 259 private: |
| 260 friend class BranchInstr; |
| 261 |
| 255 intptr_t deopt_id_; | 262 intptr_t deopt_id_; |
| 256 const ICData* ic_data_; | 263 const ICData* ic_data_; |
| 257 LocationSummary* locs_; | 264 LocationSummary* locs_; |
| 258 | 265 |
| 259 DISALLOW_COPY_AND_ASSIGN(Computation); | 266 DISALLOW_COPY_AND_ASSIGN(Computation); |
| 260 }; | 267 }; |
| 261 | 268 |
| 262 | 269 |
| 263 // An embedded container with N elements of type T. Used (with partial | 270 // An embedded container with N elements of type T. Used (with partial |
| 264 // specialization for N=0) because embedded arrays cannot have size 0. | 271 // specialization for N=0) because embedded arrays cannot have size 0. |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 DECLARE_COMPUTATION(StrictCompare) | 811 DECLARE_COMPUTATION(StrictCompare) |
| 805 | 812 |
| 806 virtual void PrintOperandsTo(BufferFormatter* f) const; | 813 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 807 | 814 |
| 808 virtual bool CanDeoptimize() const { return false; } | 815 virtual bool CanDeoptimize() const { return false; } |
| 809 | 816 |
| 810 virtual Definition* TryReplace(BindInstr* instr) const; | 817 virtual Definition* TryReplace(BindInstr* instr) const; |
| 811 | 818 |
| 812 virtual intptr_t ResultCid() const { return kBoolCid; } | 819 virtual intptr_t ResultCid() const { return kBoolCid; } |
| 813 | 820 |
| 821 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 822 BranchInstr* branch); |
| 823 |
| 814 private: | 824 private: |
| 815 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); | 825 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); |
| 816 }; | 826 }; |
| 817 | 827 |
| 818 | 828 |
| 819 class EqualityCompareComp : public ComparisonComp { | 829 class EqualityCompareComp : public ComparisonComp { |
| 820 public: | 830 public: |
| 821 EqualityCompareComp(intptr_t token_pos, | 831 EqualityCompareComp(intptr_t token_pos, |
| 822 intptr_t try_index, | 832 intptr_t try_index, |
| 823 Token::Kind kind, | 833 Token::Kind kind, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 837 | 847 |
| 838 // Receiver class id is computed from collected ICData. | 848 // Receiver class id is computed from collected ICData. |
| 839 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } | 849 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } |
| 840 intptr_t receiver_class_id() const { return receiver_class_id_; } | 850 intptr_t receiver_class_id() const { return receiver_class_id_; } |
| 841 | 851 |
| 842 virtual void PrintOperandsTo(BufferFormatter* f) const; | 852 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 843 | 853 |
| 844 virtual bool CanDeoptimize() const { return true; } | 854 virtual bool CanDeoptimize() const { return true; } |
| 845 virtual intptr_t ResultCid() const; | 855 virtual intptr_t ResultCid() const; |
| 846 | 856 |
| 857 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 858 BranchInstr* branch); |
| 859 |
| 847 private: | 860 private: |
| 848 const intptr_t token_pos_; | 861 const intptr_t token_pos_; |
| 849 const intptr_t try_index_; | 862 const intptr_t try_index_; |
| 850 intptr_t receiver_class_id_; // Set by optimizer. | 863 intptr_t receiver_class_id_; // Set by optimizer. |
| 851 | 864 |
| 852 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); | 865 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); |
| 853 }; | 866 }; |
| 854 | 867 |
| 855 | 868 |
| 856 class RelationalOpComp : public ComparisonComp { | 869 class RelationalOpComp : public ComparisonComp { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 878 operands_class_id_ = value; | 891 operands_class_id_ = value; |
| 879 } | 892 } |
| 880 | 893 |
| 881 intptr_t operands_class_id() const { return operands_class_id_; } | 894 intptr_t operands_class_id() const { return operands_class_id_; } |
| 882 | 895 |
| 883 virtual void PrintOperandsTo(BufferFormatter* f) const; | 896 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 884 | 897 |
| 885 virtual bool CanDeoptimize() const { return true; } | 898 virtual bool CanDeoptimize() const { return true; } |
| 886 virtual intptr_t ResultCid() const; | 899 virtual intptr_t ResultCid() const; |
| 887 | 900 |
| 901 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 902 BranchInstr* branch); |
| 903 |
| 888 private: | 904 private: |
| 889 const intptr_t token_pos_; | 905 const intptr_t token_pos_; |
| 890 const intptr_t try_index_; | 906 const intptr_t try_index_; |
| 891 intptr_t operands_class_id_; // class id of both operands. | 907 intptr_t operands_class_id_; // class id of both operands. |
| 892 | 908 |
| 893 DISALLOW_COPY_AND_ASSIGN(RelationalOpComp); | 909 DISALLOW_COPY_AND_ASSIGN(RelationalOpComp); |
| 894 }; | 910 }; |
| 895 | 911 |
| 896 | 912 |
| 897 class StaticCallComp : public TemplateComputation<0> { | 913 class StaticCallComp : public TemplateComputation<0> { |
| (...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2195 M(Phi) \ | 2211 M(Phi) \ |
| 2196 M(Bind) \ | 2212 M(Bind) \ |
| 2197 M(Parameter) \ | 2213 M(Parameter) \ |
| 2198 M(ParallelMove) \ | 2214 M(ParallelMove) \ |
| 2199 M(PushArgument) \ | 2215 M(PushArgument) \ |
| 2200 M(Return) \ | 2216 M(Return) \ |
| 2201 M(Throw) \ | 2217 M(Throw) \ |
| 2202 M(ReThrow) \ | 2218 M(ReThrow) \ |
| 2203 M(Goto) \ | 2219 M(Goto) \ |
| 2204 M(Branch) \ | 2220 M(Branch) \ |
| 2205 M(StrictCompareAndBranch) | |
| 2206 | 2221 |
| 2207 | 2222 |
| 2208 // Forward declarations for Instruction classes. | 2223 // Forward declarations for Instruction classes. |
| 2209 class BlockEntryInstr; | 2224 class BlockEntryInstr; |
| 2210 class FlowGraphBuilder; | 2225 class FlowGraphBuilder; |
| 2211 class Environment; | 2226 class Environment; |
| 2212 | 2227 |
| 2213 #define FORWARD_DECLARATION(type) class type##Instr; | 2228 #define FORWARD_DECLARATION(type) class type##Instr; |
| 2214 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 2229 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
| 2215 #undef FORWARD_DECLARATION | 2230 #undef FORWARD_DECLARATION |
| (...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3205 Condition true_condition); | 3220 Condition true_condition); |
| 3206 | 3221 |
| 3207 private: | 3222 private: |
| 3208 TargetEntryInstr* true_successor_; | 3223 TargetEntryInstr* true_successor_; |
| 3209 TargetEntryInstr* false_successor_; | 3224 TargetEntryInstr* false_successor_; |
| 3210 | 3225 |
| 3211 DISALLOW_COPY_AND_ASSIGN(ControlInstruction); | 3226 DISALLOW_COPY_AND_ASSIGN(ControlInstruction); |
| 3212 }; | 3227 }; |
| 3213 | 3228 |
| 3214 | 3229 |
| 3215 template<intptr_t N> | 3230 class BranchInstr : public ControlInstruction { |
| 3216 class TemplateControlInstruction: public ControlInstruction { | |
| 3217 public: | 3231 public: |
| 3218 TemplateControlInstruction<N>() : locs_(NULL) { } | 3232 explicit BranchInstr(ComparisonComp* computation) |
| 3219 | 3233 : computation_(computation), locs_(NULL) { } |
| 3220 virtual intptr_t InputCount() const { return N; } | |
| 3221 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | |
| 3222 virtual void SetInputAt(intptr_t i, Value* value) { | |
| 3223 ASSERT(value != NULL); | |
| 3224 inputs_[i] = value; | |
| 3225 } | |
| 3226 | |
| 3227 virtual LocationSummary* locs() { | |
| 3228 if (locs_ == NULL) { | |
| 3229 locs_ = MakeLocationSummary(); | |
| 3230 } | |
| 3231 return locs_; | |
| 3232 } | |
| 3233 | |
| 3234 virtual LocationSummary* MakeLocationSummary() const = 0; | |
| 3235 | |
| 3236 protected: | |
| 3237 EmbeddedArray<Value*, N> inputs_; | |
| 3238 | |
| 3239 private: | |
| 3240 LocationSummary* locs_; | |
| 3241 }; | |
| 3242 | |
| 3243 | |
| 3244 class BranchInstr : public TemplateControlInstruction<2> { | |
| 3245 public: | |
| 3246 BranchInstr(intptr_t token_pos, | |
| 3247 intptr_t try_index, | |
| 3248 Value* left, | |
| 3249 Value* right, | |
| 3250 Token::Kind kind) | |
| 3251 : deopt_id_(Isolate::kNoDeoptId), | |
| 3252 ic_data_(NULL), | |
| 3253 token_pos_(token_pos), | |
| 3254 try_index_(try_index), | |
| 3255 kind_(kind) { | |
| 3256 ASSERT(left != NULL); | |
| 3257 ASSERT(right != NULL); | |
| 3258 inputs_[0] = left; | |
| 3259 inputs_[1] = right; | |
| 3260 ASSERT(!Token::IsStrictEqualityOperator(kind)); | |
| 3261 ASSERT(Token::IsEqualityOperator(kind) || | |
| 3262 Token::IsRelationalOperator(kind) || | |
| 3263 Token::IsTypeTestOperator(kind)); | |
| 3264 Isolate* isolate = Isolate::Current(); | |
| 3265 deopt_id_ = isolate->GetNextDeoptId(); | |
| 3266 ic_data_ = isolate->GetICDataForDeoptId(deopt_id_); | |
| 3267 } | |
| 3268 | 3234 |
| 3269 DECLARE_INSTRUCTION(Branch) | 3235 DECLARE_INSTRUCTION(Branch) |
| 3270 | 3236 |
| 3271 Value* left() const { return inputs_[0]; } | 3237 virtual intptr_t ArgumentCount() const { |
| 3272 Value* right() const { return inputs_[1]; } | 3238 return computation()->ArgumentCount(); |
| 3239 } |
| 3240 intptr_t InputCount() const { return computation()->InputCount(); } |
| 3273 | 3241 |
| 3274 virtual intptr_t ArgumentCount() const { return 0; } | 3242 Value* InputAt(intptr_t i) const { return computation()->InputAt(i); } |
| 3275 | 3243 |
| 3276 Token::Kind kind() const { return kind_; } | 3244 void SetInputAt(intptr_t i, Value* value) { |
| 3277 | 3245 computation()->SetInputAt(i, value); |
| 3278 intptr_t deopt_id() const { return deopt_id_; } | |
| 3279 | |
| 3280 const ICData* ic_data() const { return ic_data_; } | |
| 3281 bool HasICData() const { | |
| 3282 return (ic_data() != NULL) && !ic_data()->IsNull(); | |
| 3283 } | 3246 } |
| 3284 | 3247 |
| 3285 intptr_t token_pos() const { return token_pos_;} | 3248 virtual bool CanDeoptimize() const { return computation()->CanDeoptimize(); } |
| 3286 intptr_t try_index() const { return try_index_; } | |
| 3287 | 3249 |
| 3288 virtual LocationSummary* MakeLocationSummary() const; | 3250 ComparisonComp* computation() const { return computation_; } |
| 3251 void set_computation(ComparisonComp* value) { computation_ = value; } |
| 3289 | 3252 |
| 3290 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 3253 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 3291 | 3254 |
| 3292 virtual bool CanDeoptimize() const { return true; } | 3255 virtual LocationSummary* locs() { |
| 3256 if (computation_->locs_ == NULL) { |
| 3257 LocationSummary* summary = computation_->MakeLocationSummary(); |
| 3258 // Branches don't produce a result. |
| 3259 summary->set_out(Location::NoLocation()); |
| 3260 computation_->locs_ = summary; |
| 3261 } |
| 3262 return computation_->locs_; |
| 3263 } |
| 3293 | 3264 |
| 3294 private: | 3265 private: |
| 3295 intptr_t deopt_id_; | 3266 ComparisonComp* computation_; |
| 3296 const ICData* ic_data_; | 3267 LocationSummary* locs_; |
| 3297 const intptr_t token_pos_; | |
| 3298 const intptr_t try_index_; | |
| 3299 const Token::Kind kind_; | |
| 3300 | 3268 |
| 3301 DISALLOW_COPY_AND_ASSIGN(BranchInstr); | 3269 DISALLOW_COPY_AND_ASSIGN(BranchInstr); |
| 3302 }; | 3270 }; |
| 3303 | 3271 |
| 3304 | 3272 |
| 3305 class StrictCompareAndBranchInstr : public TemplateControlInstruction<2> { | |
| 3306 public: | |
| 3307 StrictCompareAndBranchInstr(Value* left, Value* right, Token::Kind kind) | |
| 3308 : kind_(kind) { | |
| 3309 ASSERT(left != NULL); | |
| 3310 ASSERT(right != NULL); | |
| 3311 inputs_[0] = left; | |
| 3312 inputs_[1] = right; | |
| 3313 ASSERT(Token::IsStrictEqualityOperator(kind)); | |
| 3314 } | |
| 3315 | |
| 3316 DECLARE_INSTRUCTION(StrictCompareAndBranch) | |
| 3317 | |
| 3318 Value* left() const { return inputs_[0]; } | |
| 3319 Value* right() const { return inputs_[1]; } | |
| 3320 | |
| 3321 virtual intptr_t ArgumentCount() const { return 0; } | |
| 3322 | |
| 3323 Token::Kind kind() const { return kind_; } | |
| 3324 | |
| 3325 virtual LocationSummary* MakeLocationSummary() const; | |
| 3326 | |
| 3327 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | |
| 3328 | |
| 3329 virtual bool CanDeoptimize() const { return false; } | |
| 3330 | |
| 3331 private: | |
| 3332 const Token::Kind kind_; | |
| 3333 | |
| 3334 DISALLOW_COPY_AND_ASSIGN(StrictCompareAndBranchInstr); | |
| 3335 }; | |
| 3336 | |
| 3337 | |
| 3338 #undef DECLARE_INSTRUCTION | 3273 #undef DECLARE_INSTRUCTION |
| 3339 | 3274 |
| 3340 | 3275 |
| 3341 class Environment : public ZoneAllocated { | 3276 class Environment : public ZoneAllocated { |
| 3342 public: | 3277 public: |
| 3343 // Construct an environment by constructing uses from an array of definitions. | 3278 // Construct an environment by constructing uses from an array of definitions. |
| 3344 Environment(const GrowableArray<Definition*>& definitions, | 3279 Environment(const GrowableArray<Definition*>& definitions, |
| 3345 intptr_t fixed_parameter_count); | 3280 intptr_t fixed_parameter_count); |
| 3346 | 3281 |
| 3347 void set_locations(Location* locations) { | 3282 void set_locations(Location* locations) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3424 ForwardInstructionIterator* current_iterator_; | 3359 ForwardInstructionIterator* current_iterator_; |
| 3425 | 3360 |
| 3426 private: | 3361 private: |
| 3427 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3362 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 3428 }; | 3363 }; |
| 3429 | 3364 |
| 3430 | 3365 |
| 3431 } // namespace dart | 3366 } // namespace dart |
| 3432 | 3367 |
| 3433 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3368 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |