Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 | 73 |
| 74 #define FOREACH_INT32X4_OPCODE(V) \ | 74 #define FOREACH_INT32X4_OPCODE(V) \ |
| 75 V(Int32x4Splat) \ | 75 V(Int32x4Splat) \ |
| 76 V(Int32x4ExtractLane) \ | 76 V(Int32x4ExtractLane) \ |
| 77 V(Int32x4ReplaceLane) \ | 77 V(Int32x4ReplaceLane) \ |
| 78 V(Int32x4Neg) \ | 78 V(Int32x4Neg) \ |
| 79 V(Simd128Not) \ | 79 V(Simd128Not) \ |
| 80 V(Int32x4Add) \ | 80 V(Int32x4Add) \ |
| 81 V(Int32x4Sub) \ | 81 V(Int32x4Sub) \ |
| 82 V(Int32x4Mul) \ | 82 V(Int32x4Mul) \ |
| 83 V(Int32x4Min) \ | |
| 84 V(Int32x4Max) \ | |
| 85 V(Uint32x4Min) \ | |
| 86 V(Uint32x4Max) \ | |
| 83 V(Simd128And) \ | 87 V(Simd128And) \ |
| 84 V(Simd128Or) \ | 88 V(Simd128Or) \ |
| 85 V(Simd128Xor) | 89 V(Simd128Xor) \ |
| 90 V(Int32x4FromFloat32x4) \ | |
| 91 V(Uint32x4FromFloat32x4) | |
| 86 | 92 |
| 87 #define FOREACH_FLOAT32X4_OPCODE(V) \ | 93 #define FOREACH_FLOAT32X4_OPCODE(V) \ |
| 88 V(Float32x4Splat) \ | 94 V(Float32x4Splat) \ |
| 89 V(Float32x4ExtractLane) \ | 95 V(Float32x4ExtractLane) \ |
| 90 V(Float32x4ReplaceLane) \ | 96 V(Float32x4ReplaceLane) \ |
| 91 V(Float32x4Abs) \ | 97 V(Float32x4Abs) \ |
| 92 V(Float32x4Neg) \ | 98 V(Float32x4Neg) \ |
| 93 V(Float32x4Add) \ | 99 V(Float32x4Add) \ |
| 94 V(Float32x4Sub) \ | 100 V(Float32x4Sub) \ |
| 95 V(Float32x4Mul) \ | 101 V(Float32x4Mul) \ |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 107 case IrOpcode::kParameter: | 113 case IrOpcode::kParameter: |
| 108 case IrOpcode::kCall: { | 114 case IrOpcode::kCall: { |
| 109 replacements_[node->id()].type = SimdType::kInt32; | 115 replacements_[node->id()].type = SimdType::kInt32; |
| 110 break; | 116 break; |
| 111 } | 117 } |
| 112 FOREACH_FLOAT32X4_OPCODE(CASE_STMT) { | 118 FOREACH_FLOAT32X4_OPCODE(CASE_STMT) { |
| 113 replacements_[node->id()].type = SimdType::kFloat32; | 119 replacements_[node->id()].type = SimdType::kFloat32; |
| 114 break; | 120 break; |
| 115 } | 121 } |
| 116 #undef CASE_STMT | 122 #undef CASE_STMT |
| 117 default: { | 123 default: { |
|
titzer
2017/03/01 09:40:28
Probably time for an innner switch now?
aseemgarg
2017/03/01 10:55:16
Done.
| |
| 118 if (output->opcode() == IrOpcode::kFloat32x4FromInt32x4 || | 124 if (output->opcode() == IrOpcode::kFloat32x4FromInt32x4 || |
| 119 output->opcode() == IrOpcode::kFloat32x4FromUint32x4) { | 125 output->opcode() == IrOpcode::kFloat32x4FromUint32x4) { |
| 120 replacements_[node->id()].type = SimdType::kInt32; | 126 replacements_[node->id()].type = SimdType::kInt32; |
| 127 } else if (output->opcode() == IrOpcode::kInt32x4FromFloat32x4 || | |
| 128 output->opcode() == IrOpcode::kUint32x4FromFloat32x4) { | |
| 129 replacements_[node->id()].type = SimdType::kFloat32; | |
| 121 } else { | 130 } else { |
| 122 replacements_[node->id()].type = replacements_[output->id()].type; | 131 replacements_[node->id()].type = replacements_[output->id()].type; |
| 123 } | 132 } |
| 124 } | 133 } |
| 125 } | 134 } |
| 126 } | 135 } |
| 127 | 136 |
| 128 static int GetParameterIndexAfterLowering( | 137 static int GetParameterIndexAfterLowering( |
| 129 Signature<MachineRepresentation>* signature, int old_index) { | 138 Signature<MachineRepresentation>* signature, int old_index) { |
| 130 // In function calls, the simd128 types are passed as 4 Int32 types. The | 139 // In function calls, the simd128 types are passed as 4 Int32 types. The |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 257 const Operator* op) { | 266 const Operator* op) { |
| 258 DCHECK(node->InputCount() == 1); | 267 DCHECK(node->InputCount() == 1); |
| 259 Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type); | 268 Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type); |
| 260 Node* rep_node[kMaxLanes]; | 269 Node* rep_node[kMaxLanes]; |
| 261 for (int i = 0; i < kMaxLanes; ++i) { | 270 for (int i = 0; i < kMaxLanes; ++i) { |
| 262 rep_node[i] = graph()->NewNode(op, rep[i]); | 271 rep_node[i] = graph()->NewNode(op, rep[i]); |
| 263 } | 272 } |
| 264 ReplaceNode(node, rep_node); | 273 ReplaceNode(node, rep_node); |
| 265 } | 274 } |
| 266 | 275 |
| 276 void SimdScalarLowering::LowerIntMinMax(Node* node, const Operator* op, | |
| 277 bool is_max) { | |
| 278 DCHECK(node->InputCount() == 2); | |
| 279 Node** rep_left = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); | |
| 280 Node** rep_right = | |
| 281 GetReplacementsWithType(node->InputAt(1), SimdType::kInt32); | |
| 282 Node* rep_node[kMaxLanes]; | |
| 283 for (int i = 0; i < kMaxLanes; ++i) { | |
| 284 Diamond d(graph(), common(), | |
| 285 graph()->NewNode(op, rep_left[i], rep_right[i])); | |
| 286 if (is_max) { | |
| 287 rep_node[i] = | |
| 288 d.Phi(MachineRepresentation::kWord32, rep_right[i], rep_left[i]); | |
| 289 } else { | |
| 290 rep_node[i] = | |
| 291 d.Phi(MachineRepresentation::kWord32, rep_left[i], rep_right[i]); | |
| 292 } | |
| 293 } | |
| 294 ReplaceNode(node, rep_node); | |
| 295 } | |
| 296 | |
| 297 void SimdScalarLowering::LowerConvertFromFloat(Node* node, bool is_signed) { | |
| 298 DCHECK(node->InputCount() == 1); | |
| 299 Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kFloat32); | |
| 300 Node* rep_node[kMaxLanes]; | |
| 301 Node* double_zero = graph()->NewNode(common()->Float64Constant(0.0)); | |
| 302 Node* min = graph()->NewNode( | |
| 303 common()->Float64Constant(static_cast<double>(is_signed ? kMinInt : 0))); | |
| 304 Node* max = graph()->NewNode(common()->Float64Constant( | |
| 305 static_cast<double>(is_signed ? kMaxInt : 0xffffffffu))); | |
| 306 for (int i = 0; i < kMaxLanes; ++i) { | |
| 307 Node* double_rep = | |
| 308 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), rep[i]); | |
| 309 Diamond nan_d(graph(), common(), graph()->NewNode(machine()->Float64Equal(), | |
| 310 double_rep, double_rep)); | |
| 311 Node* temp = | |
| 312 nan_d.Phi(MachineRepresentation::kFloat64, double_rep, double_zero); | |
| 313 Diamond min_d(graph(), common(), | |
| 314 graph()->NewNode(machine()->Float64LessThan(), temp, min)); | |
| 315 temp = min_d.Phi(MachineRepresentation::kFloat64, min, temp); | |
| 316 Diamond max_d(graph(), common(), | |
| 317 graph()->NewNode(machine()->Float64LessThan(), max, temp)); | |
| 318 // if (!machine()->Float32RoundTruncate().IsSupported()) { | |
|
titzer
2017/03/01 09:40:28
Is this code ncessary? if not, then please remove
aseemgarg
2017/03/01 10:55:16
Removed. All bots are passing with this commented
| |
| 319 // trunc = BuildF32Trunc(input); | |
| 320 // } else { | |
| 321 // trunc = | |
| 322 // } | |
| 323 temp = max_d.Phi(MachineRepresentation::kFloat64, max, temp); | |
| 324 Node* trunc = | |
| 325 graph()->NewNode(machine()->Float64RoundTruncate().op(), temp); | |
| 326 if (is_signed) { | |
| 327 rep_node[i] = graph()->NewNode(machine()->ChangeFloat64ToInt32(), trunc); | |
| 328 } else { | |
| 329 rep_node[i] = | |
| 330 graph()->NewNode(machine()->TruncateFloat64ToUint32(), trunc); | |
| 331 } | |
| 332 } | |
| 333 ReplaceNode(node, rep_node); | |
| 334 } | |
| 335 | |
| 336 void SimdScalarLowering::LowerShiftOp(Node* node, const Operator* op) { | |
| 337 static int32_t shift_mask = 0x1f; | |
| 338 DCHECK_EQ(1, node->InputCount()); | |
| 339 int32_t shift_amount = OpParameter<int32_t>(node); | |
| 340 Node* shift_node = | |
| 341 graph()->NewNode(common()->Int32Constant(shift_amount & shift_mask)); | |
| 342 Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); | |
| 343 Node* rep_node[kMaxLanes]; | |
| 344 for (int i = 0; i < kMaxLanes; ++i) { | |
| 345 rep_node[i] = graph()->NewNode(op, rep[i], shift_node); | |
| 346 } | |
| 347 ReplaceNode(node, rep_node); | |
| 348 } | |
| 349 | |
| 267 void SimdScalarLowering::LowerNode(Node* node) { | 350 void SimdScalarLowering::LowerNode(Node* node) { |
| 268 SimdType rep_type = ReplacementType(node); | 351 SimdType rep_type = ReplacementType(node); |
| 269 switch (node->opcode()) { | 352 switch (node->opcode()) { |
| 270 case IrOpcode::kStart: { | 353 case IrOpcode::kStart: { |
| 271 int parameter_count = GetParameterCountAfterLowering(); | 354 int parameter_count = GetParameterCountAfterLowering(); |
| 272 // Only exchange the node if the parameter count actually changed. | 355 // Only exchange the node if the parameter count actually changed. |
| 273 if (parameter_count != static_cast<int>(signature()->parameter_count())) { | 356 if (parameter_count != static_cast<int>(signature()->parameter_count())) { |
| 274 int delta = | 357 int delta = |
| 275 parameter_count - static_cast<int>(signature()->parameter_count()); | 358 parameter_count - static_cast<int>(signature()->parameter_count()); |
| 276 int new_output_count = node->op()->ValueOutputCount() + delta; | 359 int new_output_count = node->op()->ValueOutputCount() + delta; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 LowerBinaryOp(node, rep_type, machine()->instruction()); \ | 498 LowerBinaryOp(node, rep_type, machine()->instruction()); \ |
| 416 break; \ | 499 break; \ |
| 417 } | 500 } |
| 418 I32X4_BINOP_CASE(kInt32x4Add, Int32Add) | 501 I32X4_BINOP_CASE(kInt32x4Add, Int32Add) |
| 419 I32X4_BINOP_CASE(kInt32x4Sub, Int32Sub) | 502 I32X4_BINOP_CASE(kInt32x4Sub, Int32Sub) |
| 420 I32X4_BINOP_CASE(kInt32x4Mul, Int32Mul) | 503 I32X4_BINOP_CASE(kInt32x4Mul, Int32Mul) |
| 421 I32X4_BINOP_CASE(kSimd128And, Word32And) | 504 I32X4_BINOP_CASE(kSimd128And, Word32And) |
| 422 I32X4_BINOP_CASE(kSimd128Or, Word32Or) | 505 I32X4_BINOP_CASE(kSimd128Or, Word32Or) |
| 423 I32X4_BINOP_CASE(kSimd128Xor, Word32Xor) | 506 I32X4_BINOP_CASE(kSimd128Xor, Word32Xor) |
| 424 #undef I32X4_BINOP_CASE | 507 #undef I32X4_BINOP_CASE |
| 508 case IrOpcode::kInt32x4Max: { | |
| 509 LowerIntMinMax(node, machine()->Int32LessThan(), true); | |
| 510 break; | |
| 511 } | |
| 512 case IrOpcode::kInt32x4Min: { | |
| 513 LowerIntMinMax(node, machine()->Int32LessThan(), false); | |
| 514 break; | |
| 515 } | |
| 516 case IrOpcode::kUint32x4Max: { | |
| 517 LowerIntMinMax(node, machine()->Uint32LessThan(), true); | |
| 518 break; | |
| 519 } | |
| 520 case IrOpcode::kUint32x4Min: { | |
| 521 LowerIntMinMax(node, machine()->Uint32LessThan(), false); | |
| 522 break; | |
| 523 } | |
| 425 case IrOpcode::kInt32x4Neg: { | 524 case IrOpcode::kInt32x4Neg: { |
| 426 DCHECK(node->InputCount() == 1); | 525 DCHECK(node->InputCount() == 1); |
| 427 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); | 526 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); |
| 428 Node* rep_node[kMaxLanes]; | 527 Node* rep_node[kMaxLanes]; |
| 429 for (int i = 0; i < kMaxLanes; ++i) { | 528 for (int i = 0; i < kMaxLanes; ++i) { |
| 430 rep_node[i] = graph()->NewNode( | 529 rep_node[i] = graph()->NewNode( |
| 431 machine()->Int32Sub(), graph()->NewNode(common()->Int32Constant(0)), | 530 machine()->Int32Sub(), graph()->NewNode(common()->Int32Constant(0)), |
| 432 rep[i]); | 531 rep[i]); |
| 433 } | 532 } |
| 434 ReplaceNode(node, rep_node); | 533 ReplaceNode(node, rep_node); |
| 435 break; | 534 break; |
| 436 } | 535 } |
| 437 case IrOpcode::kSimd128Not: { | 536 case IrOpcode::kSimd128Not: { |
| 438 DCHECK(node->InputCount() == 1); | 537 DCHECK(node->InputCount() == 1); |
| 439 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); | 538 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); |
| 440 Node* rep_node[kMaxLanes]; | 539 Node* rep_node[kMaxLanes]; |
| 441 for (int i = 0; i < kMaxLanes; ++i) { | 540 for (int i = 0; i < kMaxLanes; ++i) { |
| 442 rep_node[i] = graph()->NewNode( | 541 rep_node[i] = graph()->NewNode( |
| 443 machine()->Word32Xor(), rep[i], | 542 machine()->Word32Xor(), rep[i], |
| 444 graph()->NewNode(common()->Int32Constant(0xffffffff))); | 543 graph()->NewNode(common()->Int32Constant(0xffffffff))); |
| 445 } | 544 } |
| 446 ReplaceNode(node, rep_node); | 545 ReplaceNode(node, rep_node); |
| 447 break; | 546 break; |
| 448 } | 547 } |
| 548 case IrOpcode::kInt32x4FromFloat32x4: { | |
| 549 LowerConvertFromFloat(node, true); | |
| 550 break; | |
| 551 } | |
| 552 case IrOpcode::kUint32x4FromFloat32x4: { | |
| 553 LowerConvertFromFloat(node, false); | |
| 554 break; | |
| 555 } | |
| 556 case IrOpcode::kInt32x4ShiftLeftByScalar: { | |
| 557 LowerShiftOp(node, machine()->Word32Shl()); | |
| 558 break; | |
| 559 } | |
| 560 case IrOpcode::kInt32x4ShiftRightByScalar: { | |
| 561 LowerShiftOp(node, machine()->Word32Sar()); | |
| 562 break; | |
| 563 } | |
| 564 case IrOpcode::kUint32x4ShiftRightByScalar: { | |
| 565 LowerShiftOp(node, machine()->Word32Shr()); | |
| 566 break; | |
| 567 } | |
| 449 #define F32X4_BINOP_CASE(name) \ | 568 #define F32X4_BINOP_CASE(name) \ |
| 450 case IrOpcode::kFloat32x4##name: { \ | 569 case IrOpcode::kFloat32x4##name: { \ |
| 451 LowerBinaryOp(node, rep_type, machine()->Float32##name()); \ | 570 LowerBinaryOp(node, rep_type, machine()->Float32##name()); \ |
| 452 break; \ | 571 break; \ |
| 453 } | 572 } |
| 454 F32X4_BINOP_CASE(Add) | 573 F32X4_BINOP_CASE(Add) |
| 455 F32X4_BINOP_CASE(Sub) | 574 F32X4_BINOP_CASE(Sub) |
| 456 F32X4_BINOP_CASE(Mul) | 575 F32X4_BINOP_CASE(Mul) |
| 457 F32X4_BINOP_CASE(Div) | 576 F32X4_BINOP_CASE(Div) |
| 458 F32X4_BINOP_CASE(Min) | 577 F32X4_BINOP_CASE(Min) |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 618 } else { | 737 } else { |
| 619 UNREACHABLE(); | 738 UNREACHABLE(); |
| 620 } | 739 } |
| 621 } | 740 } |
| 622 ReplaceNode(phi, rep_nodes); | 741 ReplaceNode(phi, rep_nodes); |
| 623 } | 742 } |
| 624 } | 743 } |
| 625 } // namespace compiler | 744 } // namespace compiler |
| 626 } // namespace internal | 745 } // namespace internal |
| 627 } // namespace v8 | 746 } // namespace v8 |
| OLD | NEW |