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

Side by Side Diff: src/compiler/instruction-selector-impl.h

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

Powered by Google App Engine
This is Rietveld 408576698