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

Side by Side Diff: src/compiler/simd-scalar-lowering.cc

Issue 2498283002: [wasm] implement simd lowering for replaceLane, load, store and test for phi (Closed)
Patch Set: [wasm] implement simd lowering for replaceLane, load, store and test for phi Created 4 years 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/simd-scalar-lowering.h ('k') | src/compiler/wasm-compiler.h » ('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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #include "src/compiler/simd-scalar-lowering.h" 5 #include "src/compiler/simd-scalar-lowering.h"
6 #include "src/compiler/diamond.h" 6 #include "src/compiler/diamond.h"
7 #include "src/compiler/linkage.h" 7 #include "src/compiler/linkage.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 10
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 } else { 51 } else {
52 // Push the next input onto the stack. 52 // Push the next input onto the stack.
53 Node* input = top.node->InputAt(top.input_index++); 53 Node* input = top.node->InputAt(top.input_index++);
54 if (state_.Get(input) == State::kUnvisited) { 54 if (state_.Get(input) == State::kUnvisited) {
55 SetLoweredType(input, top.node); 55 SetLoweredType(input, top.node);
56 if (input->opcode() == IrOpcode::kPhi) { 56 if (input->opcode() == IrOpcode::kPhi) {
57 // To break cycles with phi nodes we push phis on a separate stack so 57 // To break cycles with phi nodes we push phis on a separate stack so
58 // that they are processed after all other nodes. 58 // that they are processed after all other nodes.
59 PreparePhiReplacement(input); 59 PreparePhiReplacement(input);
60 stack_.push_front({input, 0}); 60 stack_.push_front({input, 0});
61 } else if (input->opcode() == IrOpcode::kEffectPhi ||
62 input->opcode() == IrOpcode::kLoop) {
63 stack_.push_front({input, 0});
61 } else { 64 } else {
62 stack_.push_back({input, 0}); 65 stack_.push_back({input, 0});
63 } 66 }
64 state_.Set(input, State::kOnStack); 67 state_.Set(input, State::kOnStack);
65 } 68 }
66 } 69 }
67 } 70 }
68 } 71 }
69 72
70 #define FOREACH_INT32X4_OPCODE(V) \ 73 #define FOREACH_INT32X4_OPCODE(V) \
71 V(Int32x4Add) \ 74 V(Int32x4Add) \
72 V(Int32x4ExtractLane) \ 75 V(Int32x4ExtractLane) \
73 V(CreateInt32x4) 76 V(CreateInt32x4) \
77 V(Int32x4ReplaceLane)
74 78
75 #define FOREACH_FLOAT32X4_OPCODE(V) \ 79 #define FOREACH_FLOAT32X4_OPCODE(V) \
76 V(Float32x4Add) \ 80 V(Float32x4Add) \
77 V(Float32x4ExtractLane) \ 81 V(Float32x4ExtractLane) \
78 V(CreateFloat32x4) 82 V(CreateFloat32x4) \
83 V(Float32x4ReplaceLane)
79 84
80 void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { 85 void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
81 switch (node->opcode()) { 86 switch (node->opcode()) {
82 #define CASE_STMT(name) case IrOpcode::k##name: 87 #define CASE_STMT(name) case IrOpcode::k##name:
83 FOREACH_INT32X4_OPCODE(CASE_STMT) 88 FOREACH_INT32X4_OPCODE(CASE_STMT)
84 case IrOpcode::kReturn: 89 case IrOpcode::kReturn:
85 case IrOpcode::kParameter: 90 case IrOpcode::kParameter:
86 case IrOpcode::kCall: { 91 case IrOpcode::kCall: {
87 replacements_[node->id()].type = SimdType::kInt32; 92 replacements_[node->id()].type = SimdType::kInt32;
88 break; 93 break;
89 } 94 }
90 FOREACH_FLOAT32X4_OPCODE(CASE_STMT) { 95 FOREACH_FLOAT32X4_OPCODE(CASE_STMT) {
91 replacements_[node->id()].type = SimdType::kFloat32; 96 replacements_[node->id()].type = SimdType::kFloat32;
92 break; 97 break;
93 } 98 }
94 #undef CASE_STMT 99 #undef CASE_STMT
95 default: 100 default:
96 replacements_[node->id()].type = replacements_[output->id()].type; 101 replacements_[node->id()].type = replacements_[output->id()].type;
97 } 102 }
98 } 103 }
99 104
100 static int GetParameterIndexAfterLowering( 105 static int GetParameterIndexAfterLowering(
101 Signature<MachineRepresentation>* signature, int old_index) { 106 Signature<MachineRepresentation>* signature, int old_index) {
102 // In function calls, the simd128 types are passed as 4 Int32 types. The 107 // In function calls, the simd128 types are passed as 4 Int32 types. The
103 // parameters are typecast to the types as needed for various operations. 108 // parameters are typecast to the types as needed for various operations.
104 int result = old_index; 109 int result = old_index;
105 for (int i = 0; i < old_index; i++) { 110 for (int i = 0; i < old_index; ++i) {
106 if (signature->GetParam(i) == MachineRepresentation::kSimd128) { 111 if (signature->GetParam(i) == MachineRepresentation::kSimd128) {
107 result += 3; 112 result += 3;
108 } 113 }
109 } 114 }
110 return result; 115 return result;
111 } 116 }
112 117
113 int SimdScalarLowering::GetParameterCountAfterLowering() { 118 int SimdScalarLowering::GetParameterCountAfterLowering() {
114 if (parameter_count_after_lowering_ == -1) { 119 if (parameter_count_after_lowering_ == -1) {
115 // GetParameterIndexAfterLowering(parameter_count) returns the parameter 120 // GetParameterIndexAfterLowering(parameter_count) returns the parameter
116 // count after lowering. 121 // count after lowering.
117 parameter_count_after_lowering_ = GetParameterIndexAfterLowering( 122 parameter_count_after_lowering_ = GetParameterIndexAfterLowering(
118 signature(), static_cast<int>(signature()->parameter_count())); 123 signature(), static_cast<int>(signature()->parameter_count()));
119 } 124 }
120 return parameter_count_after_lowering_; 125 return parameter_count_after_lowering_;
121 } 126 }
122 127
123 static int GetReturnCountAfterLowering( 128 static int GetReturnCountAfterLowering(
124 Signature<MachineRepresentation>* signature) { 129 Signature<MachineRepresentation>* signature) {
125 int result = static_cast<int>(signature->return_count()); 130 int result = static_cast<int>(signature->return_count());
126 for (int i = 0; i < static_cast<int>(signature->return_count()); i++) { 131 for (int i = 0; i < static_cast<int>(signature->return_count()); ++i) {
127 if (signature->GetReturn(i) == MachineRepresentation::kSimd128) { 132 if (signature->GetReturn(i) == MachineRepresentation::kSimd128) {
128 result += 3; 133 result += 3;
129 } 134 }
130 } 135 }
131 return result; 136 return result;
132 } 137 }
133 138
139 void SimdScalarLowering::GetIndexNodes(Node* index, Node** new_indices) {
140 new_indices[0] = index;
141 for (size_t i = 1; i < kMaxLanes; ++i) {
142 new_indices[i] = graph()->NewNode(machine()->Int32Add(), index,
143 graph()->NewNode(common()->Int32Constant(
144 static_cast<int>(i) * kLaneWidth)));
145 }
146 }
147
148 void SimdScalarLowering::LowerLoadOp(MachineRepresentation rep, Node* node,
149 const Operator* load_op) {
150 if (rep == MachineRepresentation::kSimd128) {
151 Node* base = node->InputAt(0);
152 Node* index = node->InputAt(1);
153 Node* indices[kMaxLanes];
154 GetIndexNodes(index, indices);
155 Node* rep_nodes[kMaxLanes];
156 rep_nodes[0] = node;
157 NodeProperties::ChangeOp(rep_nodes[0], load_op);
158 if (node->InputCount() > 2) {
159 DCHECK(node->InputCount() > 3);
160 Node* effect_input = node->InputAt(2);
161 Node* control_input = node->InputAt(3);
162 rep_nodes[3] = graph()->NewNode(load_op, base, indices[3], effect_input,
163 control_input);
164 rep_nodes[2] = graph()->NewNode(load_op, base, indices[2], rep_nodes[3],
165 control_input);
166 rep_nodes[1] = graph()->NewNode(load_op, base, indices[1], rep_nodes[2],
167 control_input);
168 rep_nodes[0]->ReplaceInput(2, rep_nodes[1]);
169 } else {
170 for (size_t i = 1; i < kMaxLanes; ++i) {
171 rep_nodes[i] = graph()->NewNode(load_op, base, indices[i]);
172 }
173 }
174 ReplaceNode(node, rep_nodes);
175 } else {
176 DefaultLowering(node);
177 }
178 }
179
180 void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node,
181 const Operator* store_op,
182 SimdType rep_type) {
183 if (rep == MachineRepresentation::kSimd128) {
184 Node* base = node->InputAt(0);
185 Node* index = node->InputAt(1);
186 Node* indices[kMaxLanes];
187 GetIndexNodes(index, indices);
188 DCHECK(node->InputCount() > 2);
189 Node* value = node->InputAt(2);
190 DCHECK(HasReplacement(1, value));
191 Node* rep_nodes[kMaxLanes];
192 rep_nodes[0] = node;
193 Node** rep_inputs = GetReplacementsWithType(value, rep_type);
194 rep_nodes[0]->ReplaceInput(2, rep_inputs[0]);
195 NodeProperties::ChangeOp(node, store_op);
196 if (node->InputCount() > 3) {
197 DCHECK(node->InputCount() > 4);
198 Node* effect_input = node->InputAt(3);
199 Node* control_input = node->InputAt(4);
200 rep_nodes[3] = graph()->NewNode(store_op, base, indices[3], rep_inputs[3],
201 effect_input, control_input);
202 rep_nodes[2] = graph()->NewNode(store_op, base, indices[2], rep_inputs[2],
203 rep_nodes[3], control_input);
204 rep_nodes[1] = graph()->NewNode(store_op, base, indices[1], rep_inputs[1],
205 rep_nodes[2], control_input);
206 rep_nodes[0]->ReplaceInput(3, rep_nodes[1]);
207
208 } else {
209 for (size_t i = 1; i < kMaxLanes; ++i) {
210 rep_nodes[i] =
211 graph()->NewNode(store_op, base, indices[i], rep_inputs[i]);
212 }
213 }
214
215 ReplaceNode(node, rep_nodes);
216 } else {
217 DefaultLowering(node);
218 }
219 }
220
221 void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType rep_type,
222 const Operator* op) {
223 DCHECK(node->InputCount() == 2);
224 Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type);
225 Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type);
226 Node* rep_node[kMaxLanes];
227 for (int i = 0; i < kMaxLanes; ++i) {
228 rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]);
229 }
230 ReplaceNode(node, rep_node);
231 }
232
134 void SimdScalarLowering::LowerNode(Node* node) { 233 void SimdScalarLowering::LowerNode(Node* node) {
135 SimdType rep_type = ReplacementType(node); 234 SimdType rep_type = ReplacementType(node);
136 switch (node->opcode()) { 235 switch (node->opcode()) {
137 case IrOpcode::kStart: { 236 case IrOpcode::kStart: {
138 int parameter_count = GetParameterCountAfterLowering(); 237 int parameter_count = GetParameterCountAfterLowering();
139 // Only exchange the node if the parameter count actually changed. 238 // Only exchange the node if the parameter count actually changed.
140 if (parameter_count != static_cast<int>(signature()->parameter_count())) { 239 if (parameter_count != static_cast<int>(signature()->parameter_count())) {
141 int delta = 240 int delta =
142 parameter_count - static_cast<int>(signature()->parameter_count()); 241 parameter_count - static_cast<int>(signature()->parameter_count());
143 int new_output_count = node->op()->ValueOutputCount() + delta; 242 int new_output_count = node->op()->ValueOutputCount() + delta;
144 NodeProperties::ChangeOp(node, common()->Start(new_output_count)); 243 NodeProperties::ChangeOp(node, common()->Start(new_output_count));
145 } 244 }
146 break; 245 break;
147 } 246 }
148 case IrOpcode::kParameter: { 247 case IrOpcode::kParameter: {
149 DCHECK(node->InputCount() == 1); 248 DCHECK(node->InputCount() == 1);
150 // Only exchange the node if the parameter count actually changed. We do 249 // Only exchange the node if the parameter count actually changed. We do
151 // not even have to do the default lowering because the the start node, 250 // not even have to do the default lowering because the the start node,
152 // the only input of a parameter node, only changes if the parameter count 251 // the only input of a parameter node, only changes if the parameter count
153 // changes. 252 // changes.
154 if (GetParameterCountAfterLowering() != 253 if (GetParameterCountAfterLowering() !=
155 static_cast<int>(signature()->parameter_count())) { 254 static_cast<int>(signature()->parameter_count())) {
156 int old_index = ParameterIndexOf(node->op()); 255 int old_index = ParameterIndexOf(node->op());
157 int new_index = GetParameterIndexAfterLowering(signature(), old_index); 256 int new_index = GetParameterIndexAfterLowering(signature(), old_index);
158 if (old_index == new_index) { 257 if (old_index == new_index) {
159 NodeProperties::ChangeOp(node, common()->Parameter(new_index)); 258 NodeProperties::ChangeOp(node, common()->Parameter(new_index));
160 259
161 Node* new_node[kMaxLanes]; 260 Node* new_node[kMaxLanes];
162 for (int i = 0; i < kMaxLanes; i++) { 261 for (int i = 0; i < kMaxLanes; ++i) {
163 new_node[i] = nullptr; 262 new_node[i] = nullptr;
164 } 263 }
165 new_node[0] = node; 264 new_node[0] = node;
166 if (signature()->GetParam(old_index) == 265 if (signature()->GetParam(old_index) ==
167 MachineRepresentation::kSimd128) { 266 MachineRepresentation::kSimd128) {
168 for (int i = 1; i < kMaxLanes; i++) { 267 for (int i = 1; i < kMaxLanes; ++i) {
169 new_node[i] = graph()->NewNode(common()->Parameter(new_index + i), 268 new_node[i] = graph()->NewNode(common()->Parameter(new_index + i),
170 graph()->start()); 269 graph()->start());
171 } 270 }
172 } 271 }
173 ReplaceNode(node, new_node); 272 ReplaceNode(node, new_node);
174 } 273 }
175 } 274 }
176 break; 275 break;
177 } 276 }
277 case IrOpcode::kLoad: {
278 MachineRepresentation rep =
279 LoadRepresentationOf(node->op()).representation();
280 const Operator* load_op;
281 if (rep_type == SimdType::kInt32) {
282 load_op = machine()->Load(MachineType::Int32());
283 } else if (rep_type == SimdType::kFloat32) {
284 load_op = machine()->Load(MachineType::Float32());
285 }
286 LowerLoadOp(rep, node, load_op);
287 break;
288 }
289 case IrOpcode::kUnalignedLoad: {
290 MachineRepresentation rep =
291 UnalignedLoadRepresentationOf(node->op()).representation();
292 const Operator* load_op;
293 if (rep_type == SimdType::kInt32) {
294 load_op = machine()->UnalignedLoad(MachineType::Int32());
295 } else if (rep_type == SimdType::kFloat32) {
296 load_op = machine()->UnalignedLoad(MachineType::Float32());
297 }
298 LowerLoadOp(rep, node, load_op);
299 break;
300 }
301 case IrOpcode::kStore: {
302 MachineRepresentation rep =
303 StoreRepresentationOf(node->op()).representation();
304 WriteBarrierKind write_barrier_kind =
305 StoreRepresentationOf(node->op()).write_barrier_kind();
306 const Operator* store_op;
307 if (rep_type == SimdType::kInt32) {
308 store_op = machine()->Store(StoreRepresentation(
309 MachineRepresentation::kWord32, write_barrier_kind));
310 } else {
311 store_op = machine()->Store(StoreRepresentation(
312 MachineRepresentation::kFloat32, write_barrier_kind));
313 }
314 LowerStoreOp(rep, node, store_op, rep_type);
315 break;
316 }
317 case IrOpcode::kUnalignedStore: {
318 MachineRepresentation rep = UnalignedStoreRepresentationOf(node->op());
319 const Operator* store_op;
320 if (rep_type == SimdType::kInt32) {
321 store_op = machine()->UnalignedStore(MachineRepresentation::kWord32);
322 } else {
323 store_op = machine()->UnalignedStore(MachineRepresentation::kFloat32);
324 }
325 LowerStoreOp(rep, node, store_op, rep_type);
326 break;
327 }
178 case IrOpcode::kReturn: { 328 case IrOpcode::kReturn: {
179 DefaultLowering(node); 329 DefaultLowering(node);
180 int new_return_count = GetReturnCountAfterLowering(signature()); 330 int new_return_count = GetReturnCountAfterLowering(signature());
181 if (static_cast<int>(signature()->return_count()) != new_return_count) { 331 if (static_cast<int>(signature()->return_count()) != new_return_count) {
182 NodeProperties::ChangeOp(node, common()->Return(new_return_count)); 332 NodeProperties::ChangeOp(node, common()->Return(new_return_count));
183 } 333 }
184 break; 334 break;
185 } 335 }
186 case IrOpcode::kCall: { 336 case IrOpcode::kCall: {
187 // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor. 337 // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor.
188 CallDescriptor* descriptor = 338 CallDescriptor* descriptor =
189 const_cast<CallDescriptor*>(CallDescriptorOf(node->op())); 339 const_cast<CallDescriptor*>(CallDescriptorOf(node->op()));
190 if (DefaultLowering(node) || 340 if (DefaultLowering(node) ||
191 (descriptor->ReturnCount() == 1 && 341 (descriptor->ReturnCount() == 1 &&
192 descriptor->GetReturnType(0) == MachineType::Simd128())) { 342 descriptor->GetReturnType(0) == MachineType::Simd128())) {
193 // We have to adjust the call descriptor. 343 // We have to adjust the call descriptor.
194 const Operator* op = 344 const Operator* op =
195 common()->Call(wasm::ModuleEnv::GetI32WasmCallDescriptorForSimd( 345 common()->Call(wasm::ModuleEnv::GetI32WasmCallDescriptorForSimd(
196 zone(), descriptor)); 346 zone(), descriptor));
197 NodeProperties::ChangeOp(node, op); 347 NodeProperties::ChangeOp(node, op);
198 } 348 }
199 if (descriptor->ReturnCount() == 1 && 349 if (descriptor->ReturnCount() == 1 &&
200 descriptor->GetReturnType(0) == MachineType::Simd128()) { 350 descriptor->GetReturnType(0) == MachineType::Simd128()) {
201 // We access the additional return values through projections. 351 // We access the additional return values through projections.
202 Node* rep_node[kMaxLanes]; 352 Node* rep_node[kMaxLanes];
203 for (int i = 0; i < kMaxLanes; i++) { 353 for (int i = 0; i < kMaxLanes; ++i) {
204 rep_node[i] = 354 rep_node[i] =
205 graph()->NewNode(common()->Projection(i), node, graph()->start()); 355 graph()->NewNode(common()->Projection(i), node, graph()->start());
206 } 356 }
207 ReplaceNode(node, rep_node); 357 ReplaceNode(node, rep_node);
208 } 358 }
209 break; 359 break;
210 } 360 }
211 case IrOpcode::kPhi: { 361 case IrOpcode::kPhi: {
212 MachineRepresentation rep = PhiRepresentationOf(node->op()); 362 MachineRepresentation rep = PhiRepresentationOf(node->op());
213 if (rep == MachineRepresentation::kSimd128) { 363 if (rep == MachineRepresentation::kSimd128) {
214 // The replacement nodes have already been created, we only have to 364 // The replacement nodes have already been created, we only have to
215 // replace placeholder nodes. 365 // replace placeholder nodes.
216 Node** rep_node = GetReplacements(node); 366 Node** rep_node = GetReplacements(node);
217 for (int i = 0; i < node->op()->ValueInputCount(); i++) { 367 for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
218 Node** rep_input = 368 Node** rep_input =
219 GetReplacementsWithType(node->InputAt(i), rep_type); 369 GetReplacementsWithType(node->InputAt(i), rep_type);
220 for (int j = 0; j < kMaxLanes; j++) { 370 for (int j = 0; j < kMaxLanes; j++) {
221 rep_node[j]->ReplaceInput(i, rep_input[j]); 371 rep_node[j]->ReplaceInput(i, rep_input[j]);
222 } 372 }
223 } 373 }
224 } else { 374 } else {
225 DefaultLowering(node); 375 DefaultLowering(node);
226 } 376 }
227 break; 377 break;
228 } 378 }
229
230 case IrOpcode::kInt32x4Add: { 379 case IrOpcode::kInt32x4Add: {
231 DCHECK(node->InputCount() == 2); 380 LowerBinaryOp(node, rep_type, machine()->Int32Add());
232 Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type); 381 break;
233 Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type); 382 }
383 case IrOpcode::kFloat32x4Add: {
384 LowerBinaryOp(node, rep_type, machine()->Float32Add());
385 break;
386 }
387 case IrOpcode::kCreateInt32x4:
388 case IrOpcode::kCreateFloat32x4: {
234 Node* rep_node[kMaxLanes]; 389 Node* rep_node[kMaxLanes];
235 for (int i = 0; i < kMaxLanes; i++) { 390 for (int i = 0; i < kMaxLanes; ++i) {
236 rep_node[i] = 391 if (HasReplacement(0, node->InputAt(i))) {
237 graph()->NewNode(machine()->Int32Add(), rep_left[i], rep_right[i]); 392 rep_node[i] = GetReplacements(node->InputAt(i))[0];
393 } else {
394 rep_node[i] = node->InputAt(i);
395 }
238 } 396 }
239 ReplaceNode(node, rep_node); 397 ReplaceNode(node, rep_node);
240 break; 398 break;
241 } 399 }
242 400 case IrOpcode::kInt32x4ExtractLane:
243 case IrOpcode::kCreateInt32x4: { 401 case IrOpcode::kFloat32x4ExtractLane: {
244 Node* rep_node[kMaxLanes];
245 for (int i = 0; i < kMaxLanes; i++) {
246 DCHECK(!HasReplacement(1, node->InputAt(i)));
247 rep_node[i] = node->InputAt(i);
248 }
249 ReplaceNode(node, rep_node);
250 break;
251 }
252
253 case IrOpcode::kInt32x4ExtractLane: {
254 Node* laneNode = node->InputAt(1); 402 Node* laneNode = node->InputAt(1);
255 DCHECK_EQ(laneNode->opcode(), IrOpcode::kInt32Constant); 403 DCHECK_EQ(laneNode->opcode(), IrOpcode::kInt32Constant);
256 int32_t lane = OpParameter<int32_t>(laneNode); 404 int32_t lane = OpParameter<int32_t>(laneNode);
257 Node* rep_node[kMaxLanes] = { 405 Node* rep_node[kMaxLanes] = {
258 GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr, 406 GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr,
259 nullptr, nullptr}; 407 nullptr, nullptr};
260 ReplaceNode(node, rep_node); 408 ReplaceNode(node, rep_node);
261 break; 409 break;
262 } 410 }
263 411 case IrOpcode::kInt32x4ReplaceLane:
264 case IrOpcode::kFloat32x4Add: { 412 case IrOpcode::kFloat32x4ReplaceLane: {
265 DCHECK(node->InputCount() == 2); 413 DCHECK_EQ(3, node->InputCount());
266 Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type); 414 Node* laneNode = node->InputAt(1);
267 Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type); 415 Node* repNode = node->InputAt(2);
268 Node* rep_node[kMaxLanes]; 416 DCHECK_EQ(laneNode->opcode(), IrOpcode::kInt32Constant);
269 for (int i = 0; i < kMaxLanes; i++) { 417 int32_t lane = OpParameter<int32_t>(laneNode);
270 rep_node[i] = graph()->NewNode(machine()->Float32Add(), rep_left[i], 418 DCHECK(lane >= 0 && lane <= 3);
271 rep_right[i]); 419 Node** rep_node = GetReplacementsWithType(node->InputAt(0), rep_type);
420 if (HasReplacement(0, repNode)) {
421 rep_node[lane] = GetReplacements(repNode)[0];
422 } else {
423 rep_node[lane] = repNode;
272 } 424 }
273 ReplaceNode(node, rep_node); 425 ReplaceNode(node, rep_node);
274 break; 426 break;
275 } 427 }
276
277 case IrOpcode::kCreateFloat32x4: {
278 Node* rep_node[kMaxLanes];
279 for (int i = 0; i < kMaxLanes; i++) {
280 DCHECK(!HasReplacement(1, node->InputAt(i)));
281 rep_node[i] = node->InputAt(i);
282 }
283 ReplaceNode(node, rep_node);
284 break;
285 }
286
287 case IrOpcode::kFloat32x4ExtractLane: {
288 Node* laneNode = node->InputAt(1);
289 DCHECK_EQ(laneNode->opcode(), IrOpcode::kInt32Constant);
290 int32_t lane = OpParameter<int32_t>(laneNode);
291 Node* rep_node[kMaxLanes] = {
292 GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr,
293 nullptr, nullptr};
294 ReplaceNode(node, rep_node);
295 break;
296 }
297
298 default: { DefaultLowering(node); } 428 default: { DefaultLowering(node); }
299 } 429 }
300 } 430 }
301 431
302 bool SimdScalarLowering::DefaultLowering(Node* node) { 432 bool SimdScalarLowering::DefaultLowering(Node* node) {
303 bool something_changed = false; 433 bool something_changed = false;
304 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) { 434 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
305 Node* input = node->InputAt(i); 435 Node* input = node->InputAt(i);
306 if (HasReplacement(0, input)) { 436 if (HasReplacement(0, input)) {
307 something_changed = true; 437 something_changed = true;
308 node->ReplaceInput(i, GetReplacements(input)[0]); 438 node->ReplaceInput(i, GetReplacements(input)[0]);
309 } 439 }
310 if (HasReplacement(1, input)) { 440 if (HasReplacement(1, input)) {
311 something_changed = true; 441 something_changed = true;
312 for (int j = 1; j < kMaxLanes; j++) { 442 for (int j = 1; j < kMaxLanes; j++) {
313 node->InsertInput(zone(), i + j, GetReplacements(input)[j]); 443 node->InsertInput(zone(), i + j, GetReplacements(input)[j]);
314 } 444 }
315 } 445 }
316 } 446 }
317 return something_changed; 447 return something_changed;
318 } 448 }
319 449
320 void SimdScalarLowering::ReplaceNode(Node* old, Node** new_node) { 450 void SimdScalarLowering::ReplaceNode(Node* old, Node** new_node) {
321 // if new_low == nullptr, then also new_high == nullptr. 451 // if new_low == nullptr, then also new_high == nullptr.
322 DCHECK(new_node[0] != nullptr || 452 DCHECK(new_node[0] != nullptr ||
323 (new_node[1] == nullptr && new_node[2] == nullptr && 453 (new_node[1] == nullptr && new_node[2] == nullptr &&
324 new_node[3] == nullptr)); 454 new_node[3] == nullptr));
325 for (int i = 0; i < kMaxLanes; i++) { 455 for (int i = 0; i < kMaxLanes; ++i) {
326 replacements_[old->id()].node[i] = new_node[i]; 456 replacements_[old->id()].node[i] = new_node[i];
327 } 457 }
328 } 458 }
329 459
330 bool SimdScalarLowering::HasReplacement(size_t index, Node* node) { 460 bool SimdScalarLowering::HasReplacement(size_t index, Node* node) {
331 return replacements_[node->id()].node[index] != nullptr; 461 return replacements_[node->id()].node[index] != nullptr;
332 } 462 }
333 463
334 SimdScalarLowering::SimdType SimdScalarLowering::ReplacementType(Node* node) { 464 SimdScalarLowering::SimdType SimdScalarLowering::ReplacementType(Node* node) {
335 return replacements_[node->id()].type; 465 return replacements_[node->id()].type;
336 } 466 }
337 467
338 Node** SimdScalarLowering::GetReplacements(Node* node) { 468 Node** SimdScalarLowering::GetReplacements(Node* node) {
339 Node** result = replacements_[node->id()].node; 469 Node** result = replacements_[node->id()].node;
340 DCHECK(result); 470 DCHECK(result);
341 return result; 471 return result;
342 } 472 }
343 473
344 Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) { 474 Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) {
345 Node** replacements = GetReplacements(node); 475 Node** replacements = GetReplacements(node);
346 if (ReplacementType(node) == type) { 476 if (ReplacementType(node) == type) {
347 return GetReplacements(node); 477 return GetReplacements(node);
348 } 478 }
349 Node** result = zone()->NewArray<Node*>(kMaxLanes); 479 Node** result = zone()->NewArray<Node*>(kMaxLanes);
350 if (ReplacementType(node) == SimdType::kInt32 && type == SimdType::kFloat32) { 480 if (ReplacementType(node) == SimdType::kInt32 && type == SimdType::kFloat32) {
351 for (int i = 0; i < kMaxLanes; i++) { 481 for (int i = 0; i < kMaxLanes; ++i) {
352 if (replacements[i] != nullptr) { 482 if (replacements[i] != nullptr) {
353 result[i] = graph()->NewNode(machine()->BitcastInt32ToFloat32(), 483 result[i] = graph()->NewNode(machine()->BitcastInt32ToFloat32(),
354 replacements[i]); 484 replacements[i]);
355 } else { 485 } else {
356 result[i] = nullptr; 486 result[i] = nullptr;
357 } 487 }
358 } 488 }
359 } else { 489 } else {
360 for (int i = 0; i < kMaxLanes; i++) { 490 for (int i = 0; i < kMaxLanes; ++i) {
361 if (replacements[i] != nullptr) { 491 if (replacements[i] != nullptr) {
362 result[i] = graph()->NewNode(machine()->BitcastFloat32ToInt32(), 492 result[i] = graph()->NewNode(machine()->BitcastFloat32ToInt32(),
363 replacements[i]); 493 replacements[i]);
364 } else { 494 } else {
365 result[i] = nullptr; 495 result[i] = nullptr;
366 } 496 }
367 } 497 }
368 } 498 }
369 return result; 499 return result;
370 } 500 }
371 501
372 void SimdScalarLowering::PreparePhiReplacement(Node* phi) { 502 void SimdScalarLowering::PreparePhiReplacement(Node* phi) {
373 MachineRepresentation rep = PhiRepresentationOf(phi->op()); 503 MachineRepresentation rep = PhiRepresentationOf(phi->op());
374 if (rep == MachineRepresentation::kSimd128) { 504 if (rep == MachineRepresentation::kSimd128) {
375 // We have to create the replacements for a phi node before we actually 505 // We have to create the replacements for a phi node before we actually
376 // lower the phi to break potential cycles in the graph. The replacements of 506 // lower the phi to break potential cycles in the graph. The replacements of
377 // input nodes do not exist yet, so we use a placeholder node to pass the 507 // input nodes do not exist yet, so we use a placeholder node to pass the
378 // graph verifier. 508 // graph verifier.
379 int value_count = phi->op()->ValueInputCount(); 509 int value_count = phi->op()->ValueInputCount();
380 SimdType type = ReplacementType(phi); 510 SimdType type = ReplacementType(phi);
381 Node** inputs_rep[kMaxLanes]; 511 Node** inputs_rep[kMaxLanes];
382 for (int i = 0; i < kMaxLanes; i++) { 512 for (int i = 0; i < kMaxLanes; ++i) {
383 inputs_rep[i] = zone()->NewArray<Node*>(value_count + 1); 513 inputs_rep[i] = zone()->NewArray<Node*>(value_count + 1);
384 inputs_rep[i][value_count] = NodeProperties::GetControlInput(phi, 0); 514 inputs_rep[i][value_count] = NodeProperties::GetControlInput(phi, 0);
385 } 515 }
386 for (int i = 0; i < value_count; i++) { 516 for (int i = 0; i < value_count; ++i) {
387 for (int j = 0; j < kMaxLanes; j++) { 517 for (int j = 0; j < kMaxLanes; j++) {
388 inputs_rep[j][i] = placeholder_; 518 inputs_rep[j][i] = placeholder_;
389 } 519 }
390 } 520 }
391 Node* rep_nodes[kMaxLanes]; 521 Node* rep_nodes[kMaxLanes];
392 for (int i = 0; i < kMaxLanes; i++) { 522 for (int i = 0; i < kMaxLanes; ++i) {
393 if (type == SimdType::kInt32) { 523 if (type == SimdType::kInt32) {
394 rep_nodes[i] = graph()->NewNode( 524 rep_nodes[i] = graph()->NewNode(
395 common()->Phi(MachineRepresentation::kWord32, value_count), 525 common()->Phi(MachineRepresentation::kWord32, value_count),
396 value_count + 1, inputs_rep[i], false); 526 value_count + 1, inputs_rep[i], false);
397 } else if (type == SimdType::kFloat32) { 527 } else if (type == SimdType::kFloat32) {
398 rep_nodes[i] = graph()->NewNode( 528 rep_nodes[i] = graph()->NewNode(
399 common()->Phi(MachineRepresentation::kFloat32, value_count), 529 common()->Phi(MachineRepresentation::kFloat32, value_count),
400 value_count + 1, inputs_rep[i], false); 530 value_count + 1, inputs_rep[i], false);
401 } else { 531 } else {
402 UNREACHABLE(); 532 UNREACHABLE();
403 } 533 }
404 } 534 }
405 ReplaceNode(phi, rep_nodes); 535 ReplaceNode(phi, rep_nodes);
406 } 536 }
407 } 537 }
408 } // namespace compiler 538 } // namespace compiler
409 } // namespace internal 539 } // namespace internal
410 } // namespace v8 540 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/simd-scalar-lowering.h ('k') | src/compiler/wasm-compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698