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

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

Issue 395943003: Support allocation sinking for compound objects. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: improve tests Created 6 years, 5 months 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 1745 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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_
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