Reviewers: Sven Panne,

Description:
[turbofan] Recursively reduce new inputs of changed nodes.

The GraphReducer should recurse into new inputs after a node was
changed. Most of the reducers already assume this behavior, and it
mostly worked by accident in many cases.

[email protected]

Please review this at https://codereview.chromium.org/800073004/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+41, -29 lines):
  M src/compiler/graph-reducer.cc


Index: src/compiler/graph-reducer.cc
diff --git a/src/compiler/graph-reducer.cc b/src/compiler/graph-reducer.cc
index 1f56b302edce5a180599b2b925b178034c11f98a..9a6b121ffbd224d2fe0e8bfed002fcf4ce312039 100644
--- a/src/compiler/graph-reducer.cc
+++ b/src/compiler/graph-reducer.cc
@@ -118,40 +118,52 @@ void GraphReducer::ReduceTop() {
   // All inputs should be visited or on stack. Apply reductions to node.
   Reduction reduction = Reduce(node);

+  // If there was no reduction, pop {node} and continue.
+  if (!reduction.Changed()) return Pop();
+
+  // Check if the reduction is an in-place update of the {node}.
+  Node* const replacement = reduction.replacement();
+  if (replacement == node) {
+    // In-place update of {node}, may need to recurse on an input.
+    for (int i = 0; i < node->InputCount(); ++i) {
+      Node* input = node->InputAt(i);
+      entry.input_index = i + 1;
+      if (input != node && Recurse(input)) return;
+    }
+  }
+
   // After reducing the node, pop it off the stack.
   Pop();

-  // If there was a reduction, revisit the uses and reduce the replacement.
-  if (reduction.Changed()) {
-    for (Node* const use : node->uses()) {
-      // Don't revisit this node if it refers to itself.
-      if (use != node) Revisit(use);
-    }
-    Node* const replacement = reduction.replacement();
-    if (replacement != node) {
-      if (node == graph()->start()) graph()->SetStart(replacement);
-      if (node == graph()->end()) graph()->SetEnd(replacement);
- // If {node} was replaced by an old node, unlink {node} and assume that
-      // {replacement} was already reduced and finish.
-      if (replacement->id() < node_count) {
-        node->ReplaceUses(replacement);
+  // Revisit all uses of the node.
+  for (Node* const use : node->uses()) {
+    // Don't revisit this node if it refers to itself.
+    if (use != node) Revisit(use);
+  }
+
+  // Check if we have a new replacement.
+  if (replacement != node) {
+    if (node == graph()->start()) graph()->SetStart(replacement);
+    if (node == graph()->end()) graph()->SetEnd(replacement);
+    // If {node} was replaced by an old node, unlink {node} and assume that
+    // {replacement} was already reduced and finish.
+    if (replacement->id() < node_count) {
+      node->ReplaceUses(replacement);
+      node->Kill();
+    } else {
+ // Otherwise {node} was replaced by a new node. Replace all old uses of
+      // {node} with {replacement}. New nodes created by this reduction can
+      // use {node}.
+      node->ReplaceUsesIf(
+ [node_count](Node* const node) { return node->id() < node_count; },
+          replacement);
+      // Unlink {node} if it's no longer used.
+      if (node->uses().empty()) {
         node->Kill();
-      } else {
- // Otherwise {node} was replaced by a new node. Replace all old uses of - // {node} with {replacement}. New nodes created by this reduction can
-        // use {node}.
-        node->ReplaceUsesIf([node_count](Node* const node) {
-                              return node->id() < node_count;
-                            },
-                            replacement);
-        // Unlink {node} if it's no longer used.
-        if (node->uses().empty()) {
-          node->Kill();
-        }
-
-        // If there was a replacement, reduce it after popping {node}.
-        Recurse(replacement);
       }
+
+      // If there was a replacement, reduce it after popping {node}.
+      Recurse(replacement);
     }
   }
 }


--
--
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