Reviewers: jarin,
Description:
[turbofan] Remove unused diamonds during control reduction.
A diamond is unused if the Merge node has no Phi/EffectPhi uses, exactly
two inputs, one IfTrue and one IfFalse, which have the same Branch
control input and no other uses except for the Merge. In this case the
diamond can safely be removed.
[email protected]
Please review this at https://codereview.chromium.org/1000883003/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+56, -30 lines):
M src/compiler/control-reducer.cc
M test/cctest/compiler/test-control-reducer.cc
Index: src/compiler/control-reducer.cc
diff --git a/src/compiler/control-reducer.cc
b/src/compiler/control-reducer.cc
index
136064faa7424e7d04b1a3593299392258a0c9b4..df84d525a4e4da8ec39f939ccd995a49064e048b
100644
--- a/src/compiler/control-reducer.cc
+++ b/src/compiler/control-reducer.cc
@@ -507,8 +507,6 @@ class ControlReducerImpl {
index++;
}
- if (live > 1 && live == node->InputCount()) return node; // nothing
to do.
-
TRACE(("ReduceMerge: #%d:%s (%d live)\n", node->id(),
node->op()->mnemonic(), live));
@@ -527,15 +525,46 @@ class ControlReducerImpl {
return node->InputAt(live_index);
}
- // Edit phis in place, removing dead inputs and revisiting them.
- for (Node* const phi : phis) {
- TRACE((" PhiInMerge: #%d:%s (%d live)\n", phi->id(),
- phi->op()->mnemonic(), live));
- RemoveDeadInputs(node, phi);
- Revisit(phi);
+ DCHECK_LE(2, live);
+
+ if (live < node->InputCount()) {
+ // Edit phis in place, removing dead inputs and revisiting them.
+ for (Node* const phi : phis) {
+ TRACE((" PhiInMerge: #%d:%s (%d live)\n", phi->id(),
+ phi->op()->mnemonic(), live));
+ RemoveDeadInputs(node, phi);
+ Revisit(phi);
+ }
+ // Edit the merge in place, removing dead inputs.
+ RemoveDeadInputs(node, node);
+ }
+
+ DCHECK_EQ(live, node->InputCount());
+
+ // Check if it's an unused diamond.
+ if (live == 2 && phis.empty()) {
+ Node* node0 = node->InputAt(0);
+ Node* node1 = node->InputAt(1);
+ if (((node0->opcode() == IrOpcode::kIfTrue &&
+ node1->opcode() == IrOpcode::kIfFalse) ||
+ (node0->opcode() == IrOpcode::kIfTrue &&
+ node1->opcode() == IrOpcode::kIfFalse)) &&
+ node0->OwnedBy(node) && node1->OwnedBy(node)) {
+ Node* branch0 = NodeProperties::GetControlInput(node0);
+ Node* branch1 = NodeProperties::GetControlInput(node1);
+ if (branch0 == branch1) {
+ // It's a dead diamond, i.e. neither the IfTrue nor the IfFalse
nodes
+ // have users except for the Merge and the Merge has no Phi or
+ // EffectPhi uses, so replace the Merge with the control input
of the
+ // diamond.
+ TRACE((" DeadDiamond: #%d:%s #%d:%s #%d:%s\n", node0->id(),
+ node0->op()->mnemonic(), node1->id(),
node1->op()->mnemonic(),
+ branch0->id(), branch0->op()->mnemonic()));
+ return NodeProperties::GetControlInput(branch0);
+ }
+ }
}
- // Edit the merge in place, removing dead inputs.
- RemoveDeadInputs(node, node);
+
return node;
}
Index: test/cctest/compiler/test-control-reducer.cc
diff --git a/test/cctest/compiler/test-control-reducer.cc
b/test/cctest/compiler/test-control-reducer.cc
index
f0efb7ddcd12bfca484cbce344a9d273df62ba43..f6d354767e7f40de5a7b40987fefd18499d5c419
100644
--- a/test/cctest/compiler/test-control-reducer.cc
+++ b/test/cctest/compiler/test-control-reducer.cc
@@ -694,9 +694,9 @@ TEST(CMergeReduce_none1) {
TEST(CMergeReduce_none2) {
ControlReducerTester R;
- Node* t = R.graph.NewNode(R.common.IfTrue(), R.start);
- Node* f = R.graph.NewNode(R.common.IfFalse(), R.start);
- Node* merge = R.graph.NewNode(R.common.Merge(2), t, f);
+ Node* t1 = R.graph.NewNode(R.common.IfTrue(), R.start);
+ Node* t2 = R.graph.NewNode(R.common.IfTrue(), R.start);
+ Node* merge = R.graph.NewNode(R.common.Merge(2), t1, t2);
R.ReduceMerge(merge, merge);
}
@@ -744,7 +744,7 @@ TEST(CMergeReduce_dead_rm1b) {
ControlReducerTester R;
Node* t = R.graph.NewNode(R.common.IfTrue(), R.start);
- Node* f = R.graph.NewNode(R.common.IfFalse(), R.start);
+ Node* f = R.graph.NewNode(R.common.IfTrue(), R.start);
for (int i = 0; i < 2; i++) {
Node* merge = R.graph.NewNode(R.common.Merge(3), R.dead, R.dead,
R.dead);
for (int j = i + 1; j < 3; j++) {
@@ -1118,7 +1118,7 @@ TEST(CChainedDiamondsReduce_x_false) {
Diamond d2(R, R.zero);
d2.chain(d1);
- R.ReduceMergeIterative(d1.merge, d2.merge);
+ R.ReduceMergeIterative(R.start, d2.merge);
}
@@ -1128,8 +1128,7 @@ TEST(CChainedDiamondsReduce_false_x) {
Diamond d2(R, R.p0);
d2.chain(d1);
- R.ReduceMergeIterative(d2.merge, d2.merge);
- CheckInputs(d2.branch, R.p0, R.start);
+ R.ReduceMergeIterative(R.start, d2.merge);
}
@@ -1190,6 +1189,14 @@ TEST(CNestedDiamonds_xyz) {
}
+TEST(CDeadDiamond) {
+ ControlReducerTester R;
+ // if (p0) { } else { }
+ Diamond d(R, R.p0);
+ R.ReduceMergeIterative(R.start, d.merge);
+}
+
+
TEST(CDeadLoop1) {
ControlReducerTester R;
@@ -1329,9 +1336,7 @@ TEST(Return_nested_diamonds1) {
CheckInputs(ret, d1.phi, R.start, d1.merge);
CheckInputs(d1.phi, R.one, R.zero, d1.merge);
- CheckInputs(d1.merge, d2.merge, d3.merge);
- CheckLiveDiamond(d2);
- CheckLiveDiamond(d3);
+ CheckInputs(d1.merge, d1.if_true, d1.if_false);
}
@@ -1348,11 +1353,7 @@ TEST(Return_nested_diamonds_true1) {
R.ReduceGraph(); // d1 gets folded true.
- CheckInputs(ret, R.one, R.start, d2.merge);
- CheckInputs(d2.branch, R.p0, R.start);
- CheckDeadDiamond(d1);
- CheckLiveDiamond(d2);
- CheckDeadDiamond(d3);
+ CheckInputs(ret, R.one, R.start, R.start);
}
@@ -1369,11 +1370,7 @@ TEST(Return_nested_diamonds_false1) {
R.ReduceGraph(); // d1 gets folded false.
- CheckInputs(ret, R.zero, R.start, d3.merge);
- CheckInputs(d3.branch, R.p0, R.start);
- CheckDeadDiamond(d1);
- CheckDeadDiamond(d2);
- CheckLiveDiamond(d3);
+ CheckInputs(ret, R.zero, R.start, R.start);
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.