Chromium Code Reviews| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 | 44 |
| 45 class BitVector; | 45 class BitVector; |
| 46 class FlowGraphAllocator; | 46 class FlowGraphAllocator; |
| 47 class FlowGraphCompiler; | 47 class FlowGraphCompiler; |
| 48 class FlowGraphVisitor; | 48 class FlowGraphVisitor; |
| 49 class Function; | 49 class Function; |
| 50 class LocalVariable; | 50 class LocalVariable; |
| 51 | 51 |
| 52 // M is a two argument macro. It is applied to each concrete value's | |
| 53 // typename and classname. | |
| 54 #define FOR_EACH_VALUE(M) \ | |
| 55 M(Use, UseVal) \ | |
| 56 | |
| 57 | |
| 58 // M is a two argument macro. It is applied to each concrete instruction's | 52 // M is a two argument macro. It is applied to each concrete instruction's |
| 59 // (including the values) typename and classname. | 53 // (including the values) typename and classname. |
| 60 #define FOR_EACH_COMPUTATION(M) \ | 54 #define FOR_EACH_COMPUTATION(M) \ |
| 61 M(AssertAssignable, AssertAssignableComp) \ | 55 M(AssertAssignable, AssertAssignableComp) \ |
| 62 M(AssertBoolean, AssertBooleanComp) \ | 56 M(AssertBoolean, AssertBooleanComp) \ |
| 63 M(CurrentContext, CurrentContextComp) \ | 57 M(CurrentContext, CurrentContextComp) \ |
| 64 M(StoreContext, StoreContextComp) \ | 58 M(StoreContext, StoreContextComp) \ |
| 65 M(ClosureCall, ClosureCallComp) \ | 59 M(ClosureCall, ClosureCallComp) \ |
| 66 M(InstanceCall, InstanceCallComp) \ | 60 M(InstanceCall, InstanceCallComp) \ |
| 67 M(PolymorphicInstanceCall, PolymorphicInstanceCallComp) \ | 61 M(PolymorphicInstanceCall, PolymorphicInstanceCallComp) \ |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 M(Constant, ConstantComp) \ | 100 M(Constant, ConstantComp) \ |
| 107 M(CheckEitherNonSmi, CheckEitherNonSmiComp) \ | 101 M(CheckEitherNonSmi, CheckEitherNonSmiComp) \ |
| 108 M(UnboxedDoubleBinaryOp, UnboxedDoubleBinaryOpComp) \ | 102 M(UnboxedDoubleBinaryOp, UnboxedDoubleBinaryOpComp) \ |
| 109 M(UnboxDouble, UnboxDoubleComp) \ | 103 M(UnboxDouble, UnboxDoubleComp) \ |
| 110 M(BoxDouble, BoxDoubleComp) \ | 104 M(BoxDouble, BoxDoubleComp) \ |
| 111 M(CheckArrayBound, CheckArrayBoundComp) | 105 M(CheckArrayBound, CheckArrayBoundComp) |
| 112 | 106 |
| 113 | 107 |
| 114 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; | 108 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; |
| 115 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) | 109 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) |
| 116 FOR_EACH_VALUE(FORWARD_DECLARATION) | |
| 117 #undef FORWARD_DECLARATION | 110 #undef FORWARD_DECLARATION |
| 118 | 111 |
| 119 // Forward declarations. | 112 // Forward declarations. |
| 120 class BindInstr; | 113 class BindInstr; |
| 121 class BranchInstr; | 114 class BranchInstr; |
| 122 class BufferFormatter; | 115 class BufferFormatter; |
| 123 class ComparisonComp; | 116 class ComparisonComp; |
| 124 class Definition; | 117 class Definition; |
| 118 class Definition; | |
|
srdjan
2012/08/29 19:45:53
One Definition too much.
| |
| 125 class Instruction; | 119 class Instruction; |
| 120 class PhiInstr; | |
| 126 class PushArgumentInstr; | 121 class PushArgumentInstr; |
| 127 class Value; | 122 class Value; |
| 128 | 123 |
| 129 | 124 |
| 130 enum Representation { | 125 enum Representation { |
| 131 kTagged, kUnboxedDouble | 126 kTagged, kUnboxedDouble |
| 132 }; | 127 }; |
| 133 | 128 |
| 134 | 129 |
| 135 class Computation : public ZoneAllocated { | 130 class Computation : public ZoneAllocated { |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 inputs_[i] = value; | 325 inputs_[i] = value; |
| 331 } | 326 } |
| 332 | 327 |
| 333 protected: | 328 protected: |
| 334 EmbeddedArray<Value*, N> inputs_; | 329 EmbeddedArray<Value*, N> inputs_; |
| 335 }; | 330 }; |
| 336 | 331 |
| 337 | 332 |
| 338 class Value : public ZoneAllocated { | 333 class Value : public ZoneAllocated { |
| 339 public: | 334 public: |
| 340 Value() { } | 335 explicit Value(Definition* definition) |
| 336 : definition_(definition), | |
| 337 next_use_(NULL), | |
| 338 instruction_(NULL), | |
| 339 use_index_(-1) { } | |
| 341 | 340 |
| 342 // Declare an enum value used to define kind-test predicates. | 341 Definition* definition() const { return definition_; } |
| 343 enum ValueKind { | 342 void set_definition(Definition* definition) { definition_ = definition; } |
| 344 #define DECLARE_VALUE_KIND(ShortName, ClassName) k##ShortName, | |
| 345 FOR_EACH_VALUE(DECLARE_VALUE_KIND) | |
| 346 #undef DECLARE_VALUE_KIND | |
| 347 }; | |
| 348 | 343 |
| 349 // Declare predicate for each value. | 344 Value* next_use() const { return next_use_; } |
| 350 #define DECLARE_PREDICATE(ShortName, ClassName) \ | 345 void set_next_use(Value* next) { next_use_ = next; } |
| 351 inline bool Is##ShortName() const; \ | |
| 352 inline const ClassName* As##ShortName() const; \ | |
| 353 inline ClassName* As##ShortName(); | |
| 354 FOR_EACH_VALUE(DECLARE_PREDICATE) | |
| 355 #undef DECLARE_PREDICATE | |
| 356 | 346 |
| 357 virtual ValueKind value_kind() const = 0; | 347 Instruction* instruction() const { return instruction_; } |
| 348 void set_instruction(Instruction* instruction) { instruction_ = instruction; } | |
| 358 | 349 |
| 359 virtual RawAbstractType* CompileType() const = 0; | 350 intptr_t use_index() const { return use_index_; } |
| 360 virtual intptr_t ResultCid() const = 0; | 351 void set_use_index(intptr_t index) { use_index_ = index; } |
| 361 | 352 |
| 362 virtual void PrintTo(BufferFormatter* f) const = 0; | 353 void AddToInputUseList(); |
| 354 void AddToEnvUseList(); | |
| 355 | |
| 356 Value* Copy() { return new Value(definition_); } | |
| 357 | |
| 358 RawAbstractType* CompileType() const; | |
| 359 intptr_t ResultCid() const; | |
| 360 | |
| 361 void PrintTo(BufferFormatter* f) const; | |
| 362 | |
| 363 const char* DebugName() const { return "Value"; } | |
| 363 | 364 |
| 364 // Returns true if the value represents a constant. | 365 // Returns true if the value represents a constant. |
| 365 virtual bool BindsToConstant() const = 0; | 366 bool BindsToConstant() const; |
| 366 | 367 |
| 367 // Returns true if the value represents constant null. | 368 // Returns true if the value represents the constant null. |
| 368 virtual bool BindsToConstantNull() const = 0; | 369 bool BindsToConstantNull() const; |
| 369 | 370 |
| 370 // Assert if BindsToConstant() is false, otherwise returns constant. | 371 // Assert if BindsToConstant() is false, otherwise returns the constant value. |
| 371 virtual const Object& BoundConstant() const = 0; | 372 const Object& BoundConstant() const; |
| 372 | 373 |
| 373 // Reminder: The type of the constant null is the bottom type, which is more | 374 // Reminder: The type of the constant null is the bottom type, which is more |
| 374 // specific than any type. | 375 // specific than any type. |
| 375 bool CompileTypeIsMoreSpecificThan(const AbstractType& dst_type) const; | 376 bool CompileTypeIsMoreSpecificThan(const AbstractType& dst_type) const; |
| 376 | 377 |
| 377 // Compile time constants, Bool, Smi and Nulls do not need to update | 378 // Compile time constants, Bool, Smi and Nulls do not need to update |
| 378 // the store buffer. | 379 // the store buffer. |
| 379 bool NeedsStoreBuffer() const; | 380 bool NeedsStoreBuffer() const; |
| 380 | 381 |
| 381 virtual bool Equals(Value* other) const = 0; | 382 bool Equals(Value* other) const; |
| 382 | |
| 383 virtual Value* CopyValue() = 0; | |
| 384 | 383 |
| 385 private: | 384 private: |
| 385 Definition* definition_; | |
| 386 Value* next_use_; | |
| 387 Instruction* instruction_; | |
| 388 intptr_t use_index_; | |
| 389 | |
| 386 DISALLOW_COPY_AND_ASSIGN(Value); | 390 DISALLOW_COPY_AND_ASSIGN(Value); |
| 387 }; | 391 }; |
| 388 | 392 |
| 389 | 393 |
| 390 // Functions defined in all concrete computation classes. | 394 // Functions defined in all concrete computation classes. |
| 391 #define DECLARE_COMPUTATION(ShortName) \ | 395 #define DECLARE_COMPUTATION(ShortName) \ |
| 392 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \ | 396 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \ |
| 393 virtual ComputationKind computation_kind() const { \ | 397 virtual ComputationKind computation_kind() const { \ |
| 394 return Computation::k##ShortName; \ | 398 return Computation::k##ShortName; \ |
| 395 } \ | 399 } \ |
| 396 virtual intptr_t ArgumentCount() const { return 0; } \ | 400 virtual intptr_t ArgumentCount() const { return 0; } \ |
| 397 virtual const char* DebugName() const { return #ShortName; } \ | 401 virtual const char* DebugName() const { return #ShortName; } \ |
| 398 virtual RawAbstractType* CompileType() const; \ | 402 virtual RawAbstractType* CompileType() const; \ |
| 399 virtual LocationSummary* MakeLocationSummary() const; \ | 403 virtual LocationSummary* MakeLocationSummary() const; \ |
| 400 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 404 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 401 | 405 |
| 402 // Functions defined in all concrete value classes. | |
| 403 #define DECLARE_VALUE(ShortName) \ | |
| 404 virtual ValueKind value_kind() const { \ | |
| 405 return Value::k##ShortName; \ | |
| 406 } \ | |
| 407 virtual const char* DebugName() const { return #ShortName; } \ | |
| 408 virtual RawAbstractType* CompileType() const; \ | |
| 409 virtual bool Equals(Value* other) const; \ | |
| 410 virtual void PrintTo(BufferFormatter* f) const; | |
| 411 | |
| 412 | 406 |
| 413 // Function defined in all call computation classes. | 407 // Function defined in all call computation classes. |
| 414 #define DECLARE_CALL_COMPUTATION(ShortName) \ | 408 #define DECLARE_CALL_COMPUTATION(ShortName) \ |
| 415 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \ | 409 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr); \ |
| 416 virtual ComputationKind computation_kind() const { \ | 410 virtual ComputationKind computation_kind() const { \ |
| 417 return Computation::k##ShortName; \ | 411 return Computation::k##ShortName; \ |
| 418 } \ | 412 } \ |
| 419 virtual const char* DebugName() const { return #ShortName; } \ | 413 virtual const char* DebugName() const { return #ShortName; } \ |
| 420 virtual RawAbstractType* CompileType() const; \ | 414 virtual RawAbstractType* CompileType() const; \ |
| 421 virtual LocationSummary* MakeLocationSummary() const; \ | 415 virtual LocationSummary* MakeLocationSummary() const; \ |
| 422 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 416 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 423 | 417 |
| 424 | 418 |
| 425 class Definition; | |
| 426 class PhiInstr; | |
| 427 | |
| 428 class UseVal : public Value { | |
| 429 public: | |
| 430 explicit UseVal(Definition* definition) | |
| 431 : definition_(definition), | |
| 432 next_use_(NULL), | |
| 433 instruction_(NULL), | |
| 434 use_index_(-1) { } | |
| 435 | |
| 436 DECLARE_VALUE(Use) | |
| 437 | |
| 438 inline Definition* definition() const { return definition_; } | |
| 439 void set_definition(Definition* definition) { definition_ = definition; } | |
| 440 | |
| 441 // Returns true if the value represents a constant. | |
| 442 virtual bool BindsToConstant() const; | |
| 443 virtual const Object& BoundConstant() const; | |
| 444 | |
| 445 // Returns true if the value represents constant null. | |
| 446 virtual bool BindsToConstantNull() const; | |
| 447 | |
| 448 virtual bool CanDeoptimize() const { return false; } | |
| 449 | |
| 450 UseVal* next_use() const { return next_use_; } | |
| 451 void set_next_use(UseVal* next) { next_use_ = next; } | |
| 452 | |
| 453 Instruction* instruction() const { return instruction_; } | |
| 454 void set_instruction(Instruction* instruction) { instruction_ = instruction; } | |
| 455 | |
| 456 intptr_t use_index() const { return use_index_; } | |
| 457 void set_use_index(intptr_t index) { use_index_ = index; } | |
| 458 | |
| 459 void AddToInputUseList(); | |
| 460 void AddToEnvUseList(); | |
| 461 | |
| 462 virtual intptr_t ResultCid() const; | |
| 463 | |
| 464 virtual Value* CopyValue() { return new UseVal(definition_); } | |
| 465 | |
| 466 private: | |
| 467 Definition* definition_; | |
| 468 UseVal* next_use_; | |
| 469 Instruction* instruction_; | |
| 470 intptr_t use_index_; | |
| 471 | |
| 472 DISALLOW_COPY_AND_ASSIGN(UseVal); | |
| 473 }; | |
| 474 | |
| 475 | |
| 476 #undef DECLARE_VALUE | |
| 477 | |
| 478 | |
| 479 class ConstantComp : public TemplateComputation<0> { | 419 class ConstantComp : public TemplateComputation<0> { |
| 480 public: | 420 public: |
| 481 explicit ConstantComp(const Object& value) : value_(value) { } | 421 explicit ConstantComp(const Object& value) : value_(value) { } |
| 482 | 422 |
| 483 DECLARE_COMPUTATION(Constant) | 423 DECLARE_COMPUTATION(Constant) |
| 484 | 424 |
| 485 const Object& value() const { return value_; } | 425 const Object& value() const { return value_; } |
| 486 | 426 |
| 487 virtual void PrintOperandsTo(BufferFormatter* f) const; | 427 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 488 | 428 |
| (...skipping 1662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2151 if (!Is##ShortName()) return NULL; \ | 2091 if (!Is##ShortName()) return NULL; \ |
| 2152 return static_cast<const ClassName*>(this); \ | 2092 return static_cast<const ClassName*>(this); \ |
| 2153 } \ | 2093 } \ |
| 2154 ClassName* Computation::As##ShortName() { \ | 2094 ClassName* Computation::As##ShortName() { \ |
| 2155 if (!Is##ShortName()) return NULL; \ | 2095 if (!Is##ShortName()) return NULL; \ |
| 2156 return static_cast<ClassName*>(this); \ | 2096 return static_cast<ClassName*>(this); \ |
| 2157 } | 2097 } |
| 2158 FOR_EACH_COMPUTATION(DEFINE_COMPUTATION_PREDICATE) | 2098 FOR_EACH_COMPUTATION(DEFINE_COMPUTATION_PREDICATE) |
| 2159 #undef DEFINE_COMPUTATION_PREDICATE | 2099 #undef DEFINE_COMPUTATION_PREDICATE |
| 2160 | 2100 |
| 2161 #define DEFINE_VALUE_PREDICATE(ShortName, ClassName) \ | |
| 2162 bool Value::Is##ShortName() const { \ | |
| 2163 return value_kind() == k##ShortName; \ | |
| 2164 } \ | |
| 2165 const ClassName* Value::As##ShortName() const { \ | |
| 2166 if (!Is##ShortName()) return NULL; \ | |
| 2167 return static_cast<const ClassName*>(this); \ | |
| 2168 } \ | |
| 2169 ClassName* Value::As##ShortName() { \ | |
| 2170 if (!Is##ShortName()) return NULL; \ | |
| 2171 return static_cast<ClassName*>(this); \ | |
| 2172 } | |
| 2173 FOR_EACH_VALUE(DEFINE_VALUE_PREDICATE) | |
| 2174 #undef DEFINE_VALUE_PREDICATE | |
| 2175 | |
| 2176 // Instructions. | 2101 // Instructions. |
| 2177 | 2102 |
| 2178 // M is a single argument macro. It is applied to each concrete instruction | 2103 // M is a single argument macro. It is applied to each concrete instruction |
| 2179 // type name. The concrete instruction classes are the name with Instr | 2104 // type name. The concrete instruction classes are the name with Instr |
| 2180 // concatenated. | 2105 // concatenated. |
| 2181 #define FOR_EACH_INSTRUCTION(M) \ | 2106 #define FOR_EACH_INSTRUCTION(M) \ |
| 2182 M(GraphEntry) \ | 2107 M(GraphEntry) \ |
| 2183 M(JoinEntry) \ | 2108 M(JoinEntry) \ |
| 2184 M(TargetEntry) \ | 2109 M(TargetEntry) \ |
| 2185 M(Phi) \ | 2110 M(Phi) \ |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2809 } | 2734 } |
| 2810 | 2735 |
| 2811 bool has_propagated_cid() const { return propagated_cid_ != kIllegalCid; } | 2736 bool has_propagated_cid() const { return propagated_cid_ != kIllegalCid; } |
| 2812 intptr_t propagated_cid() const { return propagated_cid_; } | 2737 intptr_t propagated_cid() const { return propagated_cid_; } |
| 2813 // May compute and set propagated cid. | 2738 // May compute and set propagated cid. |
| 2814 virtual intptr_t GetPropagatedCid() = 0; | 2739 virtual intptr_t GetPropagatedCid() = 0; |
| 2815 | 2740 |
| 2816 // Returns true if the propagated cid has changed. | 2741 // Returns true if the propagated cid has changed. |
| 2817 bool SetPropagatedCid(intptr_t cid); | 2742 bool SetPropagatedCid(intptr_t cid); |
| 2818 | 2743 |
| 2819 UseVal* input_use_list() { return input_use_list_; } | 2744 Value* input_use_list() { return input_use_list_; } |
| 2820 void set_input_use_list(UseVal* head) { input_use_list_ = head; } | 2745 void set_input_use_list(Value* head) { input_use_list_ = head; } |
| 2821 | 2746 |
| 2822 UseVal* env_use_list() { return env_use_list_; } | 2747 Value* env_use_list() { return env_use_list_; } |
| 2823 void set_env_use_list(UseVal* head) { env_use_list_ = head; } | 2748 void set_env_use_list(Value* head) { env_use_list_ = head; } |
| 2824 | 2749 |
| 2825 // Replace uses of this definition with uses of other definition or value. | 2750 // Replace uses of this definition with uses of other definition or value. |
| 2826 // Precondition: use lists must be properly calculated. | 2751 // Precondition: use lists must be properly calculated. |
| 2827 // Postcondition: use lists and use values are still valid. | 2752 // Postcondition: use lists and use values are still valid. |
| 2828 void ReplaceUsesWith(Definition* other); | 2753 void ReplaceUsesWith(Definition* other); |
| 2829 | 2754 |
| 2830 private: | 2755 private: |
| 2831 intptr_t temp_index_; | 2756 intptr_t temp_index_; |
| 2832 intptr_t ssa_temp_index_; | 2757 intptr_t ssa_temp_index_; |
| 2833 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; | 2758 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; |
| 2834 // For now: | 2759 // For now: |
| 2835 AbstractType& propagated_type_; | 2760 AbstractType& propagated_type_; |
| 2836 intptr_t propagated_cid_; | 2761 intptr_t propagated_cid_; |
| 2837 UseVal* input_use_list_; | 2762 Value* input_use_list_; |
| 2838 UseVal* env_use_list_; | 2763 Value* env_use_list_; |
| 2839 | 2764 |
| 2840 DISALLOW_COPY_AND_ASSIGN(Definition); | 2765 DISALLOW_COPY_AND_ASSIGN(Definition); |
| 2841 }; | 2766 }; |
| 2842 | 2767 |
| 2843 | 2768 |
| 2844 class BindInstr : public Definition { | 2769 class BindInstr : public Definition { |
| 2845 public: | 2770 public: |
| 2846 enum UseKind { kUnused, kUsed }; | 2771 enum UseKind { kUnused, kUsed }; |
| 2847 | 2772 |
| 2848 BindInstr(UseKind used, Computation* computation) | 2773 BindInstr(UseKind used, Computation* computation) |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3330 ForwardInstructionIterator* current_iterator_; | 3255 ForwardInstructionIterator* current_iterator_; |
| 3331 | 3256 |
| 3332 private: | 3257 private: |
| 3333 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3258 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 3334 }; | 3259 }; |
| 3335 | 3260 |
| 3336 | 3261 |
| 3337 } // namespace dart | 3262 } // namespace dart |
| 3338 | 3263 |
| 3339 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3264 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |