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.

Reply via email to