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..9ac1716a7eca5643dcc653f8aa7a5ea3d11d36a7 100644 |
--- a/src/compiler/simd-scalar-lowering.cc |
+++ b/src/compiler/simd-scalar-lowering.cc |
@@ -131,6 +131,15 @@ 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++) { |
Mircea Trofin
2016/11/15 16:21:27
++i
aseemgarg
2016/11/19 01:56:54
Done.
|
+ new_indices[i] = graph()->NewNode( |
+ machine()->Int32Add(), index, |
+ 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.
|
+ } |
+} |
+ |
void SimdScalarLowering::LowerNode(Node* node) { |
SimdType rep_type = ReplacementType(node); |
switch (node->opcode()) { |
@@ -175,6 +184,129 @@ void SimdScalarLowering::LowerNode(Node* node) { |
} |
break; |
} |
+ case IrOpcode::kLoad: |
+ case IrOpcode::kUnalignedLoad: { |
+ MachineRepresentation rep; |
+ if (node->opcode() == IrOpcode::kLoad) { |
+ rep = LoadRepresentationOf(node->op()).representation(); |
+ } else { |
+ DCHECK(node->opcode() == IrOpcode::kUnalignedLoad); |
+ rep = UnalignedLoadRepresentationOf(node->op()).representation(); |
+ } |
+ |
+ if (rep == MachineRepresentation::kSimd128) { |
+ Node* base = node->InputAt(0); |
+ Node* index = node->InputAt(1); |
+ Node* indices[kMaxLanes]; |
+ GetIndexNodes(index, indices); |
+ const Operator* load_op; |
+ 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.
|
+ load_op = machine()->Load(MachineType::Int32()); |
+ } else if (node->opcode() == IrOpcode::kLoad && |
+ rep_type == SimdType::kFloat32) { |
+ load_op = machine()->Load(MachineType::Float32()); |
+ } else if (node->opcode() == IrOpcode::kUnalignedLoad && |
+ rep_type == SimdType::kInt32) { |
+ load_op = machine()->UnalignedLoad(MachineType::Int32()); |
+ } else if (node->opcode() == IrOpcode::kUnalignedLoad && |
+ rep_type == SimdType::kFloat32) { |
+ load_op = machine()->UnalignedLoad(MachineType::Float32()); |
+ } |
+ |
+ Node* rep_nodes[kMaxLanes]; |
+ rep_nodes[0] = node; |
+ NodeProperties::ChangeOp(rep_nodes[0], load_op); |
+ if (node->InputCount() > 2) { |
+ Node* effect_high = node->InputAt(2); |
+ 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
|
+ 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.
|
+ effect_high, control_high); |
+ rep_nodes[2] = graph()->NewNode(load_op, base, indices[2], |
+ rep_nodes[3], control_high); |
+ rep_nodes[1] = graph()->NewNode(load_op, base, indices[1], |
+ rep_nodes[2], control_high); |
+ rep_nodes[0]->ReplaceInput(2, rep_nodes[1]); |
+ } else { |
+ 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.
|
+ rep_nodes[i] = graph()->NewNode(load_op, base, indices[i]); |
+ } |
+ } |
+ ReplaceNode(node, rep_nodes); |
+ } else { |
+ DefaultLowering(node); |
+ } |
+ break; |
+ } |
+ case IrOpcode::kStore: |
+ case IrOpcode::kUnalignedStore: { |
+ MachineRepresentation rep; |
+ if (node->opcode() == IrOpcode::kStore) { |
+ rep = StoreRepresentationOf(node->op()).representation(); |
+ } else { |
+ DCHECK(node->opcode() == IrOpcode::kUnalignedStore); |
+ rep = UnalignedStoreRepresentationOf(node->op()); |
+ } |
+ |
+ if (rep == MachineRepresentation::kSimd128) { |
+ Node* base = node->InputAt(0); |
+ Node* index = node->InputAt(1); |
+ Node* indices[4]; |
Mircea Trofin
2016/11/15 16:21:26
what's "4"?
aseemgarg
2016/11/19 01:56:54
changed to kMaxLanes
|
+ GetIndexNodes(index, indices); |
+ 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.
|
+ DCHECK(HasReplacement(1, value)); |
+ const Operator* store_op; |
+ if (node->opcode() == IrOpcode::kStore) { |
+ WriteBarrierKind write_barrier_kind = |
+ StoreRepresentationOf(node->op()).write_barrier_kind(); |
+ 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)); |
+ } |
+ } else { |
+ if (rep_type == SimdType::kInt32) { |
+ store_op = |
+ machine()->UnalignedStore(MachineRepresentation::kWord32); |
+ } else { |
+ store_op = |
+ machine()->UnalignedStore(MachineRepresentation::kFloat32); |
+ } |
+ } |
+ |
+ 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) { |
+ 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.
|
+ Node* control_high = node->InputAt(4); |
+ rep_nodes[3] = |
+ graph()->NewNode(store_op, base, indices[3], rep_inputs[3], |
+ effect_high, control_high); |
+ rep_nodes[2] = |
+ graph()->NewNode(store_op, base, indices[2], rep_inputs[2], |
+ rep_nodes[3], control_high); |
+ rep_nodes[1] = |
+ graph()->NewNode(store_op, base, indices[1], rep_inputs[1], |
+ rep_nodes[2], control_high); |
+ 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/
|
+ |
+ } 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); |
+ } |
+ break; |
+ } |
case IrOpcode::kReturn: { |
DefaultLowering(node); |
int new_return_count = GetReturnCountAfterLowering(signature()); |
@@ -226,31 +358,37 @@ 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); |
- break; |
- } |
- |
- case IrOpcode::kCreateInt32x4: { |
+#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.
|
+ case IrOpcode::opcode: { \ |
+ 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++) { \ |
Mircea Trofin
2016/11/15 16:21:27
++i
aseemgarg
2016/11/19 01:56:54
Done.
|
+ rep_node[i] = graph()->NewNode(machine()->replacementOp(), rep_left[i], \ |
+ rep_right[i]); \ |
+ } \ |
+ ReplaceNode(node, rep_node); \ |
+ break; \ |
+ } |
+ BINOP_CASE(kInt32x4Add, Int32Add) |
+ BINOP_CASE(kFloat32x4Add, Float32Add) |
+#undef BINOP |
+ case IrOpcode::kCreateInt32x4: |
+ case IrOpcode::kCreateFloat32x4: { |
Node* rep_node[kMaxLanes]; |
for (int i = 0; i < kMaxLanes; i++) { |
Mircea Trofin
2016/11/15 16:21:27
++i
aseemgarg
2016/11/19 01:56:54
Done.
|
- DCHECK(!HasReplacement(1, node->InputAt(i))); |
- rep_node[i] = node->InputAt(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 +398,21 @@ 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: { |
Node* laneNode = node->InputAt(1); |
+ 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.
|
DCHECK_EQ(laneNode->opcode(), IrOpcode::kInt32Constant); |
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.
|
- Node* rep_node[kMaxLanes] = { |
- GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr, |
- nullptr, nullptr}; |
+ 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); } |
} |
} |