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

Side by Side Diff: src/compiler/instruction.h

Issue 893913004: [turbofan] push virtual register field down to InstructionOperand (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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
« no previous file with comments | « no previous file | src/compiler/instruction.cc » ('j') | src/compiler/instruction-selector-impl.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 19 matching lines...) Expand all
30 #define INSTRUCTION_OPERAND_LIST(V) \ 30 #define INSTRUCTION_OPERAND_LIST(V) \
31 V(Constant, CONSTANT, 0) \ 31 V(Constant, CONSTANT, 0) \
32 V(Immediate, IMMEDIATE, 0) \ 32 V(Immediate, IMMEDIATE, 0) \
33 V(StackSlot, STACK_SLOT, 128) \ 33 V(StackSlot, STACK_SLOT, 128) \
34 V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \ 34 V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \
35 V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \ 35 V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \
36 V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters) 36 V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters)
37 37
38 class InstructionOperand : public ZoneObject { 38 class InstructionOperand : public ZoneObject {
39 public: 39 public:
40 static const int kInvalidVirtualRegister = -1;
41
40 enum Kind { 42 enum Kind {
43 INVALID,
41 UNALLOCATED, 44 UNALLOCATED,
42 CONSTANT, 45 CONSTANT,
43 IMMEDIATE, 46 IMMEDIATE,
44 STACK_SLOT, 47 STACK_SLOT,
45 DOUBLE_STACK_SLOT, 48 DOUBLE_STACK_SLOT,
46 REGISTER, 49 REGISTER,
47 DOUBLE_REGISTER 50 DOUBLE_REGISTER
48 }; 51 };
49 52
50 InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); } 53 InstructionOperand(Kind kind, int index)
54 : virtual_register_(kInvalidVirtualRegister) {
55 DCHECK(kind != INVALID);
56 ConvertTo(kind, index);
57 }
51 58
52 Kind kind() const { return KindField::decode(value_); } 59 Kind kind() const { return KindField::decode(value_); }
53 int index() const { return static_cast<int>(value_) >> KindField::kSize; } 60 int index() const { return static_cast<int>(value_) >> KindField::kSize; }
54 #define INSTRUCTION_OPERAND_PREDICATE(name, type, number) \ 61 #define INSTRUCTION_OPERAND_PREDICATE(name, type, number) \
55 bool Is##name() const { return kind() == type; } 62 bool Is##name() const { return kind() == type; }
56 INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) 63 INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE)
57 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) 64 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0)
58 #undef INSTRUCTION_OPERAND_PREDICATE 65 #undef INSTRUCTION_OPERAND_PREDICATE
59 bool Equals(const InstructionOperand* other) const { 66 bool Equals(const InstructionOperand* other) const {
60 return value_ == other->value_; 67 return value_ == other->value_;
61 } 68 }
62 69
63 void ConvertTo(Kind kind, int index) { 70 void ConvertTo(Kind kind, int index) {
64 if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0); 71 if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0);
65 value_ = KindField::encode(kind); 72 value_ = KindField::encode(kind);
66 value_ |= bit_cast<unsigned>(index << KindField::kSize); 73 value_ |= bit_cast<unsigned>(index << KindField::kSize);
67 DCHECK(this->index() == index); 74 DCHECK(this->index() == index);
68 } 75 }
69 76
70 // Calls SetUpCache()/TearDownCache() for each subclass. 77 // Calls SetUpCache()/TearDownCache() for each subclass.
71 static void SetUpCaches(); 78 static void SetUpCaches();
72 static void TearDownCaches(); 79 static void TearDownCaches();
73 80
74 protected: 81 protected:
75 // TODO(dcarney): remove. used to construct the Instruction operand array. 82 InstructionOperand(Kind kind, int index, int virtual_register)
76 InstructionOperand() : value_(0xffffffff) {} 83 : virtual_register_(virtual_register) {
84 ConvertTo(kind, index);
85 }
77 typedef BitField<Kind, 0, 3> KindField; 86 typedef BitField<Kind, 0, 3> KindField;
78 87
79 uint32_t value_; 88 uint32_t value_;
89 // TODO(dcarney): this should really be unsigned.
90 int32_t virtual_register_;
80 }; 91 };
81 92
82 typedef ZoneVector<InstructionOperand*> InstructionOperandVector; 93 typedef ZoneVector<InstructionOperand*> InstructionOperandVector;
83 94
84 struct PrintableInstructionOperand { 95 struct PrintableInstructionOperand {
85 const RegisterConfiguration* register_configuration_; 96 const RegisterConfiguration* register_configuration_;
86 const InstructionOperand* op_; 97 const InstructionOperand* op_;
87 }; 98 };
88 99
89 std::ostream& operator<<(std::ostream& os, 100 std::ostream& operator<<(std::ostream& os,
(...skipping 19 matching lines...) Expand all
109 // to some other operand used inside instruction (i.e. temporary or 120 // to some other operand used inside instruction (i.e. temporary or
110 // output). 121 // output).
111 USED_AT_START, 122 USED_AT_START,
112 123
113 // USED_AT_END operand is treated as live until the end of 124 // USED_AT_END operand is treated as live until the end of
114 // instruction. This means that register allocator will not reuse it's 125 // instruction. This means that register allocator will not reuse it's
115 // register for any other operand inside instruction. 126 // register for any other operand inside instruction.
116 USED_AT_END 127 USED_AT_END
117 }; 128 };
118 129
130 // TODO(dcarney): remove this.
119 static const int kInvalidVirtualRegister = -1; 131 static const int kInvalidVirtualRegister = -1;
120 132
121 explicit UnallocatedOperand(ExtendedPolicy policy) 133 // This is only for array initialization.
122 : InstructionOperand(UNALLOCATED, 0), 134 UnallocatedOperand()
123 virtual_register_(kInvalidVirtualRegister) { 135 : InstructionOperand(INVALID, 0, kInvalidVirtualRegister) {}
136
137 UnallocatedOperand(ExtendedPolicy policy, int virtual_register)
138 : InstructionOperand(UNALLOCATED, 0, virtual_register) {
124 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 139 value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
125 value_ |= ExtendedPolicyField::encode(policy); 140 value_ |= ExtendedPolicyField::encode(policy);
126 value_ |= LifetimeField::encode(USED_AT_END); 141 value_ |= LifetimeField::encode(USED_AT_END);
127 } 142 }
128 143
129 UnallocatedOperand(BasicPolicy policy, int index) 144 UnallocatedOperand(BasicPolicy policy, int index, int virtual_register)
130 : InstructionOperand(UNALLOCATED, 0), 145 : InstructionOperand(UNALLOCATED, 0, virtual_register) {
131 virtual_register_(kInvalidVirtualRegister) {
132 DCHECK(policy == FIXED_SLOT); 146 DCHECK(policy == FIXED_SLOT);
133 value_ |= BasicPolicyField::encode(policy); 147 value_ |= BasicPolicyField::encode(policy);
134 value_ |= static_cast<int32_t>(index) << FixedSlotIndexField::kShift; 148 value_ |= static_cast<int32_t>(index) << FixedSlotIndexField::kShift;
135 DCHECK(this->fixed_slot_index() == index); 149 DCHECK(this->fixed_slot_index() == index);
136 } 150 }
137 151
138 UnallocatedOperand(ExtendedPolicy policy, int index) 152 UnallocatedOperand(ExtendedPolicy policy, int index, int virtual_register)
139 : InstructionOperand(UNALLOCATED, 0), 153 : InstructionOperand(UNALLOCATED, 0, virtual_register) {
140 virtual_register_(kInvalidVirtualRegister) {
141 DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER); 154 DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER);
142 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 155 value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
143 value_ |= ExtendedPolicyField::encode(policy); 156 value_ |= ExtendedPolicyField::encode(policy);
144 value_ |= LifetimeField::encode(USED_AT_END); 157 value_ |= LifetimeField::encode(USED_AT_END);
145 value_ |= FixedRegisterField::encode(index); 158 value_ |= FixedRegisterField::encode(index);
146 } 159 }
147 160
148 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime) 161 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime,
149 : InstructionOperand(UNALLOCATED, 0), 162 int virtual_register)
150 virtual_register_(kInvalidVirtualRegister) { 163 : InstructionOperand(UNALLOCATED, 0, virtual_register) {
151 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 164 value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
152 value_ |= ExtendedPolicyField::encode(policy); 165 value_ |= ExtendedPolicyField::encode(policy);
153 value_ |= LifetimeField::encode(lifetime); 166 value_ |= LifetimeField::encode(lifetime);
154 } 167 }
155 168
156 UnallocatedOperand* CopyUnconstrained(Zone* zone) { 169 UnallocatedOperand* CopyUnconstrained(Zone* zone) {
157 UnallocatedOperand* result = new (zone) UnallocatedOperand(ANY); 170 return new (zone) UnallocatedOperand(ANY, virtual_register());
158 result->set_virtual_register(virtual_register());
159 return result;
160 } 171 }
161 172
162 static const UnallocatedOperand* cast(const InstructionOperand* op) { 173 static const UnallocatedOperand* cast(const InstructionOperand* op) {
163 DCHECK(op->IsUnallocated()); 174 DCHECK(op->IsUnallocated());
164 return static_cast<const UnallocatedOperand*>(op); 175 return static_cast<const UnallocatedOperand*>(op);
165 } 176 }
166 177
167 static UnallocatedOperand* cast(InstructionOperand* op) { 178 static UnallocatedOperand* cast(InstructionOperand* op) {
168 DCHECK(op->IsUnallocated()); 179 DCHECK(op->IsUnallocated());
169 return static_cast<UnallocatedOperand*>(op); 180 return static_cast<UnallocatedOperand*>(op);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 bool HasFixedRegisterPolicy() const { 237 bool HasFixedRegisterPolicy() const {
227 return basic_policy() == EXTENDED_POLICY && 238 return basic_policy() == EXTENDED_POLICY &&
228 extended_policy() == FIXED_REGISTER; 239 extended_policy() == FIXED_REGISTER;
229 } 240 }
230 bool HasFixedDoubleRegisterPolicy() const { 241 bool HasFixedDoubleRegisterPolicy() const {
231 return basic_policy() == EXTENDED_POLICY && 242 return basic_policy() == EXTENDED_POLICY &&
232 extended_policy() == FIXED_DOUBLE_REGISTER; 243 extended_policy() == FIXED_DOUBLE_REGISTER;
233 } 244 }
234 245
235 // [basic_policy]: Distinguish between FIXED_SLOT and all other policies. 246 // [basic_policy]: Distinguish between FIXED_SLOT and all other policies.
236 BasicPolicy basic_policy() const { return BasicPolicyField::decode(value_); } 247 BasicPolicy basic_policy() const {
248 DCHECK_EQ(UNALLOCATED, kind());
249 return BasicPolicyField::decode(value_);
250 }
237 251
238 // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy. 252 // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy.
239 ExtendedPolicy extended_policy() const { 253 ExtendedPolicy extended_policy() const {
240 DCHECK(basic_policy() == EXTENDED_POLICY); 254 DCHECK(basic_policy() == EXTENDED_POLICY);
241 return ExtendedPolicyField::decode(value_); 255 return ExtendedPolicyField::decode(value_);
242 } 256 }
243 257
244 // [fixed_slot_index]: Only for FIXED_SLOT. 258 // [fixed_slot_index]: Only for FIXED_SLOT.
245 int fixed_slot_index() const { 259 int fixed_slot_index() const {
246 DCHECK(HasFixedSlotPolicy()); 260 DCHECK(HasFixedSlotPolicy());
247 return static_cast<int>(bit_cast<int32_t>(value_) >> 261 return static_cast<int>(bit_cast<int32_t>(value_) >>
248 FixedSlotIndexField::kShift); 262 FixedSlotIndexField::kShift);
249 } 263 }
250 264
251 // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER. 265 // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER.
252 int fixed_register_index() const { 266 int fixed_register_index() const {
253 DCHECK(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy()); 267 DCHECK(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy());
254 return FixedRegisterField::decode(value_); 268 return FixedRegisterField::decode(value_);
255 } 269 }
256 270
257 // [virtual_register]: The virtual register ID for this operand. 271 // [virtual_register]: The virtual register ID for this operand.
258 int32_t virtual_register() const { return virtual_register_; } 272 int32_t virtual_register() const {
259 void set_virtual_register(int32_t id) { virtual_register_ = id; } 273 DCHECK_EQ(UNALLOCATED, kind());
274 return virtual_register_;
275 }
276
277 // TODO(dcarney): remove this.
278 void set_virtual_register(int32_t id) {
279 DCHECK_EQ(UNALLOCATED, kind());
280 virtual_register_ = id;
281 }
260 282
261 // [lifetime]: Only for non-FIXED_SLOT. 283 // [lifetime]: Only for non-FIXED_SLOT.
262 bool IsUsedAtStart() const { 284 bool IsUsedAtStart() const {
263 DCHECK(basic_policy() == EXTENDED_POLICY); 285 DCHECK(basic_policy() == EXTENDED_POLICY);
264 return LifetimeField::decode(value_) == USED_AT_START; 286 return LifetimeField::decode(value_) == USED_AT_START;
265 } 287 }
266
267 private:
268 friend class Instruction;
269 UnallocatedOperand()
270 : InstructionOperand(), virtual_register_(kInvalidVirtualRegister) {}
271
272 // TODO(dcarney): this should really be unsigned.
273 int32_t virtual_register_;
274 }; 288 };
275 289
276 290
277 class MoveOperands FINAL { 291 class MoveOperands FINAL {
278 public: 292 public:
279 MoveOperands(InstructionOperand* source, InstructionOperand* destination) 293 MoveOperands(InstructionOperand* source, InstructionOperand* destination)
280 : source_(source), destination_(destination) {} 294 : source_(source), destination_(destination) {}
281 295
282 InstructionOperand* source() const { return source_; } 296 InstructionOperand* source() const { return source_; }
283 void set_source(InstructionOperand* operand) { source_ = operand; } 297 void set_source(InstructionOperand* operand) { source_ = operand; }
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 790
777 class PhiInstruction FINAL : public ZoneObject { 791 class PhiInstruction FINAL : public ZoneObject {
778 public: 792 public:
779 typedef ZoneVector<InstructionOperand*> Inputs; 793 typedef ZoneVector<InstructionOperand*> Inputs;
780 794
781 PhiInstruction(Zone* zone, int virtual_register, size_t reserved_input_count) 795 PhiInstruction(Zone* zone, int virtual_register, size_t reserved_input_count)
782 : virtual_register_(virtual_register), 796 : virtual_register_(virtual_register),
783 operands_(zone), 797 operands_(zone),
784 output_(nullptr), 798 output_(nullptr),
785 inputs_(zone) { 799 inputs_(zone) {
786 UnallocatedOperand* output = 800 UnallocatedOperand* output = new (zone)
787 new (zone) UnallocatedOperand(UnallocatedOperand::NONE); 801 UnallocatedOperand(UnallocatedOperand::NONE, virtual_register);
788 output->set_virtual_register(virtual_register);
789 output_ = output; 802 output_ = output;
790 inputs_.reserve(reserved_input_count); 803 inputs_.reserve(reserved_input_count);
791 operands_.reserve(reserved_input_count); 804 operands_.reserve(reserved_input_count);
792 } 805 }
793 806
794 int virtual_register() const { return virtual_register_; } 807 int virtual_register() const { return virtual_register_; }
795 const IntVector& operands() const { return operands_; } 808 const IntVector& operands() const { return operands_; }
796 809
797 void Extend(Zone* zone, int virtual_register) { 810 void Extend(Zone* zone, int virtual_register) {
798 UnallocatedOperand* input = 811 UnallocatedOperand* input = new (zone)
799 new (zone) UnallocatedOperand(UnallocatedOperand::ANY); 812 UnallocatedOperand(UnallocatedOperand::ANY, virtual_register);
800 input->set_virtual_register(virtual_register);
801 operands_.push_back(virtual_register); 813 operands_.push_back(virtual_register);
802 inputs_.push_back(input); 814 inputs_.push_back(input);
803 } 815 }
804 816
805 InstructionOperand* output() const { return output_; } 817 InstructionOperand* output() const { return output_; }
806 const Inputs& inputs() const { return inputs_; } 818 const Inputs& inputs() const { return inputs_; }
807 Inputs& inputs() { return inputs_; } 819 Inputs& inputs() { return inputs_; }
808 820
809 private: 821 private:
810 // TODO(dcarney): some of these fields are only for verification, move them to 822 // TODO(dcarney): some of these fields are only for verification, move them to
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 1067
1056 1068
1057 std::ostream& operator<<(std::ostream& os, 1069 std::ostream& operator<<(std::ostream& os,
1058 const PrintableInstructionSequence& code); 1070 const PrintableInstructionSequence& code);
1059 1071
1060 } // namespace compiler 1072 } // namespace compiler
1061 } // namespace internal 1073 } // namespace internal
1062 } // namespace v8 1074 } // namespace v8
1063 1075
1064 #endif // V8_COMPILER_INSTRUCTION_H_ 1076 #endif // V8_COMPILER_INSTRUCTION_H_
OLDNEW
« no previous file with comments | « no previous file | src/compiler/instruction.cc » ('j') | src/compiler/instruction-selector-impl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698