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

Unified 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 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.h » ('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 c5a94b4297e35d39d40714caf6bff06d9cf87554..277d80b58aab971fa69d387671d16aaa33ca910c 100644
--- a/src/compiler/simd-scalar-lowering.cc
+++ b/src/compiler/simd-scalar-lowering.cc
@@ -58,6 +58,9 @@ void SimdScalarLowering::LowerGraph() {
// that they are processed after all other nodes.
PreparePhiReplacement(input);
stack_.push_front({input, 0});
+ } else if (input->opcode() == IrOpcode::kEffectPhi ||
+ input->opcode() == IrOpcode::kLoop) {
+ stack_.push_front({input, 0});
} else {
stack_.push_back({input, 0});
}
@@ -70,12 +73,14 @@ void SimdScalarLowering::LowerGraph() {
#define FOREACH_INT32X4_OPCODE(V) \
V(Int32x4Add) \
V(Int32x4ExtractLane) \
- V(CreateInt32x4)
+ V(CreateInt32x4) \
+ V(Int32x4ReplaceLane)
#define FOREACH_FLOAT32X4_OPCODE(V) \
V(Float32x4Add) \
V(Float32x4ExtractLane) \
- V(CreateFloat32x4)
+ V(CreateFloat32x4) \
+ V(Float32x4ReplaceLane)
void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
switch (node->opcode()) {
@@ -102,7 +107,7 @@ static int GetParameterIndexAfterLowering(
// In function calls, the simd128 types are passed as 4 Int32 types. The
// parameters are typecast to the types as needed for various operations.
int result = old_index;
- for (int i = 0; i < old_index; i++) {
+ for (int i = 0; i < old_index; ++i) {
if (signature->GetParam(i) == MachineRepresentation::kSimd128) {
result += 3;
}
@@ -123,7 +128,7 @@ int SimdScalarLowering::GetParameterCountAfterLowering() {
static int GetReturnCountAfterLowering(
Signature<MachineRepresentation>* signature) {
int result = static_cast<int>(signature->return_count());
- for (int i = 0; i < static_cast<int>(signature->return_count()); i++) {
+ for (int i = 0; i < static_cast<int>(signature->return_count()); ++i) {
if (signature->GetReturn(i) == MachineRepresentation::kSimd128) {
result += 3;
}
@@ -131,6 +136,100 @@ static int GetReturnCountAfterLowering(
return result;
}
+void SimdScalarLowering::GetIndexNodes(Node* index, Node** new_indices) {
+ new_indices[0] = index;
+ for (size_t i = 1; i < kMaxLanes; ++i) {
+ new_indices[i] = graph()->NewNode(machine()->Int32Add(), index,
+ graph()->NewNode(common()->Int32Constant(
+ static_cast<int>(i) * kLaneWidth)));
+ }
+}
+
+void SimdScalarLowering::LowerLoadOp(MachineRepresentation rep, Node* node,
+ const Operator* load_op) {
+ if (rep == MachineRepresentation::kSimd128) {
+ Node* base = node->InputAt(0);
+ Node* index = node->InputAt(1);
+ Node* indices[kMaxLanes];
+ GetIndexNodes(index, indices);
+ Node* rep_nodes[kMaxLanes];
+ rep_nodes[0] = node;
+ NodeProperties::ChangeOp(rep_nodes[0], load_op);
+ if (node->InputCount() > 2) {
+ DCHECK(node->InputCount() > 3);
+ Node* effect_input = node->InputAt(2);
+ Node* control_input = node->InputAt(3);
+ rep_nodes[3] = graph()->NewNode(load_op, base, indices[3], effect_input,
+ control_input);
+ rep_nodes[2] = graph()->NewNode(load_op, base, indices[2], rep_nodes[3],
+ control_input);
+ rep_nodes[1] = graph()->NewNode(load_op, base, indices[1], rep_nodes[2],
+ control_input);
+ rep_nodes[0]->ReplaceInput(2, rep_nodes[1]);
+ } else {
+ for (size_t i = 1; i < kMaxLanes; ++i) {
+ rep_nodes[i] = graph()->NewNode(load_op, base, indices[i]);
+ }
+ }
+ ReplaceNode(node, rep_nodes);
+ } else {
+ DefaultLowering(node);
+ }
+}
+
+void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node,
+ const Operator* store_op,
+ SimdType rep_type) {
+ if (rep == MachineRepresentation::kSimd128) {
+ Node* base = node->InputAt(0);
+ Node* index = node->InputAt(1);
+ Node* indices[kMaxLanes];
+ GetIndexNodes(index, indices);
+ DCHECK(node->InputCount() > 2);
+ Node* value = node->InputAt(2);
+ DCHECK(HasReplacement(1, value));
+ Node* rep_nodes[kMaxLanes];
+ rep_nodes[0] = node;
+ Node** rep_inputs = GetReplacementsWithType(value, rep_type);
+ rep_nodes[0]->ReplaceInput(2, rep_inputs[0]);
+ NodeProperties::ChangeOp(node, store_op);
+ if (node->InputCount() > 3) {
+ DCHECK(node->InputCount() > 4);
+ Node* effect_input = node->InputAt(3);
+ Node* control_input = node->InputAt(4);
+ rep_nodes[3] = graph()->NewNode(store_op, base, indices[3], rep_inputs[3],
+ effect_input, control_input);
+ rep_nodes[2] = graph()->NewNode(store_op, base, indices[2], rep_inputs[2],
+ rep_nodes[3], control_input);
+ rep_nodes[1] = graph()->NewNode(store_op, base, indices[1], rep_inputs[1],
+ rep_nodes[2], control_input);
+ rep_nodes[0]->ReplaceInput(3, rep_nodes[1]);
+
+ } else {
+ for (size_t i = 1; i < kMaxLanes; ++i) {
+ rep_nodes[i] =
+ graph()->NewNode(store_op, base, indices[i], rep_inputs[i]);
+ }
+ }
+
+ ReplaceNode(node, rep_nodes);
+ } else {
+ DefaultLowering(node);
+ }
+}
+
+void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType 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_node[kMaxLanes];
+ for (int i = 0; i < kMaxLanes; ++i) {
+ rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]);
+ }
+ ReplaceNode(node, rep_node);
+}
+
void SimdScalarLowering::LowerNode(Node* node) {
SimdType rep_type = ReplacementType(node);
switch (node->opcode()) {
@@ -159,13 +258,13 @@ void SimdScalarLowering::LowerNode(Node* node) {
NodeProperties::ChangeOp(node, common()->Parameter(new_index));
Node* new_node[kMaxLanes];
- for (int i = 0; i < kMaxLanes; i++) {
+ for (int i = 0; i < kMaxLanes; ++i) {
new_node[i] = nullptr;
}
new_node[0] = node;
if (signature()->GetParam(old_index) ==
MachineRepresentation::kSimd128) {
- for (int i = 1; i < kMaxLanes; i++) {
+ for (int i = 1; i < kMaxLanes; ++i) {
new_node[i] = graph()->NewNode(common()->Parameter(new_index + i),
graph()->start());
}
@@ -175,6 +274,57 @@ void SimdScalarLowering::LowerNode(Node* node) {
}
break;
}
+ case IrOpcode::kLoad: {
+ MachineRepresentation rep =
+ LoadRepresentationOf(node->op()).representation();
+ const Operator* load_op;
+ if (rep_type == SimdType::kInt32) {
+ load_op = machine()->Load(MachineType::Int32());
+ } else if (rep_type == SimdType::kFloat32) {
+ load_op = machine()->Load(MachineType::Float32());
+ }
+ LowerLoadOp(rep, node, load_op);
+ break;
+ }
+ case IrOpcode::kUnalignedLoad: {
+ MachineRepresentation rep =
+ UnalignedLoadRepresentationOf(node->op()).representation();
+ const Operator* load_op;
+ if (rep_type == SimdType::kInt32) {
+ load_op = machine()->UnalignedLoad(MachineType::Int32());
+ } else if (rep_type == SimdType::kFloat32) {
+ load_op = machine()->UnalignedLoad(MachineType::Float32());
+ }
+ LowerLoadOp(rep, node, load_op);
+ break;
+ }
+ case IrOpcode::kStore: {
+ MachineRepresentation rep =
+ StoreRepresentationOf(node->op()).representation();
+ WriteBarrierKind write_barrier_kind =
+ StoreRepresentationOf(node->op()).write_barrier_kind();
+ const Operator* store_op;
+ if (rep_type == SimdType::kInt32) {
+ store_op = machine()->Store(StoreRepresentation(
+ MachineRepresentation::kWord32, write_barrier_kind));
+ } else {
+ store_op = machine()->Store(StoreRepresentation(
+ MachineRepresentation::kFloat32, write_barrier_kind));
+ }
+ LowerStoreOp(rep, node, store_op, rep_type);
+ break;
+ }
+ case IrOpcode::kUnalignedStore: {
+ MachineRepresentation rep = UnalignedStoreRepresentationOf(node->op());
+ const Operator* store_op;
+ if (rep_type == SimdType::kInt32) {
+ store_op = machine()->UnalignedStore(MachineRepresentation::kWord32);
+ } else {
+ store_op = machine()->UnalignedStore(MachineRepresentation::kFloat32);
+ }
+ LowerStoreOp(rep, node, store_op, rep_type);
+ break;
+ }
case IrOpcode::kReturn: {
DefaultLowering(node);
int new_return_count = GetReturnCountAfterLowering(signature());
@@ -200,7 +350,7 @@ void SimdScalarLowering::LowerNode(Node* node) {
descriptor->GetReturnType(0) == MachineType::Simd128()) {
// We access the additional return values through projections.
Node* rep_node[kMaxLanes];
- for (int i = 0; i < kMaxLanes; i++) {
+ for (int i = 0; i < kMaxLanes; ++i) {
rep_node[i] =
graph()->NewNode(common()->Projection(i), node, graph()->start());
}
@@ -214,7 +364,7 @@ void SimdScalarLowering::LowerNode(Node* node) {
// The replacement nodes have already been created, we only have to
// replace placeholder nodes.
Node** rep_node = GetReplacements(node);
- for (int i = 0; i < node->op()->ValueInputCount(); i++) {
+ for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
Node** rep_input =
GetReplacementsWithType(node->InputAt(i), rep_type);
for (int j = 0; j < kMaxLanes; j++) {
@@ -226,31 +376,29 @@ void SimdScalarLowering::LowerNode(Node* node) {
}
break;
}
-
case IrOpcode::kInt32x4Add: {
- DCHECK(node->InputCount() == 2);
- Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type);
- Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type);
- Node* rep_node[kMaxLanes];
- for (int i = 0; i < kMaxLanes; i++) {
- rep_node[i] =
- graph()->NewNode(machine()->Int32Add(), rep_left[i], rep_right[i]);
- }
- ReplaceNode(node, rep_node);
+ LowerBinaryOp(node, rep_type, machine()->Int32Add());
break;
}
-
- case IrOpcode::kCreateInt32x4: {
+ case IrOpcode::kFloat32x4Add: {
+ LowerBinaryOp(node, rep_type, machine()->Float32Add());
+ break;
+ }
+ case IrOpcode::kCreateInt32x4:
+ case IrOpcode::kCreateFloat32x4: {
Node* rep_node[kMaxLanes];
- for (int i = 0; i < kMaxLanes; i++) {
- DCHECK(!HasReplacement(1, node->InputAt(i)));
- rep_node[i] = node->InputAt(i);
+ for (int i = 0; i < kMaxLanes; ++i) {
+ if (HasReplacement(0, node->InputAt(i))) {
+ rep_node[i] = GetReplacements(node->InputAt(i))[0];
+ } else {
+ rep_node[i] = node->InputAt(i);
+ }
}
ReplaceNode(node, rep_node);
break;
}
-
- case IrOpcode::kInt32x4ExtractLane: {
+ case IrOpcode::kInt32x4ExtractLane:
+ case IrOpcode::kFloat32x4ExtractLane: {
Node* laneNode = node->InputAt(1);
DCHECK_EQ(laneNode->opcode(), IrOpcode::kInt32Constant);
int32_t lane = OpParameter<int32_t>(laneNode);
@@ -260,41 +408,23 @@ void SimdScalarLowering::LowerNode(Node* node) {
ReplaceNode(node, rep_node);
break;
}
-
- case IrOpcode::kFloat32x4Add: {
- DCHECK(node->InputCount() == 2);
- Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type);
- Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type);
- Node* rep_node[kMaxLanes];
- for (int i = 0; i < kMaxLanes; i++) {
- rep_node[i] = graph()->NewNode(machine()->Float32Add(), rep_left[i],
- rep_right[i]);
- }
- ReplaceNode(node, rep_node);
- break;
- }
-
- case IrOpcode::kCreateFloat32x4: {
- Node* rep_node[kMaxLanes];
- for (int i = 0; i < kMaxLanes; i++) {
- DCHECK(!HasReplacement(1, node->InputAt(i)));
- rep_node[i] = node->InputAt(i);
- }
- ReplaceNode(node, rep_node);
- break;
- }
-
- case IrOpcode::kFloat32x4ExtractLane: {
+ case IrOpcode::kInt32x4ReplaceLane:
+ case IrOpcode::kFloat32x4ReplaceLane: {
+ DCHECK_EQ(3, node->InputCount());
Node* laneNode = node->InputAt(1);
+ Node* repNode = node->InputAt(2);
DCHECK_EQ(laneNode->opcode(), IrOpcode::kInt32Constant);
int32_t lane = OpParameter<int32_t>(laneNode);
- Node* rep_node[kMaxLanes] = {
- GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr,
- nullptr, nullptr};
+ DCHECK(lane >= 0 && lane <= 3);
+ Node** rep_node = GetReplacementsWithType(node->InputAt(0), rep_type);
+ if (HasReplacement(0, repNode)) {
+ rep_node[lane] = GetReplacements(repNode)[0];
+ } else {
+ rep_node[lane] = repNode;
+ }
ReplaceNode(node, rep_node);
break;
}
-
default: { DefaultLowering(node); }
}
}
@@ -322,7 +452,7 @@ void SimdScalarLowering::ReplaceNode(Node* old, Node** new_node) {
DCHECK(new_node[0] != nullptr ||
(new_node[1] == nullptr && new_node[2] == nullptr &&
new_node[3] == nullptr));
- for (int i = 0; i < kMaxLanes; i++) {
+ for (int i = 0; i < kMaxLanes; ++i) {
replacements_[old->id()].node[i] = new_node[i];
}
}
@@ -348,7 +478,7 @@ Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) {
}
Node** result = zone()->NewArray<Node*>(kMaxLanes);
if (ReplacementType(node) == SimdType::kInt32 && type == SimdType::kFloat32) {
- for (int i = 0; i < kMaxLanes; i++) {
+ for (int i = 0; i < kMaxLanes; ++i) {
if (replacements[i] != nullptr) {
result[i] = graph()->NewNode(machine()->BitcastInt32ToFloat32(),
replacements[i]);
@@ -357,7 +487,7 @@ Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) {
}
}
} else {
- for (int i = 0; i < kMaxLanes; i++) {
+ for (int i = 0; i < kMaxLanes; ++i) {
if (replacements[i] != nullptr) {
result[i] = graph()->NewNode(machine()->BitcastFloat32ToInt32(),
replacements[i]);
@@ -379,17 +509,17 @@ void SimdScalarLowering::PreparePhiReplacement(Node* phi) {
int value_count = phi->op()->ValueInputCount();
SimdType type = ReplacementType(phi);
Node** inputs_rep[kMaxLanes];
- for (int i = 0; i < kMaxLanes; i++) {
+ for (int i = 0; i < kMaxLanes; ++i) {
inputs_rep[i] = zone()->NewArray<Node*>(value_count + 1);
inputs_rep[i][value_count] = NodeProperties::GetControlInput(phi, 0);
}
- for (int i = 0; i < value_count; i++) {
+ for (int i = 0; i < value_count; ++i) {
for (int j = 0; j < kMaxLanes; j++) {
inputs_rep[j][i] = placeholder_;
}
}
Node* rep_nodes[kMaxLanes];
- for (int i = 0; i < kMaxLanes; i++) {
+ for (int i = 0; i < kMaxLanes; ++i) {
if (type == SimdType::kInt32) {
rep_nodes[i] = graph()->NewNode(
common()->Phi(MachineRepresentation::kWord32, value_count),
« 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