| 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 |