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 1745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 const LocalVariable& stacktrace_var_; | 1756 const LocalVariable& stacktrace_var_; |
1757 const bool needs_stacktrace_; | 1757 const bool needs_stacktrace_; |
1758 | 1758 |
1759 DISALLOW_COPY_AND_ASSIGN(CatchBlockEntryInstr); | 1759 DISALLOW_COPY_AND_ASSIGN(CatchBlockEntryInstr); |
1760 }; | 1760 }; |
1761 | 1761 |
1762 | 1762 |
1763 // If the result of the allocation is not stored into any field, passed | 1763 // If the result of the allocation is not stored into any field, passed |
1764 // as an argument or used in a phi then it can't alias with any other | 1764 // as an argument or used in a phi then it can't alias with any other |
1765 // SSA value. | 1765 // SSA value. |
1766 enum AliasIdentity { | 1766 class AliasIdentity : public ValueObject { |
1767 kIdentityUnknown, | 1767 public: |
1768 kIdentityAliased, | 1768 // It is unknown if value has aliases. |
1769 kIdentityNotAliased | 1769 static AliasIdentity Unknown() { return AliasIdentity(kUnknown); } |
| 1770 |
| 1771 // It is known that value can have aliases. |
| 1772 static AliasIdentity Aliased() { return AliasIdentity(kAliased); } |
| 1773 |
| 1774 // It is known that value has no aliases. |
| 1775 static AliasIdentity NotAliased() { return AliasIdentity(kNotAliased); } |
| 1776 |
| 1777 // It is known that value has no aliases and it was selected by |
| 1778 // allocation sinking pass as a candidate. |
| 1779 static AliasIdentity AllocationSinkingCandidate() { |
| 1780 return AliasIdentity(kAllocationSinkingCandidate); |
| 1781 } |
| 1782 |
| 1783 bool IsUnknown() const { return value_ == kUnknown; } |
| 1784 bool IsAliased() const { return value_ == kAliased; } |
| 1785 bool IsNotAliased() const { return (value_ & kNotAliased) != 0; } |
| 1786 bool IsAllocationSinkingCandidate() const { |
| 1787 return value_ == kAllocationSinkingCandidate; |
| 1788 } |
| 1789 |
| 1790 AliasIdentity(const AliasIdentity& other) |
| 1791 : ValueObject(), value_(other.value_) { |
| 1792 } |
| 1793 |
| 1794 AliasIdentity& operator=(const AliasIdentity& other) { |
| 1795 value_ = other.value_; |
| 1796 return *this; |
| 1797 } |
| 1798 |
| 1799 private: |
| 1800 explicit AliasIdentity(intptr_t value) : value_(value) { } |
| 1801 |
| 1802 enum { |
| 1803 kUnknown = 0, |
| 1804 kNotAliased = 1, |
| 1805 kAliased = 2, |
| 1806 kAllocationSinkingCandidate = 3, |
| 1807 }; |
| 1808 |
| 1809 COMPILE_ASSERT((kUnknown & kNotAliased) == 0); |
| 1810 COMPILE_ASSERT((kAliased & kNotAliased) == 0); |
| 1811 COMPILE_ASSERT((kAllocationSinkingCandidate & kNotAliased) != 0); |
| 1812 |
| 1813 intptr_t value_; |
1770 }; | 1814 }; |
1771 | 1815 |
1772 | 1816 |
1773 // Abstract super-class of all instructions that define a value (Bind, Phi). | 1817 // Abstract super-class of all instructions that define a value (Bind, Phi). |
1774 class Definition : public Instruction { | 1818 class Definition : public Instruction { |
1775 public: | 1819 public: |
1776 Definition(); | 1820 Definition(); |
1777 | 1821 |
1778 virtual Definition* AsDefinition() { return this; } | 1822 virtual Definition* AsDefinition() { return this; } |
1779 | 1823 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1920 } | 1964 } |
1921 | 1965 |
1922 void SetReplacement(Definition* other) { | 1966 void SetReplacement(Definition* other) { |
1923 ASSERT(ssa_temp_index_ >= 0); | 1967 ASSERT(ssa_temp_index_ >= 0); |
1924 ASSERT(WasEliminated()); | 1968 ASSERT(WasEliminated()); |
1925 ssa_temp_index_ = kReplacementMarker; | 1969 ssa_temp_index_ = kReplacementMarker; |
1926 temp_index_ = reinterpret_cast<intptr_t>(other); | 1970 temp_index_ = reinterpret_cast<intptr_t>(other); |
1927 } | 1971 } |
1928 | 1972 |
1929 virtual AliasIdentity Identity() const { | 1973 virtual AliasIdentity Identity() const { |
1930 // Only implemented for allocation instructions. | 1974 return AliasIdentity::Unknown(); |
1931 UNREACHABLE(); | |
1932 return kIdentityUnknown; | |
1933 } | 1975 } |
1934 | 1976 |
1935 virtual void SetIdentity(AliasIdentity identity) { | 1977 virtual void SetIdentity(AliasIdentity identity) { |
1936 UNREACHABLE(); | 1978 UNREACHABLE(); |
1937 } | 1979 } |
1938 | 1980 |
1939 Definition* OriginalDefinition(); | 1981 Definition* OriginalDefinition(); |
1940 | 1982 |
1941 protected: | 1983 protected: |
1942 friend class RangeAnalysis; | 1984 friend class RangeAnalysis; |
(...skipping 1679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3622 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 3664 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
3623 const ZoneGrowableArray<const ICData*>& ic_data_array) | 3665 const ZoneGrowableArray<const ICData*>& ic_data_array) |
3624 : ic_data_(GetICData(ic_data_array)), | 3666 : ic_data_(GetICData(ic_data_array)), |
3625 token_pos_(token_pos), | 3667 token_pos_(token_pos), |
3626 function_(function), | 3668 function_(function), |
3627 argument_names_(argument_names), | 3669 argument_names_(argument_names), |
3628 arguments_(arguments), | 3670 arguments_(arguments), |
3629 result_cid_(kDynamicCid), | 3671 result_cid_(kDynamicCid), |
3630 is_known_list_constructor_(false), | 3672 is_known_list_constructor_(false), |
3631 is_native_list_factory_(false), | 3673 is_native_list_factory_(false), |
3632 identity_(kIdentityUnknown) { | 3674 identity_(AliasIdentity::Unknown()) { |
3633 ASSERT(function.IsZoneHandle()); | 3675 ASSERT(function.IsZoneHandle()); |
3634 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); | 3676 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); |
3635 } | 3677 } |
3636 | 3678 |
3637 // ICData for static calls carries call count. | 3679 // ICData for static calls carries call count. |
3638 const ICData* ic_data() const { return ic_data_; } | 3680 const ICData* ic_data() const { return ic_data_; } |
3639 bool HasICData() const { | 3681 bool HasICData() const { |
3640 return (ic_data() != NULL) && !ic_data()->IsNull(); | 3682 return (ic_data() != NULL) && !ic_data()->IsNull(); |
3641 } | 3683 } |
3642 | 3684 |
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4467 | 4509 |
4468 | 4510 |
4469 class AllocateObjectInstr : public TemplateDefinition<0> { | 4511 class AllocateObjectInstr : public TemplateDefinition<0> { |
4470 public: | 4512 public: |
4471 AllocateObjectInstr(intptr_t token_pos, | 4513 AllocateObjectInstr(intptr_t token_pos, |
4472 const Class& cls, | 4514 const Class& cls, |
4473 ZoneGrowableArray<PushArgumentInstr*>* arguments) | 4515 ZoneGrowableArray<PushArgumentInstr*>* arguments) |
4474 : token_pos_(token_pos), | 4516 : token_pos_(token_pos), |
4475 cls_(cls), | 4517 cls_(cls), |
4476 arguments_(arguments), | 4518 arguments_(arguments), |
4477 identity_(kIdentityUnknown), | 4519 identity_(AliasIdentity::Unknown()), |
4478 closure_function_(Function::ZoneHandle()) { | 4520 closure_function_(Function::ZoneHandle()) { |
4479 // Either no arguments or one type-argument and one instantiator. | 4521 // Either no arguments or one type-argument and one instantiator. |
4480 ASSERT(arguments->is_empty() || (arguments->length() == 1)); | 4522 ASSERT(arguments->is_empty() || (arguments->length() == 1)); |
4481 } | 4523 } |
4482 | 4524 |
4483 DECLARE_INSTRUCTION(AllocateObject) | 4525 DECLARE_INSTRUCTION(AllocateObject) |
4484 virtual CompileType ComputeType() const; | 4526 virtual CompileType ComputeType() const; |
4485 | 4527 |
4486 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 4528 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
4487 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { | 4529 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { |
(...skipping 28 matching lines...) Expand all Loading... |
4516 | 4558 |
4517 DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr); | 4559 DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr); |
4518 }; | 4560 }; |
4519 | 4561 |
4520 | 4562 |
4521 // This instruction captures the state of the object which had its allocation | 4563 // This instruction captures the state of the object which had its allocation |
4522 // removed during the AllocationSinking pass. | 4564 // removed during the AllocationSinking pass. |
4523 // It does not produce any real code only deoptimization information. | 4565 // It does not produce any real code only deoptimization information. |
4524 class MaterializeObjectInstr : public Definition { | 4566 class MaterializeObjectInstr : public Definition { |
4525 public: | 4567 public: |
4526 MaterializeObjectInstr(const Class& cls, | 4568 MaterializeObjectInstr(AllocateObjectInstr* allocation, |
| 4569 const Class& cls, |
4527 const ZoneGrowableArray<const Object*>& slots, | 4570 const ZoneGrowableArray<const Object*>& slots, |
4528 ZoneGrowableArray<Value*>* values) | 4571 ZoneGrowableArray<Value*>* values) |
4529 : cls_(cls), slots_(slots), values_(values), locations_(NULL) { | 4572 : allocation_(allocation), |
| 4573 cls_(cls), |
| 4574 slots_(slots), |
| 4575 values_(values), |
| 4576 locations_(NULL), |
| 4577 visited_for_liveness_(false), |
| 4578 registers_remapped_(false) { |
4530 ASSERT(slots_.length() == values_->length()); | 4579 ASSERT(slots_.length() == values_->length()); |
4531 for (intptr_t i = 0; i < InputCount(); i++) { | 4580 for (intptr_t i = 0; i < InputCount(); i++) { |
4532 InputAt(i)->set_instruction(this); | 4581 InputAt(i)->set_instruction(this); |
4533 InputAt(i)->set_use_index(i); | 4582 InputAt(i)->set_use_index(i); |
4534 } | 4583 } |
4535 } | 4584 } |
4536 | 4585 |
| 4586 AllocateObjectInstr* allocation() const { return allocation_; } |
4537 const Class& cls() const { return cls_; } | 4587 const Class& cls() const { return cls_; } |
4538 intptr_t FieldOffsetAt(intptr_t i) const { | 4588 intptr_t FieldOffsetAt(intptr_t i) const { |
4539 return slots_[i]->IsField() | 4589 return slots_[i]->IsField() |
4540 ? Field::Cast(*slots_[i]).Offset() | 4590 ? Field::Cast(*slots_[i]).Offset() |
4541 : Smi::Cast(*slots_[i]).Value(); | 4591 : Smi::Cast(*slots_[i]).Value(); |
4542 } | 4592 } |
4543 const Location& LocationAt(intptr_t i) { | 4593 const Location& LocationAt(intptr_t i) { |
4544 return locations_[i]; | 4594 return locations_[i]; |
4545 } | 4595 } |
4546 | 4596 |
(...skipping 22 matching lines...) Expand all Loading... |
4569 virtual EffectSet Effects() const { return EffectSet::None(); } | 4619 virtual EffectSet Effects() const { return EffectSet::None(); } |
4570 | 4620 |
4571 Location* locations() { return locations_; } | 4621 Location* locations() { return locations_; } |
4572 void set_locations(Location* locations) { locations_ = locations; } | 4622 void set_locations(Location* locations) { locations_ = locations; } |
4573 | 4623 |
4574 virtual bool MayThrow() const { return false; } | 4624 virtual bool MayThrow() const { return false; } |
4575 | 4625 |
4576 void RemapRegisters(intptr_t* fpu_reg_slots, | 4626 void RemapRegisters(intptr_t* fpu_reg_slots, |
4577 intptr_t* cpu_reg_slots); | 4627 intptr_t* cpu_reg_slots); |
4578 | 4628 |
| 4629 bool was_visited_for_liveness() const { return visited_for_liveness_; } |
| 4630 void mark_visited_for_liveness() { |
| 4631 visited_for_liveness_ = true; |
| 4632 } |
| 4633 |
4579 private: | 4634 private: |
4580 virtual void RawSetInputAt(intptr_t i, Value* value) { | 4635 virtual void RawSetInputAt(intptr_t i, Value* value) { |
4581 (*values_)[i] = value; | 4636 (*values_)[i] = value; |
4582 } | 4637 } |
4583 | 4638 |
| 4639 AllocateObjectInstr* allocation_; |
4584 const Class& cls_; | 4640 const Class& cls_; |
4585 const ZoneGrowableArray<const Object*>& slots_; | 4641 const ZoneGrowableArray<const Object*>& slots_; |
4586 ZoneGrowableArray<Value*>* values_; | 4642 ZoneGrowableArray<Value*>* values_; |
4587 Location* locations_; | 4643 Location* locations_; |
4588 | 4644 |
| 4645 bool visited_for_liveness_; |
| 4646 bool registers_remapped_; |
| 4647 |
4589 DISALLOW_COPY_AND_ASSIGN(MaterializeObjectInstr); | 4648 DISALLOW_COPY_AND_ASSIGN(MaterializeObjectInstr); |
4590 }; | 4649 }; |
4591 | 4650 |
4592 | 4651 |
4593 class CreateArrayInstr : public TemplateDefinition<2> { | 4652 class CreateArrayInstr : public TemplateDefinition<2> { |
4594 public: | 4653 public: |
4595 CreateArrayInstr(intptr_t token_pos, | 4654 CreateArrayInstr(intptr_t token_pos, |
4596 Value* element_type, | 4655 Value* element_type, |
4597 Value* num_elements) | 4656 Value* num_elements) |
4598 : token_pos_(token_pos), identity_(kIdentityUnknown) { | 4657 : token_pos_(token_pos), identity_(AliasIdentity::Unknown()) { |
4599 SetInputAt(kElementTypePos, element_type); | 4658 SetInputAt(kElementTypePos, element_type); |
4600 SetInputAt(kLengthPos, num_elements); | 4659 SetInputAt(kLengthPos, num_elements); |
4601 } | 4660 } |
4602 | 4661 |
4603 enum { | 4662 enum { |
4604 kElementTypePos = 0, | 4663 kElementTypePos = 0, |
4605 kLengthPos = 1 | 4664 kLengthPos = 1 |
4606 }; | 4665 }; |
4607 | 4666 |
4608 DECLARE_INSTRUCTION(CreateArray) | 4667 DECLARE_INSTRUCTION(CreateArray) |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4691 } | 4750 } |
4692 virtual bool AttributesEqual(Instruction* other) const { return true; } | 4751 virtual bool AttributesEqual(Instruction* other) const { return true; } |
4693 | 4752 |
4694 virtual bool MayThrow() const { return false; } | 4753 virtual bool MayThrow() const { return false; } |
4695 | 4754 |
4696 private: | 4755 private: |
4697 DISALLOW_COPY_AND_ASSIGN(LoadClassIdInstr); | 4756 DISALLOW_COPY_AND_ASSIGN(LoadClassIdInstr); |
4698 }; | 4757 }; |
4699 | 4758 |
4700 | 4759 |
4701 | |
4702 | |
4703 class LoadFieldInstr : public TemplateDefinition<1> { | 4760 class LoadFieldInstr : public TemplateDefinition<1> { |
4704 public: | 4761 public: |
4705 LoadFieldInstr(Value* instance, | 4762 LoadFieldInstr(Value* instance, |
4706 intptr_t offset_in_bytes, | 4763 intptr_t offset_in_bytes, |
4707 const AbstractType& type, | 4764 const AbstractType& type, |
4708 intptr_t token_pos) | 4765 intptr_t token_pos) |
4709 : offset_in_bytes_(offset_in_bytes), | 4766 : offset_in_bytes_(offset_in_bytes), |
4710 type_(type), | 4767 type_(type), |
4711 result_cid_(kDynamicCid), | 4768 result_cid_(kDynamicCid), |
4712 immutable_(false), | 4769 immutable_(false), |
(...skipping 3855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8568 ForwardInstructionIterator* current_iterator_; | 8625 ForwardInstructionIterator* current_iterator_; |
8569 | 8626 |
8570 private: | 8627 private: |
8571 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 8628 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
8572 }; | 8629 }; |
8573 | 8630 |
8574 | 8631 |
8575 } // namespace dart | 8632 } // namespace dart |
8576 | 8633 |
8577 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 8634 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |