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.