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

Side by Side Diff: src/compiler/instruction-selector-impl.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 | « src/compiler/instruction.cc ('k') | src/compiler/register-allocator.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 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_SELECTOR_IMPL_H_ 5 #ifndef V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_
6 #define V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ 6 #define V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_
7 7
8 #include "src/compiler/instruction.h" 8 #include "src/compiler/instruction.h"
9 #include "src/compiler/instruction-selector.h" 9 #include "src/compiler/instruction-selector.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
11 #include "src/macro-assembler.h" 11 #include "src/macro-assembler.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 namespace compiler { 15 namespace compiler {
16 16
17 // A helper class for the instruction selector that simplifies construction of 17 // A helper class for the instruction selector that simplifies construction of
18 // Operands. This class implements a base for architecture-specific helpers. 18 // Operands. This class implements a base for architecture-specific helpers.
19 class OperandGenerator { 19 class OperandGenerator {
20 public: 20 public:
21 explicit OperandGenerator(InstructionSelector* selector) 21 explicit OperandGenerator(InstructionSelector* selector)
22 : selector_(selector) {} 22 : selector_(selector) {}
23 23
24 InstructionOperand* DefineAsRegister(Node* node) { 24 InstructionOperand* DefineAsRegister(Node* node) {
25 return Define(node, new (zone()) 25 return Define(node,
26 UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)); 26 new (zone()) UnallocatedOperand(
27 UnallocatedOperand::MUST_HAVE_REGISTER, GetVReg(node)));
27 } 28 }
28 29
29 InstructionOperand* DefineSameAsFirst(Node* result) { 30 InstructionOperand* DefineSameAsFirst(Node* node) {
30 return Define(result, new (zone()) 31 return Define(node,
31 UnallocatedOperand(UnallocatedOperand::SAME_AS_FIRST_INPUT)); 32 new (zone()) UnallocatedOperand(
33 UnallocatedOperand::SAME_AS_FIRST_INPUT, GetVReg(node)));
32 } 34 }
33 35
34 InstructionOperand* DefineAsFixed(Node* node, Register reg) { 36 InstructionOperand* DefineAsFixed(Node* node, Register reg) {
35 return Define(node, new (zone()) 37 return Define(node, new (zone()) UnallocatedOperand(
36 UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 38 UnallocatedOperand::FIXED_REGISTER,
37 Register::ToAllocationIndex(reg))); 39 Register::ToAllocationIndex(reg), GetVReg(node)));
38 } 40 }
39 41
40 InstructionOperand* DefineAsFixed(Node* node, DoubleRegister reg) { 42 InstructionOperand* DefineAsFixed(Node* node, DoubleRegister reg) {
41 return Define(node, new (zone()) 43 return Define(node,
42 UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER, 44 new (zone()) UnallocatedOperand(
43 DoubleRegister::ToAllocationIndex(reg))); 45 UnallocatedOperand::FIXED_DOUBLE_REGISTER,
46 DoubleRegister::ToAllocationIndex(reg), GetVReg(node)));
44 } 47 }
45 48
46 InstructionOperand* DefineAsConstant(Node* node) { 49 InstructionOperand* DefineAsConstant(Node* node) {
47 selector()->MarkAsDefined(node); 50 selector()->MarkAsDefined(node);
48 int virtual_register = selector_->GetVirtualRegister(node); 51 int virtual_register = GetVReg(node);
49 sequence()->AddConstant(virtual_register, ToConstant(node)); 52 sequence()->AddConstant(virtual_register, ToConstant(node));
50 return ConstantOperand::Create(virtual_register, zone()); 53 return ConstantOperand::Create(virtual_register, zone());
51 } 54 }
52 55
53 InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location, 56 InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location,
54 MachineType type) { 57 MachineType type) {
55 return Define(node, ToUnallocatedOperand(location, type)); 58 return Define(node, ToUnallocatedOperand(location, type, GetVReg(node)));
56 } 59 }
57 60
58 InstructionOperand* Use(Node* node) { 61 InstructionOperand* Use(Node* node) {
59 return Use( 62 return Use(node, new (zone()) UnallocatedOperand(
60 node, new (zone()) UnallocatedOperand( 63 UnallocatedOperand::NONE,
61 UnallocatedOperand::NONE, UnallocatedOperand::USED_AT_START)); 64 UnallocatedOperand::USED_AT_START, GetVReg(node)));
62 } 65 }
63 66
64 InstructionOperand* UseRegister(Node* node) { 67 InstructionOperand* UseRegister(Node* node) {
65 return Use(node, new (zone()) 68 return Use(node, new (zone()) UnallocatedOperand(
66 UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 69 UnallocatedOperand::MUST_HAVE_REGISTER,
67 UnallocatedOperand::USED_AT_START)); 70 UnallocatedOperand::USED_AT_START, GetVReg(node)));
68 } 71 }
69 72
70 // Use register or operand for the node. If a register is chosen, it won't 73 // Use register or operand for the node. If a register is chosen, it won't
71 // alias any temporary or output registers. 74 // alias any temporary or output registers.
72 InstructionOperand* UseUnique(Node* node) { 75 InstructionOperand* UseUnique(Node* node) {
73 return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::NONE)); 76 return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::NONE,
77 GetVReg(node)));
74 } 78 }
75 79
76 // Use a unique register for the node that does not alias any temporary or 80 // Use a unique register for the node that does not alias any temporary or
77 // output registers. 81 // output registers.
78 InstructionOperand* UseUniqueRegister(Node* node) { 82 InstructionOperand* UseUniqueRegister(Node* node) {
79 return Use(node, new (zone()) 83 return Use(node,
80 UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)); 84 new (zone()) UnallocatedOperand(
85 UnallocatedOperand::MUST_HAVE_REGISTER, GetVReg(node)));
81 } 86 }
82 87
83 InstructionOperand* UseFixed(Node* node, Register reg) { 88 InstructionOperand* UseFixed(Node* node, Register reg) {
84 return Use(node, new (zone()) 89 return Use(node, new (zone()) UnallocatedOperand(
85 UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 90 UnallocatedOperand::FIXED_REGISTER,
86 Register::ToAllocationIndex(reg))); 91 Register::ToAllocationIndex(reg), GetVReg(node)));
87 } 92 }
88 93
89 InstructionOperand* UseFixed(Node* node, DoubleRegister reg) { 94 InstructionOperand* UseFixed(Node* node, DoubleRegister reg) {
90 return Use(node, new (zone()) 95 return Use(node,
91 UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER, 96 new (zone()) UnallocatedOperand(
92 DoubleRegister::ToAllocationIndex(reg))); 97 UnallocatedOperand::FIXED_DOUBLE_REGISTER,
98 DoubleRegister::ToAllocationIndex(reg), GetVReg(node)));
93 } 99 }
94 100
95 InstructionOperand* UseImmediate(Node* node) { 101 InstructionOperand* UseImmediate(Node* node) {
96 int index = sequence()->AddImmediate(ToConstant(node)); 102 int index = sequence()->AddImmediate(ToConstant(node));
97 return ImmediateOperand::Create(index, zone()); 103 return ImmediateOperand::Create(index, zone());
98 } 104 }
99 105
100 InstructionOperand* UseLocation(Node* node, LinkageLocation location, 106 InstructionOperand* UseLocation(Node* node, LinkageLocation location,
101 MachineType type) { 107 MachineType type) {
102 return Use(node, ToUnallocatedOperand(location, type)); 108 return Use(node, ToUnallocatedOperand(location, type, GetVReg(node)));
103 } 109 }
104 110
105 InstructionOperand* TempRegister() { 111 InstructionOperand* TempRegister() {
106 UnallocatedOperand* op = 112 return new (zone()) UnallocatedOperand(
107 new (zone()) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 113 UnallocatedOperand::MUST_HAVE_REGISTER,
108 UnallocatedOperand::USED_AT_START); 114 UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister());
109 op->set_virtual_register(sequence()->NextVirtualRegister());
110 return op;
111 } 115 }
112 116
113 InstructionOperand* TempDoubleRegister() { 117 InstructionOperand* TempDoubleRegister() {
114 UnallocatedOperand* op = 118 UnallocatedOperand* op = new (zone()) UnallocatedOperand(
115 new (zone()) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 119 UnallocatedOperand::MUST_HAVE_REGISTER,
116 UnallocatedOperand::USED_AT_START); 120 UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister());
117 op->set_virtual_register(sequence()->NextVirtualRegister());
118 sequence()->MarkAsDouble(op->virtual_register()); 121 sequence()->MarkAsDouble(op->virtual_register());
119 return op; 122 return op;
120 } 123 }
121 124
122 InstructionOperand* TempRegister(Register reg) { 125 InstructionOperand* TempRegister(Register reg) {
123 return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 126 return new (zone()) UnallocatedOperand(
124 Register::ToAllocationIndex(reg)); 127 UnallocatedOperand::FIXED_REGISTER, Register::ToAllocationIndex(reg),
128 UnallocatedOperand::kInvalidVirtualRegister);
125 } 129 }
126 130
127 InstructionOperand* TempImmediate(int32_t imm) { 131 InstructionOperand* TempImmediate(int32_t imm) {
128 int index = sequence()->AddImmediate(Constant(imm)); 132 int index = sequence()->AddImmediate(Constant(imm));
129 return ImmediateOperand::Create(index, zone()); 133 return ImmediateOperand::Create(index, zone());
130 } 134 }
131 135
132 InstructionOperand* TempLocation(LinkageLocation location, MachineType type) { 136 InstructionOperand* TempLocation(LinkageLocation location, MachineType type) {
133 UnallocatedOperand* op = ToUnallocatedOperand(location, type); 137 return ToUnallocatedOperand(location, type,
134 op->set_virtual_register(sequence()->NextVirtualRegister()); 138 sequence()->NextVirtualRegister());
135 return op;
136 } 139 }
137 140
138 InstructionOperand* Label(BasicBlock* block) { 141 InstructionOperand* Label(BasicBlock* block) {
139 int index = sequence()->AddImmediate(Constant(block->GetRpoNumber())); 142 int index = sequence()->AddImmediate(Constant(block->GetRpoNumber()));
140 return ImmediateOperand::Create(index, zone()); 143 return ImmediateOperand::Create(index, zone());
141 } 144 }
142 145
143 protected: 146 protected:
144 InstructionSelector* selector() const { return selector_; } 147 InstructionSelector* selector() const { return selector_; }
145 InstructionSequence* sequence() const { return selector()->sequence(); } 148 InstructionSequence* sequence() const { return selector()->sequence(); }
146 Zone* zone() const { return selector()->instruction_zone(); } 149 Zone* zone() const { return selector()->instruction_zone(); }
147 150
148 private: 151 private:
152 int GetVReg(Node* node) const { return selector_->GetVirtualRegister(node); }
153
149 static Constant ToConstant(const Node* node) { 154 static Constant ToConstant(const Node* node) {
150 switch (node->opcode()) { 155 switch (node->opcode()) {
151 case IrOpcode::kInt32Constant: 156 case IrOpcode::kInt32Constant:
152 return Constant(OpParameter<int32_t>(node)); 157 return Constant(OpParameter<int32_t>(node));
153 case IrOpcode::kInt64Constant: 158 case IrOpcode::kInt64Constant:
154 return Constant(OpParameter<int64_t>(node)); 159 return Constant(OpParameter<int64_t>(node));
155 case IrOpcode::kFloat32Constant: 160 case IrOpcode::kFloat32Constant:
156 return Constant(OpParameter<float>(node)); 161 return Constant(OpParameter<float>(node));
157 case IrOpcode::kFloat64Constant: 162 case IrOpcode::kFloat64Constant:
158 case IrOpcode::kNumberConstant: 163 case IrOpcode::kNumberConstant:
159 return Constant(OpParameter<double>(node)); 164 return Constant(OpParameter<double>(node));
160 case IrOpcode::kExternalConstant: 165 case IrOpcode::kExternalConstant:
161 return Constant(OpParameter<ExternalReference>(node)); 166 return Constant(OpParameter<ExternalReference>(node));
162 case IrOpcode::kHeapConstant: 167 case IrOpcode::kHeapConstant:
163 return Constant(OpParameter<Unique<HeapObject> >(node).handle()); 168 return Constant(OpParameter<Unique<HeapObject> >(node).handle());
164 default: 169 default:
165 break; 170 break;
166 } 171 }
167 UNREACHABLE(); 172 UNREACHABLE();
168 return Constant(static_cast<int32_t>(0)); 173 return Constant(static_cast<int32_t>(0));
169 } 174 }
170 175
171 UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) { 176 UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) {
172 DCHECK_NOT_NULL(node); 177 DCHECK_NOT_NULL(node);
173 DCHECK_NOT_NULL(operand); 178 DCHECK_NOT_NULL(operand);
174 operand->set_virtual_register(selector_->GetVirtualRegister(node)); 179 DCHECK_EQ(operand->virtual_register(), GetVReg(node));
175 selector()->MarkAsDefined(node); 180 selector()->MarkAsDefined(node);
176 return operand; 181 return operand;
177 } 182 }
178 183
179 UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) { 184 UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) {
180 DCHECK_NOT_NULL(node); 185 DCHECK_NOT_NULL(node);
181 DCHECK_NOT_NULL(operand); 186 DCHECK_NOT_NULL(operand);
182 operand->set_virtual_register(selector_->GetVirtualRegister(node)); 187 DCHECK_EQ(operand->virtual_register(), GetVReg(node));
183 selector()->MarkAsUsed(node); 188 selector()->MarkAsUsed(node);
184 return operand; 189 return operand;
185 } 190 }
186 191
187 UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location, 192 UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location,
188 MachineType type) { 193 MachineType type,
194 int virtual_register) {
189 if (location.location_ == LinkageLocation::ANY_REGISTER) { 195 if (location.location_ == LinkageLocation::ANY_REGISTER) {
190 // any machine register. 196 // any machine register.
191 return new (zone()) 197 return new (zone()) UnallocatedOperand(
192 UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER); 198 UnallocatedOperand::MUST_HAVE_REGISTER, virtual_register);
193 } 199 }
194 if (location.location_ < 0) { 200 if (location.location_ < 0) {
195 // a location on the caller frame. 201 // a location on the caller frame.
196 return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_SLOT, 202 return new (zone()) UnallocatedOperand(
197 location.location_); 203 UnallocatedOperand::FIXED_SLOT, location.location_, virtual_register);
198 } 204 }
199 if (location.location_ > LinkageLocation::ANY_REGISTER) { 205 if (location.location_ > LinkageLocation::ANY_REGISTER) {
200 // a spill location on this (callee) frame. 206 // a spill location on this (callee) frame.
201 return new (zone()) UnallocatedOperand( 207 return new (zone()) UnallocatedOperand(
202 UnallocatedOperand::FIXED_SLOT, 208 UnallocatedOperand::FIXED_SLOT,
203 location.location_ - LinkageLocation::ANY_REGISTER - 1); 209 location.location_ - LinkageLocation::ANY_REGISTER - 1,
210 virtual_register);
204 } 211 }
205 // a fixed register. 212 // a fixed register.
206 if (RepresentationOf(type) == kRepFloat64) { 213 if (RepresentationOf(type) == kRepFloat64) {
207 return new (zone()) UnallocatedOperand( 214 return new (zone())
208 UnallocatedOperand::FIXED_DOUBLE_REGISTER, location.location_); 215 UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
216 location.location_, virtual_register);
209 } 217 }
210 return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 218 return new (zone())
211 location.location_); 219 UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
220 location.location_, virtual_register);
212 } 221 }
213 222
214 InstructionSelector* selector_; 223 InstructionSelector* selector_;
215 }; 224 };
216 225
217 226
218 // The flags continuation is a way to combine a branch or a materialization 227 // The flags continuation is a way to combine a branch or a materialization
219 // of a boolean value with an instruction that sets the flags register. 228 // of a boolean value with an instruction that sets the flags register.
220 // The whole instruction is treated as a unit by the register allocator, and 229 // The whole instruction is treated as a unit by the register allocator, and
221 // thus no spills or moves can be introduced between the flags-setting 230 // thus no spills or moves can be introduced between the flags-setting
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 : (frame_state_descriptor->GetTotalSize() + 363 : (frame_state_descriptor->GetTotalSize() +
355 1); // Include deopt id. 364 1); // Include deopt id.
356 } 365 }
357 }; 366 };
358 367
359 } // namespace compiler 368 } // namespace compiler
360 } // namespace internal 369 } // namespace internal
361 } // namespace v8 370 } // namespace v8
362 371
363 #endif // V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ 372 #endif // V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_
OLDNEW
« no previous file with comments | « src/compiler/instruction.cc ('k') | src/compiler/register-allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698