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

Unified Diff: src/compiler/simd-scalar-lowering.cc

Issue 2724973003: [wasm]implement simd lowering for f32x4->i32x4, i32x4 min/max and shift instructions (Closed)
Patch Set: comment Created 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/simd-scalar-lowering.h ('k') | src/compiler/wasm-compiler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/simd-scalar-lowering.cc
diff --git a/src/compiler/simd-scalar-lowering.cc b/src/compiler/simd-scalar-lowering.cc
index cfa46c3cafe817c92ee61c462928a8aa67fddbff..d2487e2e79bbb1cf6e6eb604c216a762c87faca6 100644
--- a/src/compiler/simd-scalar-lowering.cc
+++ b/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() {
@@ -80,9 +75,15 @@ void SimdScalarLowering::LowerGraph() {
V(Int32x4Add) \
V(Int32x4Sub) \
V(Int32x4Mul) \
+ V(Int32x4Min) \
+ V(Int32x4Max) \
+ V(Uint32x4Min) \
+ V(Uint32x4Max) \
V(Simd128And) \
V(Simd128Or) \
- V(Simd128Xor)
+ V(Simd128Xor) \
+ V(Int32x4FromFloat32x4) \
+ V(Uint32x4FromFloat32x4)
#define FOREACH_FLOAT32X4_OPCODE(V) \
V(Float32x4Splat) \
@@ -115,11 +116,20 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
}
#undef CASE_STMT
default: {
- if (output->opcode() == IrOpcode::kFloat32x4FromInt32x4 ||
- output->opcode() == IrOpcode::kFloat32x4FromUint32x4) {
- replacements_[node->id()].type = SimdType::kInt32;
- } else {
- replacements_[node->id()].type = replacements_[output->id()].type;
+ switch (output->opcode()) {
+ case IrOpcode::kFloat32x4FromInt32x4:
+ case IrOpcode::kFloat32x4FromUint32x4: {
+ replacements_[node->id()].type = SimdType::kInt32;
+ break;
+ }
+ case IrOpcode::kInt32x4FromFloat32x4:
+ case IrOpcode::kUint32x4FromFloat32x4: {
+ replacements_[node->id()].type = SimdType::kFloat32;
+ break;
+ }
+ default: {
+ replacements_[node->id()].type = replacements_[output->id()].type;
+ }
}
}
}
@@ -264,6 +274,104 @@ void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type,
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::LowerNode(Node* node) {
SimdType rep_type = ReplacementType(node);
switch (node->opcode()) {
@@ -422,6 +530,22 @@ void SimdScalarLowering::LowerNode(Node* node) {
I32X4_BINOP_CASE(kSimd128Or, Word32Or)
I32X4_BINOP_CASE(kSimd128Xor, Word32Xor)
#undef I32X4_BINOP_CASE
+ case IrOpcode::kInt32x4Max: {
+ LowerIntMinMax(node, machine()->Int32LessThan(), true);
+ break;
+ }
+ case IrOpcode::kInt32x4Min: {
+ LowerIntMinMax(node, machine()->Int32LessThan(), false);
+ break;
+ }
+ case IrOpcode::kUint32x4Max: {
+ LowerIntMinMax(node, machine()->Uint32LessThan(), true);
+ break;
+ }
+ case IrOpcode::kUint32x4Min: {
+ LowerIntMinMax(node, machine()->Uint32LessThan(), false);
+ break;
+ }
case IrOpcode::kInt32x4Neg: {
DCHECK(node->InputCount() == 1);
Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
@@ -444,6 +568,26 @@ void SimdScalarLowering::LowerNode(Node* node) {
ReplaceNode(node, rep_node);
break;
}
+ case IrOpcode::kInt32x4FromFloat32x4: {
+ LowerConvertFromFloat(node, true);
+ break;
+ }
+ case IrOpcode::kUint32x4FromFloat32x4: {
+ LowerConvertFromFloat(node, false);
+ break;
+ }
+ case IrOpcode::kInt32x4ShiftLeftByScalar: {
+ LowerShiftOp(node, machine()->Word32Shl());
+ break;
+ }
+ case IrOpcode::kInt32x4ShiftRightByScalar: {
+ LowerShiftOp(node, machine()->Word32Sar());
+ break;
+ }
+ case IrOpcode::kUint32x4ShiftRightByScalar: {
+ LowerShiftOp(node, machine()->Word32Shr());
+ break;
+ }
#define F32X4_BINOP_CASE(name) \
case IrOpcode::kFloat32x4##name: { \
LowerBinaryOp(node, rep_type, machine()->Float32##name()); \
« no previous file with comments | « src/compiler/simd-scalar-lowering.h ('k') | src/compiler/wasm-compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698