[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. R=jarin@chromium.org Review URL: https://codereview.chromium.org/1000883003 Cr-Commit-Position: refs/heads/master@{#27148}
This commit is contained in:
parent
8329f04abe
commit
b5197ea478
@ -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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user