diff options
author | Michaël Zasso <targos@protonmail.com> | 2017-06-06 10:28:14 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2017-06-07 10:33:31 +0200 |
commit | 3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09 (patch) | |
tree | 9dee56e142638b34f1eccbd0ad88c3bce5377c29 /deps/v8/src/compiler/simd-scalar-lowering.cc | |
parent | 91a1bbe3055a660194ca4d403795aa0c03e9d056 (diff) | |
download | node-new-3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09.tar.gz |
deps: update V8 to 5.9.211.32
PR-URL: https://github.com/nodejs/node/pull/13263
Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'deps/v8/src/compiler/simd-scalar-lowering.cc')
-rw-r--r-- | deps/v8/src/compiler/simd-scalar-lowering.cc | 423 |
1 files changed, 380 insertions, 43 deletions
diff --git a/deps/v8/src/compiler/simd-scalar-lowering.cc b/deps/v8/src/compiler/simd-scalar-lowering.cc index 19ffe93775..8f967788db 100644 --- a/deps/v8/src/compiler/simd-scalar-lowering.cc +++ b/deps/v8/src/compiler/simd-scalar-lowering.cc @@ -17,24 +17,19 @@ namespace internal { namespace compiler { SimdScalarLowering::SimdScalarLowering( - Graph* graph, MachineOperatorBuilder* machine, - CommonOperatorBuilder* common, Zone* zone, - Signature<MachineRepresentation>* signature) - : zone_(zone), - graph_(graph), - machine_(machine), - common_(common), - state_(graph, 3), - stack_(zone), + JSGraph* jsgraph, Signature<MachineRepresentation>* signature) + : jsgraph_(jsgraph), + state_(jsgraph->graph(), 3), + stack_(jsgraph_->zone()), replacements_(nullptr), signature_(signature), - placeholder_( - graph->NewNode(common->Parameter(-2, "placeholder"), graph->start())), + placeholder_(graph()->NewNode(common()->Parameter(-2, "placeholder"), + graph()->start())), parameter_count_after_lowering_(-1) { - DCHECK_NOT_NULL(graph); - DCHECK_NOT_NULL(graph->end()); - replacements_ = zone->NewArray<Replacement>(graph->NodeCount()); - memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount()); + DCHECK_NOT_NULL(graph()); + DCHECK_NOT_NULL(graph()->end()); + replacements_ = zone()->NewArray<Replacement>(graph()->NodeCount()); + memset(replacements_, 0, sizeof(Replacement) * graph()->NodeCount()); } void SimdScalarLowering::LowerGraph() { @@ -72,16 +67,58 @@ void SimdScalarLowering::LowerGraph() { } #define FOREACH_INT32X4_OPCODE(V) \ - V(Int32x4Add) \ - V(Int32x4ExtractLane) \ - V(CreateInt32x4) \ - V(Int32x4ReplaceLane) + V(I32x4Splat) \ + V(I32x4ExtractLane) \ + V(I32x4ReplaceLane) \ + V(I32x4SConvertF32x4) \ + V(I32x4UConvertF32x4) \ + V(I32x4Neg) \ + V(I32x4Add) \ + V(I32x4Sub) \ + V(I32x4Mul) \ + V(I32x4MinS) \ + V(I32x4MaxS) \ + V(I32x4MinU) \ + V(I32x4MaxU) \ + V(S128And) \ + V(S128Or) \ + V(S128Xor) \ + V(S128Not) #define FOREACH_FLOAT32X4_OPCODE(V) \ - V(Float32x4Add) \ - V(Float32x4ExtractLane) \ - V(CreateFloat32x4) \ - V(Float32x4ReplaceLane) + V(F32x4Splat) \ + V(F32x4ExtractLane) \ + V(F32x4ReplaceLane) \ + V(F32x4SConvertI32x4) \ + V(F32x4UConvertI32x4) \ + V(F32x4Abs) \ + V(F32x4Neg) \ + V(F32x4Add) \ + V(F32x4Sub) \ + V(F32x4Mul) \ + V(F32x4Div) \ + V(F32x4Min) \ + V(F32x4Max) + +#define FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(V) \ + V(F32x4Eq) \ + V(F32x4Ne) \ + V(F32x4Lt) \ + V(F32x4Le) \ + V(F32x4Gt) \ + V(F32x4Ge) + +#define FOREACH_INT32X4_TO_SIMD1X4OPCODE(V) \ + V(I32x4Eq) \ + V(I32x4Ne) \ + V(I32x4LtS) \ + V(I32x4LeS) \ + V(I32x4GtS) \ + V(I32x4GeS) \ + V(I32x4LtU) \ + V(I32x4LeU) \ + V(I32x4GtU) \ + V(I32x4GeU) void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { switch (node->opcode()) { @@ -97,9 +134,35 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { replacements_[node->id()].type = SimdType::kFloat32; break; } + FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT) + FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) { + replacements_[node->id()].type = SimdType::kSimd1x4; + break; + } + default: { + switch (output->opcode()) { + FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT) + case IrOpcode::kF32x4SConvertI32x4: + case IrOpcode::kF32x4UConvertI32x4: { + replacements_[node->id()].type = SimdType::kInt32; + break; + } + FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) + case IrOpcode::kI32x4SConvertF32x4: + case IrOpcode::kI32x4UConvertF32x4: { + replacements_[node->id()].type = SimdType::kFloat32; + break; + } + case IrOpcode::kS32x4Select: { + replacements_[node->id()].type = SimdType::kSimd1x4; + break; + } + default: { + replacements_[node->id()].type = replacements_[output->id()].type; + } + } + } #undef CASE_STMT - default: - replacements_[node->id()].type = replacements_[output->id()].type; } } @@ -219,14 +282,142 @@ void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node, } } -void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType rep_type, +void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type, + const Operator* op, bool invert_inputs) { + DCHECK(node->InputCount() == 2); + Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); + Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); + Node* rep_node[kMaxLanes]; + for (int i = 0; i < kMaxLanes; ++i) { + if (invert_inputs) { + rep_node[i] = graph()->NewNode(op, rep_right[i], rep_left[i]); + } else { + rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]); + } + } + ReplaceNode(node, rep_node); +} + +void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type, + const Operator* op) { + DCHECK(node->InputCount() == 1); + Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type); + Node* rep_node[kMaxLanes]; + for (int i = 0; i < kMaxLanes; ++i) { + rep_node[i] = graph()->NewNode(op, rep[i]); + } + ReplaceNode(node, rep_node); +} + +void SimdScalarLowering::LowerIntMinMax(Node* node, const Operator* op, + bool is_max) { + DCHECK(node->InputCount() == 2); + Node** rep_left = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); + Node** rep_right = + GetReplacementsWithType(node->InputAt(1), SimdType::kInt32); + Node* rep_node[kMaxLanes]; + for (int i = 0; i < kMaxLanes; ++i) { + Diamond d(graph(), common(), + graph()->NewNode(op, rep_left[i], rep_right[i])); + if (is_max) { + rep_node[i] = + d.Phi(MachineRepresentation::kWord32, rep_right[i], rep_left[i]); + } else { + rep_node[i] = + d.Phi(MachineRepresentation::kWord32, rep_left[i], rep_right[i]); + } + } + ReplaceNode(node, rep_node); +} + +Node* SimdScalarLowering::BuildF64Trunc(Node* input) { + if (machine()->Float64RoundTruncate().IsSupported()) { + return graph()->NewNode(machine()->Float64RoundTruncate().op(), input); + } else { + ExternalReference ref = + ExternalReference::wasm_f64_trunc(jsgraph_->isolate()); + Node* stack_slot = + graph()->NewNode(machine()->StackSlot(MachineRepresentation::kFloat64)); + const Operator* store_op = machine()->Store( + StoreRepresentation(MachineRepresentation::kFloat64, kNoWriteBarrier)); + Node* effect = + graph()->NewNode(store_op, stack_slot, jsgraph_->Int32Constant(0), + input, graph()->start(), graph()->start()); + Node* function = graph()->NewNode(common()->ExternalConstant(ref)); + Node** args = zone()->NewArray<Node*>(4); + args[0] = function; + args[1] = stack_slot; + args[2] = effect; + args[3] = graph()->start(); + Signature<MachineType>::Builder sig_builder(zone(), 0, 1); + sig_builder.AddParam(MachineType::Pointer()); + CallDescriptor* desc = + Linkage::GetSimplifiedCDescriptor(zone(), sig_builder.Build()); + Node* call = graph()->NewNode(common()->Call(desc), 4, args); + return graph()->NewNode(machine()->Load(LoadRepresentation::Float64()), + stack_slot, jsgraph_->Int32Constant(0), call, + graph()->start()); + } +} + +void SimdScalarLowering::LowerConvertFromFloat(Node* node, bool is_signed) { + DCHECK(node->InputCount() == 1); + Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kFloat32); + Node* rep_node[kMaxLanes]; + Node* double_zero = graph()->NewNode(common()->Float64Constant(0.0)); + Node* min = graph()->NewNode( + common()->Float64Constant(static_cast<double>(is_signed ? kMinInt : 0))); + Node* max = graph()->NewNode(common()->Float64Constant( + static_cast<double>(is_signed ? kMaxInt : 0xffffffffu))); + for (int i = 0; i < kMaxLanes; ++i) { + Node* double_rep = + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), rep[i]); + Diamond nan_d(graph(), common(), graph()->NewNode(machine()->Float64Equal(), + double_rep, double_rep)); + Node* temp = + nan_d.Phi(MachineRepresentation::kFloat64, double_rep, double_zero); + Diamond min_d(graph(), common(), + graph()->NewNode(machine()->Float64LessThan(), temp, min)); + temp = min_d.Phi(MachineRepresentation::kFloat64, min, temp); + Diamond max_d(graph(), common(), + graph()->NewNode(machine()->Float64LessThan(), max, temp)); + temp = max_d.Phi(MachineRepresentation::kFloat64, max, temp); + Node* trunc = BuildF64Trunc(temp); + if (is_signed) { + rep_node[i] = graph()->NewNode(machine()->ChangeFloat64ToInt32(), trunc); + } else { + rep_node[i] = + graph()->NewNode(machine()->TruncateFloat64ToUint32(), trunc); + } + } + ReplaceNode(node, rep_node); +} + +void SimdScalarLowering::LowerShiftOp(Node* node, const Operator* op) { + static int32_t shift_mask = 0x1f; + DCHECK_EQ(1, node->InputCount()); + int32_t shift_amount = OpParameter<int32_t>(node); + Node* shift_node = + graph()->NewNode(common()->Int32Constant(shift_amount & shift_mask)); + Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); + Node* rep_node[kMaxLanes]; + for (int i = 0; i < kMaxLanes; ++i) { + rep_node[i] = graph()->NewNode(op, rep[i], shift_node); + } + ReplaceNode(node, rep_node); +} + +void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type, const Operator* op) { DCHECK(node->InputCount() == 2); - Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type); - Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type); + Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); + Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); Node* rep_node[kMaxLanes]; for (int i = 0; i < kMaxLanes; ++i) { - rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]); + Diamond d(graph(), common(), + graph()->NewNode(op, rep_left[i], rep_right[i])); + rep_node[i] = d.Phi(MachineRepresentation::kWord32, + jsgraph_->Int32Constant(0), jsgraph_->Int32Constant(1)); } ReplaceNode(node, rep_node); } @@ -377,29 +568,120 @@ void SimdScalarLowering::LowerNode(Node* node) { } break; } - case IrOpcode::kInt32x4Add: { - LowerBinaryOp(node, rep_type, machine()->Int32Add()); +#define I32X4_BINOP_CASE(opcode, instruction) \ + case IrOpcode::opcode: { \ + LowerBinaryOp(node, rep_type, machine()->instruction()); \ + break; \ + } + I32X4_BINOP_CASE(kI32x4Add, Int32Add) + I32X4_BINOP_CASE(kI32x4Sub, Int32Sub) + I32X4_BINOP_CASE(kI32x4Mul, Int32Mul) + I32X4_BINOP_CASE(kS128And, Word32And) + I32X4_BINOP_CASE(kS128Or, Word32Or) + I32X4_BINOP_CASE(kS128Xor, Word32Xor) +#undef I32X4_BINOP_CASE + case IrOpcode::kI32x4MaxS: { + LowerIntMinMax(node, machine()->Int32LessThan(), true); + break; + } + case IrOpcode::kI32x4MinS: { + LowerIntMinMax(node, machine()->Int32LessThan(), false); + break; + } + case IrOpcode::kI32x4MaxU: { + LowerIntMinMax(node, machine()->Uint32LessThan(), true); + break; + } + case IrOpcode::kI32x4MinU: { + LowerIntMinMax(node, machine()->Uint32LessThan(), false); + break; + } + case IrOpcode::kI32x4Neg: { + DCHECK(node->InputCount() == 1); + Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); + Node* rep_node[kMaxLanes]; + Node* zero = graph()->NewNode(common()->Int32Constant(0)); + for (int i = 0; i < kMaxLanes; ++i) { + rep_node[i] = graph()->NewNode(machine()->Int32Sub(), zero, rep[i]); + } + ReplaceNode(node, rep_node); + break; + } + case IrOpcode::kS128Not: { + DCHECK(node->InputCount() == 1); + Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); + Node* rep_node[kMaxLanes]; + Node* mask = graph()->NewNode(common()->Int32Constant(0xffffffff)); + for (int i = 0; i < kMaxLanes; ++i) { + rep_node[i] = graph()->NewNode(machine()->Word32Xor(), rep[i], mask); + } + ReplaceNode(node, rep_node); + break; + } + case IrOpcode::kI32x4SConvertF32x4: { + LowerConvertFromFloat(node, true); + break; + } + case IrOpcode::kI32x4UConvertF32x4: { + LowerConvertFromFloat(node, false); + break; + } + case IrOpcode::kI32x4Shl: { + LowerShiftOp(node, machine()->Word32Shl()); + break; + } + case IrOpcode::kI32x4ShrS: { + LowerShiftOp(node, machine()->Word32Sar()); break; } - case IrOpcode::kFloat32x4Add: { - LowerBinaryOp(node, rep_type, machine()->Float32Add()); + case IrOpcode::kI32x4ShrU: { + LowerShiftOp(node, machine()->Word32Shr()); + break; + } +#define F32X4_BINOP_CASE(name) \ + case IrOpcode::kF32x4##name: { \ + LowerBinaryOp(node, rep_type, machine()->Float32##name()); \ + break; \ + } + F32X4_BINOP_CASE(Add) + F32X4_BINOP_CASE(Sub) + F32X4_BINOP_CASE(Mul) + F32X4_BINOP_CASE(Div) + F32X4_BINOP_CASE(Min) + F32X4_BINOP_CASE(Max) +#undef F32X4_BINOP_CASE +#define F32X4_UNOP_CASE(name) \ + case IrOpcode::kF32x4##name: { \ + LowerUnaryOp(node, rep_type, machine()->Float32##name()); \ + break; \ + } + F32X4_UNOP_CASE(Abs) + F32X4_UNOP_CASE(Neg) + F32X4_UNOP_CASE(Sqrt) +#undef F32x4_UNOP_CASE + case IrOpcode::kF32x4SConvertI32x4: { + LowerUnaryOp(node, SimdType::kInt32, machine()->RoundInt32ToFloat32()); break; } - case IrOpcode::kCreateInt32x4: - case IrOpcode::kCreateFloat32x4: { + case IrOpcode::kF32x4UConvertI32x4: { + LowerUnaryOp(node, SimdType::kInt32, machine()->RoundUint32ToFloat32()); + break; + } + case IrOpcode::kI32x4Splat: + case IrOpcode::kF32x4Splat: { Node* rep_node[kMaxLanes]; for (int i = 0; i < kMaxLanes; ++i) { - if (HasReplacement(0, node->InputAt(i))) { - rep_node[i] = GetReplacements(node->InputAt(i))[0]; + if (HasReplacement(0, node->InputAt(0))) { + rep_node[i] = GetReplacements(node->InputAt(0))[0]; } else { - rep_node[i] = node->InputAt(i); + rep_node[i] = node->InputAt(0); } } ReplaceNode(node, rep_node); break; } - case IrOpcode::kInt32x4ExtractLane: - case IrOpcode::kFloat32x4ExtractLane: { + case IrOpcode::kI32x4ExtractLane: + case IrOpcode::kF32x4ExtractLane: { int32_t lane = OpParameter<int32_t>(node); Node* rep_node[kMaxLanes] = { GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr, @@ -407,8 +689,8 @@ void SimdScalarLowering::LowerNode(Node* node) { ReplaceNode(node, rep_node); break; } - case IrOpcode::kInt32x4ReplaceLane: - case IrOpcode::kFloat32x4ReplaceLane: { + case IrOpcode::kI32x4ReplaceLane: + case IrOpcode::kF32x4ReplaceLane: { DCHECK_EQ(2, node->InputCount()); Node* repNode = node->InputAt(1); int32_t lane = OpParameter<int32_t>(node); @@ -422,6 +704,58 @@ void SimdScalarLowering::LowerNode(Node* node) { ReplaceNode(node, rep_node); break; } +#define COMPARISON_CASE(type, simd_op, lowering_op, invert) \ + case IrOpcode::simd_op: { \ + LowerBinaryOp(node, SimdType::k##type, machine()->lowering_op(), invert); \ + break; \ + } + COMPARISON_CASE(Float32, kF32x4Eq, Float32Equal, false) + COMPARISON_CASE(Float32, kF32x4Lt, Float32LessThan, false) + COMPARISON_CASE(Float32, kF32x4Le, Float32LessThanOrEqual, false) + COMPARISON_CASE(Float32, kF32x4Gt, Float32LessThan, true) + COMPARISON_CASE(Float32, kF32x4Ge, Float32LessThanOrEqual, true) + COMPARISON_CASE(Int32, kI32x4Eq, Word32Equal, false) + COMPARISON_CASE(Int32, kI32x4LtS, Int32LessThan, false) + COMPARISON_CASE(Int32, kI32x4LeS, Int32LessThanOrEqual, false) + COMPARISON_CASE(Int32, kI32x4GtS, Int32LessThan, true) + COMPARISON_CASE(Int32, kI32x4GeS, Int32LessThanOrEqual, true) + COMPARISON_CASE(Int32, kI32x4LtU, Uint32LessThan, false) + COMPARISON_CASE(Int32, kI32x4LeU, Uint32LessThanOrEqual, false) + COMPARISON_CASE(Int32, kI32x4GtU, Uint32LessThan, true) + COMPARISON_CASE(Int32, kI32x4GeU, Uint32LessThanOrEqual, true) +#undef COMPARISON_CASE + case IrOpcode::kF32x4Ne: { + LowerNotEqual(node, SimdType::kFloat32, machine()->Float32Equal()); + break; + } + case IrOpcode::kI32x4Ne: { + LowerNotEqual(node, SimdType::kInt32, machine()->Word32Equal()); + break; + } + case IrOpcode::kS32x4Select: { + DCHECK(node->InputCount() == 3); + DCHECK(ReplacementType(node->InputAt(0)) == SimdType::kSimd1x4); + Node** boolean_input = GetReplacements(node->InputAt(0)); + Node** rep_left = GetReplacementsWithType(node->InputAt(1), rep_type); + Node** rep_right = GetReplacementsWithType(node->InputAt(2), rep_type); + Node* rep_node[kMaxLanes]; + for (int i = 0; i < kMaxLanes; ++i) { + Diamond d(graph(), common(), + graph()->NewNode(machine()->Word32Equal(), boolean_input[i], + jsgraph_->Int32Constant(0))); + if (rep_type == SimdType::kFloat32) { + rep_node[i] = + d.Phi(MachineRepresentation::kFloat32, rep_right[1], rep_left[0]); + } else if (rep_type == SimdType::kInt32) { + rep_node[i] = + d.Phi(MachineRepresentation::kWord32, rep_right[1], rep_left[0]); + } else { + UNREACHABLE(); + } + } + ReplaceNode(node, rep_node); + break; + } default: { DefaultLowering(node); } } } @@ -483,7 +817,8 @@ Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) { result[i] = nullptr; } } - } else { + } else if (ReplacementType(node) == SimdType::kFloat32 && + type == SimdType::kInt32) { for (int i = 0; i < kMaxLanes; ++i) { if (replacements[i] != nullptr) { result[i] = graph()->NewNode(machine()->BitcastFloat32ToInt32(), @@ -492,6 +827,8 @@ Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) { result[i] = nullptr; } } + } else { + UNREACHABLE(); } return result; } |