OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_INSTRUCTION_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_H_ |
6 #define V8_COMPILER_INSTRUCTION_H_ | 6 #define V8_COMPILER_INSTRUCTION_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 #include <map> | 10 #include <map> |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); } | 53 InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); } |
54 | 54 |
55 Kind kind() const { return KindField::decode(value_); } | 55 Kind kind() const { return KindField::decode(value_); } |
56 int index() const { return static_cast<int>(value_) >> KindField::kSize; } | 56 int index() const { return static_cast<int>(value_) >> KindField::kSize; } |
57 #define INSTRUCTION_OPERAND_PREDICATE(name, type, number) \ | 57 #define INSTRUCTION_OPERAND_PREDICATE(name, type, number) \ |
58 bool Is##name() const { return kind() == type; } | 58 bool Is##name() const { return kind() == type; } |
59 INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) | 59 INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) |
60 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) | 60 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) |
61 INSTRUCTION_OPERAND_PREDICATE(Ignored, INVALID, 0) | 61 INSTRUCTION_OPERAND_PREDICATE(Ignored, INVALID, 0) |
62 #undef INSTRUCTION_OPERAND_PREDICATE | 62 #undef INSTRUCTION_OPERAND_PREDICATE |
63 bool Equals(InstructionOperand* other) const { | 63 bool Equals(const InstructionOperand* other) const { |
64 return value_ == other->value_; | 64 return value_ == other->value_; |
65 } | 65 } |
66 | 66 |
67 void ConvertTo(Kind kind, int index) { | 67 void ConvertTo(Kind kind, int index) { |
68 if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0); | 68 if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0); |
69 value_ = KindField::encode(kind); | 69 value_ = KindField::encode(kind); |
70 value_ |= index << KindField::kSize; | 70 value_ |= index << KindField::kSize; |
71 DCHECK(this->index() == index); | 71 DCHECK(this->index() == index); |
72 } | 72 } |
73 | 73 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 USED_AT_START, | 113 USED_AT_START, |
114 | 114 |
115 // USED_AT_END operand is treated as live until the end of | 115 // USED_AT_END operand is treated as live until the end of |
116 // instruction. This means that register allocator will not reuse it's | 116 // instruction. This means that register allocator will not reuse it's |
117 // register for any other operand inside instruction. | 117 // register for any other operand inside instruction. |
118 USED_AT_END | 118 USED_AT_END |
119 }; | 119 }; |
120 | 120 |
121 explicit UnallocatedOperand(ExtendedPolicy policy) | 121 explicit UnallocatedOperand(ExtendedPolicy policy) |
122 : InstructionOperand(UNALLOCATED, 0) { | 122 : InstructionOperand(UNALLOCATED, 0) { |
| 123 value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister); |
123 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); | 124 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
124 value_ |= ExtendedPolicyField::encode(policy); | 125 value_ |= ExtendedPolicyField::encode(policy); |
125 value_ |= LifetimeField::encode(USED_AT_END); | 126 value_ |= LifetimeField::encode(USED_AT_END); |
126 } | 127 } |
127 | 128 |
128 UnallocatedOperand(BasicPolicy policy, int index) | 129 UnallocatedOperand(BasicPolicy policy, int index) |
129 : InstructionOperand(UNALLOCATED, 0) { | 130 : InstructionOperand(UNALLOCATED, 0) { |
130 DCHECK(policy == FIXED_SLOT); | 131 DCHECK(policy == FIXED_SLOT); |
| 132 value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister); |
131 value_ |= BasicPolicyField::encode(policy); | 133 value_ |= BasicPolicyField::encode(policy); |
132 value_ |= index << FixedSlotIndexField::kShift; | 134 value_ |= index << FixedSlotIndexField::kShift; |
133 DCHECK(this->fixed_slot_index() == index); | 135 DCHECK(this->fixed_slot_index() == index); |
134 } | 136 } |
135 | 137 |
136 UnallocatedOperand(ExtendedPolicy policy, int index) | 138 UnallocatedOperand(ExtendedPolicy policy, int index) |
137 : InstructionOperand(UNALLOCATED, 0) { | 139 : InstructionOperand(UNALLOCATED, 0) { |
138 DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER); | 140 DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER); |
| 141 value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister); |
139 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); | 142 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
140 value_ |= ExtendedPolicyField::encode(policy); | 143 value_ |= ExtendedPolicyField::encode(policy); |
141 value_ |= LifetimeField::encode(USED_AT_END); | 144 value_ |= LifetimeField::encode(USED_AT_END); |
142 value_ |= FixedRegisterField::encode(index); | 145 value_ |= FixedRegisterField::encode(index); |
143 } | 146 } |
144 | 147 |
145 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime) | 148 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime) |
146 : InstructionOperand(UNALLOCATED, 0) { | 149 : InstructionOperand(UNALLOCATED, 0) { |
| 150 value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister); |
147 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); | 151 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
148 value_ |= ExtendedPolicyField::encode(policy); | 152 value_ |= ExtendedPolicyField::encode(policy); |
149 value_ |= LifetimeField::encode(lifetime); | 153 value_ |= LifetimeField::encode(lifetime); |
150 } | 154 } |
151 | 155 |
152 UnallocatedOperand* CopyUnconstrained(Zone* zone) { | 156 UnallocatedOperand* CopyUnconstrained(Zone* zone) { |
153 UnallocatedOperand* result = new (zone) UnallocatedOperand(ANY); | 157 UnallocatedOperand* result = new (zone) UnallocatedOperand(ANY); |
154 result->set_virtual_register(virtual_register()); | 158 result->set_virtual_register(virtual_register()); |
155 return result; | 159 return result; |
156 } | 160 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 class VirtualRegisterField : public BitField<unsigned, 4, 18> {}; | 195 class VirtualRegisterField : public BitField<unsigned, 4, 18> {}; |
192 | 196 |
193 // BitFields specific to BasicPolicy::FIXED_SLOT. | 197 // BitFields specific to BasicPolicy::FIXED_SLOT. |
194 class FixedSlotIndexField : public BitField<int, 22, 10> {}; | 198 class FixedSlotIndexField : public BitField<int, 22, 10> {}; |
195 | 199 |
196 // BitFields specific to BasicPolicy::EXTENDED_POLICY. | 200 // BitFields specific to BasicPolicy::EXTENDED_POLICY. |
197 class ExtendedPolicyField : public BitField<ExtendedPolicy, 22, 3> {}; | 201 class ExtendedPolicyField : public BitField<ExtendedPolicy, 22, 3> {}; |
198 class LifetimeField : public BitField<Lifetime, 25, 1> {}; | 202 class LifetimeField : public BitField<Lifetime, 25, 1> {}; |
199 class FixedRegisterField : public BitField<int, 26, 6> {}; | 203 class FixedRegisterField : public BitField<int, 26, 6> {}; |
200 | 204 |
201 static const int kMaxVirtualRegisters = VirtualRegisterField::kMax + 1; | 205 static const int kInvalidVirtualRegister = VirtualRegisterField::kMax; |
| 206 static const int kMaxVirtualRegisters = VirtualRegisterField::kMax; |
202 static const int kFixedSlotIndexWidth = FixedSlotIndexField::kSize; | 207 static const int kFixedSlotIndexWidth = FixedSlotIndexField::kSize; |
203 static const int kMaxFixedSlotIndex = (1 << (kFixedSlotIndexWidth - 1)) - 1; | 208 static const int kMaxFixedSlotIndex = (1 << (kFixedSlotIndexWidth - 1)) - 1; |
204 static const int kMinFixedSlotIndex = -(1 << (kFixedSlotIndexWidth - 1)); | 209 static const int kMinFixedSlotIndex = -(1 << (kFixedSlotIndexWidth - 1)); |
205 | 210 |
206 // Predicates for the operand policy. | 211 // Predicates for the operand policy. |
207 bool HasAnyPolicy() const { | 212 bool HasAnyPolicy() const { |
208 return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY; | 213 return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY; |
209 } | 214 } |
210 bool HasFixedPolicy() const { | 215 bool HasFixedPolicy() const { |
211 return basic_policy() == FIXED_SLOT || | 216 return basic_policy() == FIXED_SLOT || |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 LAST_INNER_POSITION = AFTER | 584 LAST_INNER_POSITION = AFTER |
580 }; | 585 }; |
581 | 586 |
582 ParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) { | 587 ParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) { |
583 if (parallel_moves_[pos] == NULL) { | 588 if (parallel_moves_[pos] == NULL) { |
584 parallel_moves_[pos] = new (zone) ParallelMove(zone); | 589 parallel_moves_[pos] = new (zone) ParallelMove(zone); |
585 } | 590 } |
586 return parallel_moves_[pos]; | 591 return parallel_moves_[pos]; |
587 } | 592 } |
588 | 593 |
589 ParallelMove* GetParallelMove(InnerPosition pos) const { | 594 ParallelMove* GetParallelMove(InnerPosition pos) { |
590 return parallel_moves_[pos]; | 595 return parallel_moves_[pos]; |
591 } | 596 } |
592 | 597 |
| 598 const ParallelMove* GetParallelMove(InnerPosition pos) const { |
| 599 return parallel_moves_[pos]; |
| 600 } |
| 601 |
593 static GapInstruction* New(Zone* zone) { | 602 static GapInstruction* New(Zone* zone) { |
594 void* buffer = zone->New(sizeof(GapInstruction)); | 603 void* buffer = zone->New(sizeof(GapInstruction)); |
595 return new (buffer) GapInstruction(kGapInstruction); | 604 return new (buffer) GapInstruction(kGapInstruction); |
596 } | 605 } |
597 | 606 |
598 static GapInstruction* cast(Instruction* instr) { | 607 static GapInstruction* cast(Instruction* instr) { |
599 DCHECK(instr->IsGapMoves()); | 608 DCHECK(instr->IsGapMoves()); |
600 return static_cast<GapInstruction*>(instr); | 609 return static_cast<GapInstruction*>(instr); |
601 } | 610 } |
602 | 611 |
(...skipping 24 matching lines...) Expand all Loading... |
627 static BlockStartInstruction* New(Zone* zone) { | 636 static BlockStartInstruction* New(Zone* zone) { |
628 void* buffer = zone->New(sizeof(BlockStartInstruction)); | 637 void* buffer = zone->New(sizeof(BlockStartInstruction)); |
629 return new (buffer) BlockStartInstruction(); | 638 return new (buffer) BlockStartInstruction(); |
630 } | 639 } |
631 | 640 |
632 static BlockStartInstruction* cast(Instruction* instr) { | 641 static BlockStartInstruction* cast(Instruction* instr) { |
633 DCHECK(instr->IsBlockStart()); | 642 DCHECK(instr->IsBlockStart()); |
634 return static_cast<BlockStartInstruction*>(instr); | 643 return static_cast<BlockStartInstruction*>(instr); |
635 } | 644 } |
636 | 645 |
| 646 static const BlockStartInstruction* cast(const Instruction* instr) { |
| 647 DCHECK(instr->IsBlockStart()); |
| 648 return static_cast<const BlockStartInstruction*>(instr); |
| 649 } |
| 650 |
637 private: | 651 private: |
638 BlockStartInstruction() : GapInstruction(kBlockStartInstruction) {} | 652 BlockStartInstruction() : GapInstruction(kBlockStartInstruction) {} |
639 }; | 653 }; |
640 | 654 |
641 | 655 |
642 class SourcePositionInstruction FINAL : public Instruction { | 656 class SourcePositionInstruction FINAL : public Instruction { |
643 public: | 657 public: |
644 static SourcePositionInstruction* New(Zone* zone, SourcePosition position) { | 658 static SourcePositionInstruction* New(Zone* zone, SourcePosition position) { |
645 void* buffer = zone->New(sizeof(SourcePositionInstruction)); | 659 void* buffer = zone->New(sizeof(SourcePositionInstruction)); |
646 return new (buffer) SourcePositionInstruction(position); | 660 return new (buffer) SourcePositionInstruction(position); |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 const InstructionBlock* GetInstructionBlock(int instruction_index) const; | 924 const InstructionBlock* GetInstructionBlock(int instruction_index) const; |
911 | 925 |
912 bool IsReference(int virtual_register) const; | 926 bool IsReference(int virtual_register) const; |
913 bool IsDouble(int virtual_register) const; | 927 bool IsDouble(int virtual_register) const; |
914 | 928 |
915 void MarkAsReference(int virtual_register); | 929 void MarkAsReference(int virtual_register); |
916 void MarkAsDouble(int virtual_register); | 930 void MarkAsDouble(int virtual_register); |
917 | 931 |
918 void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to); | 932 void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to); |
919 | 933 |
920 BlockStartInstruction* GetBlockStart(BasicBlock::RpoNumber rpo); | 934 BlockStartInstruction* GetBlockStart(BasicBlock::RpoNumber rpo) const; |
921 | 935 |
922 typedef InstructionDeque::const_iterator const_iterator; | 936 typedef InstructionDeque::const_iterator const_iterator; |
923 const_iterator begin() const { return instructions_.begin(); } | 937 const_iterator begin() const { return instructions_.begin(); } |
924 const_iterator end() const { return instructions_.end(); } | 938 const_iterator end() const { return instructions_.end(); } |
925 const InstructionDeque& instructions() const { return instructions_; } | 939 const InstructionDeque& instructions() const { return instructions_; } |
926 | 940 |
927 GapInstruction* GapAt(int index) const { | 941 GapInstruction* GapAt(int index) const { |
928 return GapInstruction::cast(InstructionAt(index)); | 942 return GapInstruction::cast(InstructionAt(index)); |
929 } | 943 } |
930 bool IsGapAt(int index) const { return InstructionAt(index)->IsGapMoves(); } | 944 bool IsGapAt(int index) const { return InstructionAt(index)->IsGapMoves(); } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 | 1025 |
1012 | 1026 |
1013 std::ostream& operator<<(std::ostream& os, | 1027 std::ostream& operator<<(std::ostream& os, |
1014 const PrintableInstructionSequence& code); | 1028 const PrintableInstructionSequence& code); |
1015 | 1029 |
1016 } // namespace compiler | 1030 } // namespace compiler |
1017 } // namespace internal | 1031 } // namespace internal |
1018 } // namespace v8 | 1032 } // namespace v8 |
1019 | 1033 |
1020 #endif // V8_COMPILER_INSTRUCTION_H_ | 1034 #endif // V8_COMPILER_INSTRUCTION_H_ |
OLD | NEW |