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

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: Created 4 years, 1 month 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
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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 Signature<MachineRepresentation>* signature) { 124 Signature<MachineRepresentation>* signature) {
125 int result = static_cast<int>(signature->return_count()); 125 int result = static_cast<int>(signature->return_count());
126 for (int i = 0; i < static_cast<int>(signature->return_count()); i++) { 126 for (int i = 0; i < static_cast<int>(signature->return_count()); i++) {
127 if (signature->GetReturn(i) == MachineRepresentation::kSimd128) { 127 if (signature->GetReturn(i) == MachineRepresentation::kSimd128) {
128 result += 3; 128 result += 3;
129 } 129 }
130 } 130 }
131 return result; 131 return result;
132 } 132 }
133 133
134 void SimdScalarLowering::GetIndexNodes(Node* index, Node** new_indices) {
135 new_indices[0] = index;
136 for (size_t i = 1; i < kMaxLanes; i++) {
Mircea Trofin 2016/11/15 16:21:27 ++i
aseemgarg 2016/11/19 01:56:54 Done.
137 new_indices[i] = graph()->NewNode(
138 machine()->Int32Add(), index,
139 graph()->NewNode(common()->Int32Constant(static_cast<int>(i) * 4)));
titzer 2016/11/15 09:21:17 Should this be 16 / kMaxLanes for clarity?
Mircea Trofin 2016/11/15 16:21:27 Consider using the relevant constant for "4" (or "
aseemgarg 2016/11/19 01:56:54 Done. But I don't get how it is clearer? 4 is just
titzer 2016/11/22 12:01:52 I meant, please introduce a constant that defines
aseemgarg 2016/11/23 23:07:56 Done.
140 }
141 }
142
134 void SimdScalarLowering::LowerNode(Node* node) { 143 void SimdScalarLowering::LowerNode(Node* node) {
135 SimdType rep_type = ReplacementType(node); 144 SimdType rep_type = ReplacementType(node);
136 switch (node->opcode()) { 145 switch (node->opcode()) {
137 case IrOpcode::kStart: { 146 case IrOpcode::kStart: {
138 int parameter_count = GetParameterCountAfterLowering(); 147 int parameter_count = GetParameterCountAfterLowering();
139 // Only exchange the node if the parameter count actually changed. 148 // Only exchange the node if the parameter count actually changed.
140 if (parameter_count != static_cast<int>(signature()->parameter_count())) { 149 if (parameter_count != static_cast<int>(signature()->parameter_count())) {
141 int delta = 150 int delta =
142 parameter_count - static_cast<int>(signature()->parameter_count()); 151 parameter_count - static_cast<int>(signature()->parameter_count());
143 int new_output_count = node->op()->ValueOutputCount() + delta; 152 int new_output_count = node->op()->ValueOutputCount() + delta;
(...skipping 24 matching lines...) Expand all
168 for (int i = 1; i < kMaxLanes; i++) { 177 for (int i = 1; i < kMaxLanes; i++) {
169 new_node[i] = graph()->NewNode(common()->Parameter(new_index + i), 178 new_node[i] = graph()->NewNode(common()->Parameter(new_index + i),
170 graph()->start()); 179 graph()->start());
171 } 180 }
172 } 181 }
173 ReplaceNode(node, new_node); 182 ReplaceNode(node, new_node);
174 } 183 }
175 } 184 }
176 break; 185 break;
177 } 186 }
187 case IrOpcode::kLoad:
188 case IrOpcode::kUnalignedLoad: {
189 MachineRepresentation rep;
190 if (node->opcode() == IrOpcode::kLoad) {
191 rep = LoadRepresentationOf(node->op()).representation();
192 } else {
193 DCHECK(node->opcode() == IrOpcode::kUnalignedLoad);
194 rep = UnalignedLoadRepresentationOf(node->op()).representation();
195 }
196
197 if (rep == MachineRepresentation::kSimd128) {
198 Node* base = node->InputAt(0);
199 Node* index = node->InputAt(1);
200 Node* indices[kMaxLanes];
201 GetIndexNodes(index, indices);
202 const Operator* load_op;
203 if (node->opcode() == IrOpcode::kLoad && rep_type == SimdType::kInt32) {
titzer 2016/11/15 09:21:17 Can you factor out a subroutines GetLoadOp() and G
aseemgarg 2016/11/19 01:56:54 Done.
204 load_op = machine()->Load(MachineType::Int32());
205 } else if (node->opcode() == IrOpcode::kLoad &&
206 rep_type == SimdType::kFloat32) {
207 load_op = machine()->Load(MachineType::Float32());
208 } else if (node->opcode() == IrOpcode::kUnalignedLoad &&
209 rep_type == SimdType::kInt32) {
210 load_op = machine()->UnalignedLoad(MachineType::Int32());
211 } else if (node->opcode() == IrOpcode::kUnalignedLoad &&
212 rep_type == SimdType::kFloat32) {
213 load_op = machine()->UnalignedLoad(MachineType::Float32());
214 }
215
216 Node* rep_nodes[kMaxLanes];
217 rep_nodes[0] = node;
218 NodeProperties::ChangeOp(rep_nodes[0], load_op);
219 if (node->InputCount() > 2) {
220 Node* effect_high = node->InputAt(2);
221 Node* control_high = node->InputAt(3);
Mircea Trofin 2016/11/15 16:21:27 aren't inputs 0 indexed? in that case, wouldn't In
aseemgarg 2016/11/19 01:56:54 The check for greater than 2 just tells that there
222 rep_nodes[3] = graph()->NewNode(load_op, base, indices[3],
Mircea Trofin 2016/11/15 16:21:27 This all hinges on kMaxLanes > 3 (a DCHECK?)
aseemgarg 2016/11/19 01:56:54 Done.
223 effect_high, control_high);
224 rep_nodes[2] = graph()->NewNode(load_op, base, indices[2],
225 rep_nodes[3], control_high);
226 rep_nodes[1] = graph()->NewNode(load_op, base, indices[1],
227 rep_nodes[2], control_high);
228 rep_nodes[0]->ReplaceInput(2, rep_nodes[1]);
229 } else {
230 for (size_t i = 1; i < kMaxLanes; i++) {
Mircea Trofin 2016/11/15 16:21:27 ++i
aseemgarg 2016/11/19 01:56:54 Done.
231 rep_nodes[i] = graph()->NewNode(load_op, base, indices[i]);
232 }
233 }
234 ReplaceNode(node, rep_nodes);
235 } else {
236 DefaultLowering(node);
237 }
238 break;
239 }
240 case IrOpcode::kStore:
241 case IrOpcode::kUnalignedStore: {
242 MachineRepresentation rep;
243 if (node->opcode() == IrOpcode::kStore) {
244 rep = StoreRepresentationOf(node->op()).representation();
245 } else {
246 DCHECK(node->opcode() == IrOpcode::kUnalignedStore);
247 rep = UnalignedStoreRepresentationOf(node->op());
248 }
249
250 if (rep == MachineRepresentation::kSimd128) {
251 Node* base = node->InputAt(0);
252 Node* index = node->InputAt(1);
253 Node* indices[4];
Mircea Trofin 2016/11/15 16:21:26 what's "4"?
aseemgarg 2016/11/19 01:56:54 changed to kMaxLanes
254 GetIndexNodes(index, indices);
255 Node* value = node->InputAt(2);
Mircea Trofin 2016/11/15 16:21:27 DCHECK node's input count
aseemgarg 2016/11/19 01:56:54 Done.
256 DCHECK(HasReplacement(1, value));
257 const Operator* store_op;
258 if (node->opcode() == IrOpcode::kStore) {
259 WriteBarrierKind write_barrier_kind =
260 StoreRepresentationOf(node->op()).write_barrier_kind();
261 if (rep_type == SimdType::kInt32) {
262 store_op = machine()->Store(StoreRepresentation(
263 MachineRepresentation::kWord32, write_barrier_kind));
264 } else {
265 store_op = machine()->Store(StoreRepresentation(
266 MachineRepresentation::kFloat32, write_barrier_kind));
267 }
268 } else {
269 if (rep_type == SimdType::kInt32) {
270 store_op =
271 machine()->UnalignedStore(MachineRepresentation::kWord32);
272 } else {
273 store_op =
274 machine()->UnalignedStore(MachineRepresentation::kFloat32);
275 }
276 }
277
278 Node* rep_nodes[kMaxLanes];
279 rep_nodes[0] = node;
280 Node** rep_inputs = GetReplacementsWithType(value, rep_type);
281 rep_nodes[0]->ReplaceInput(2, rep_inputs[0]);
282 NodeProperties::ChangeOp(node, store_op);
283 if (node->InputCount() > 3) {
284 Node* effect_high = node->InputAt(3);
Mircea Trofin 2016/11/15 16:21:27 same question about input being 0 indexed
aseemgarg 2016/11/19 01:56:54 see above. Added Dcheck
titzer 2016/11/22 12:01:52 Can you just name this effect_input and control_in
aseemgarg 2016/11/23 23:07:56 Done.
285 Node* control_high = node->InputAt(4);
286 rep_nodes[3] =
287 graph()->NewNode(store_op, base, indices[3], rep_inputs[3],
288 effect_high, control_high);
289 rep_nodes[2] =
290 graph()->NewNode(store_op, base, indices[2], rep_inputs[2],
291 rep_nodes[3], control_high);
292 rep_nodes[1] =
293 graph()->NewNode(store_op, base, indices[1], rep_inputs[1],
294 rep_nodes[2], control_high);
295 rep_nodes[0]->ReplaceInput(3, rep_nodes[1]);
titzer 2016/11/15 09:21:17 I think the effect chain is messed up here. I thin
aseemgarg 2016/11/19 01:56:54 I am not quite sure I understand how effect nodes
titzer 2016/11/22 12:01:52 Let me clarify a bit here. There isn't really an "
aseemgarg 2016/11/23 23:07:56 Didn't change anything. Leaving as is On 2016/11/
296
297 } else {
298 for (size_t i = 1; i < kMaxLanes; i++) {
299 rep_nodes[i] =
300 graph()->NewNode(store_op, base, indices[i], rep_inputs[i]);
301 }
302 }
303
304 ReplaceNode(node, rep_nodes);
305 } else {
306 DefaultLowering(node);
307 }
308 break;
309 }
178 case IrOpcode::kReturn: { 310 case IrOpcode::kReturn: {
179 DefaultLowering(node); 311 DefaultLowering(node);
180 int new_return_count = GetReturnCountAfterLowering(signature()); 312 int new_return_count = GetReturnCountAfterLowering(signature());
181 if (static_cast<int>(signature()->return_count()) != new_return_count) { 313 if (static_cast<int>(signature()->return_count()) != new_return_count) {
182 NodeProperties::ChangeOp(node, common()->Return(new_return_count)); 314 NodeProperties::ChangeOp(node, common()->Return(new_return_count));
183 } 315 }
184 break; 316 break;
185 } 317 }
186 case IrOpcode::kCall: { 318 case IrOpcode::kCall: {
187 // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor. 319 // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 GetReplacementsWithType(node->InputAt(i), rep_type); 351 GetReplacementsWithType(node->InputAt(i), rep_type);
220 for (int j = 0; j < kMaxLanes; j++) { 352 for (int j = 0; j < kMaxLanes; j++) {
221 rep_node[j]->ReplaceInput(i, rep_input[j]); 353 rep_node[j]->ReplaceInput(i, rep_input[j]);
222 } 354 }
223 } 355 }
224 } else { 356 } else {
225 DefaultLowering(node); 357 DefaultLowering(node);
226 } 358 }
227 break; 359 break;
228 } 360 }
229 361 #define BINOP_CASE(opcode, replacementOp) \
titzer 2016/11/15 09:21:17 Can you make this into a call to a subroutine? AFA
aseemgarg 2016/11/19 01:56:54 Done.
230 case IrOpcode::kInt32x4Add: { 362 case IrOpcode::opcode: { \
231 DCHECK(node->InputCount() == 2); 363 DCHECK(node->InputCount() == 2); \
232 Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type); 364 Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type); \
233 Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type); 365 Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type); \
366 Node* rep_node[kMaxLanes]; \
367 for (int i = 0; i < kMaxLanes; i++) { \
Mircea Trofin 2016/11/15 16:21:27 ++i
aseemgarg 2016/11/19 01:56:54 Done.
368 rep_node[i] = graph()->NewNode(machine()->replacementOp(), rep_left[i], \
369 rep_right[i]); \
370 } \
371 ReplaceNode(node, rep_node); \
372 break; \
373 }
374 BINOP_CASE(kInt32x4Add, Int32Add)
375 BINOP_CASE(kFloat32x4Add, Float32Add)
376 #undef BINOP
377 case IrOpcode::kCreateInt32x4:
378 case IrOpcode::kCreateFloat32x4: {
234 Node* rep_node[kMaxLanes]; 379 Node* rep_node[kMaxLanes];
235 for (int i = 0; i < kMaxLanes; i++) { 380 for (int i = 0; i < kMaxLanes; i++) {
Mircea Trofin 2016/11/15 16:21:27 ++i
aseemgarg 2016/11/19 01:56:54 Done.
236 rep_node[i] = 381 if (HasReplacement(0, node->InputAt(i))) {
237 graph()->NewNode(machine()->Int32Add(), rep_left[i], rep_right[i]); 382 rep_node[i] = GetReplacements(node->InputAt(i))[0];
383 } else {
384 rep_node[i] = node->InputAt(i);
385 }
238 } 386 }
239 ReplaceNode(node, rep_node); 387 ReplaceNode(node, rep_node);
240 break; 388 break;
241 } 389 }
242 390 case IrOpcode::kInt32x4ExtractLane:
243 case IrOpcode::kCreateInt32x4: { 391 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); 392 Node* laneNode = node->InputAt(1);
255 DCHECK_EQ(laneNode->opcode(), IrOpcode::kInt32Constant); 393 DCHECK_EQ(laneNode->opcode(), IrOpcode::kInt32Constant);
256 int32_t lane = OpParameter<int32_t>(laneNode); 394 int32_t lane = OpParameter<int32_t>(laneNode);
257 Node* rep_node[kMaxLanes] = { 395 Node* rep_node[kMaxLanes] = {
258 GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr, 396 GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr,
259 nullptr, nullptr}; 397 nullptr, nullptr};
260 ReplaceNode(node, rep_node); 398 ReplaceNode(node, rep_node);
261 break; 399 break;
262 } 400 }
263 401 case IrOpcode::kInt32x4ReplaceLane:
264 case IrOpcode::kFloat32x4Add: { 402 case IrOpcode::kFloat32x4ReplaceLane: {
265 DCHECK(node->InputCount() == 2); 403 Node* laneNode = node->InputAt(1);
266 Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type); 404 Node* repNode = node->InputAt(2);
Mircea Trofin 2016/11/15 16:21:27 dcheck for input count
aseemgarg 2016/11/19 01:56:54 Done.
267 Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type); 405 DCHECK_EQ(laneNode->opcode(), IrOpcode::kInt32Constant);
268 Node* rep_node[kMaxLanes]; 406 int32_t lane = OpParameter<int32_t>(laneNode);
Mircea Trofin 2016/11/15 16:21:27 dcheck lane is in bounds for rep_node
aseemgarg 2016/11/19 01:56:54 Done.
269 for (int i = 0; i < kMaxLanes; i++) { 407 Node** rep_node = GetReplacementsWithType(node->InputAt(0), rep_type);
270 rep_node[i] = graph()->NewNode(machine()->Float32Add(), rep_left[i], 408 if (HasReplacement(0, repNode)) {
271 rep_right[i]); 409 rep_node[lane] = GetReplacements(repNode)[0];
410 } else {
411 rep_node[lane] = repNode;
272 } 412 }
273 ReplaceNode(node, rep_node); 413 ReplaceNode(node, rep_node);
274 break; 414 break;
275 } 415 }
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); } 416 default: { DefaultLowering(node); }
299 } 417 }
300 } 418 }
301 419
302 bool SimdScalarLowering::DefaultLowering(Node* node) { 420 bool SimdScalarLowering::DefaultLowering(Node* node) {
303 bool something_changed = false; 421 bool something_changed = false;
304 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) { 422 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
305 Node* input = node->InputAt(i); 423 Node* input = node->InputAt(i);
306 if (HasReplacement(0, input)) { 424 if (HasReplacement(0, input)) {
307 something_changed = true; 425 something_changed = true;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 } else { 519 } else {
402 UNREACHABLE(); 520 UNREACHABLE();
403 } 521 }
404 } 522 }
405 ReplaceNode(phi, rep_nodes); 523 ReplaceNode(phi, rep_nodes);
406 } 524 }
407 } 525 }
408 } // namespace compiler 526 } // namespace compiler
409 } // namespace internal 527 } // namespace internal
410 } // namespace v8 528 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698