OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/graph-reducer.h" | 5 #include "src/compiler/graph-reducer.h" |
6 | 6 |
7 #include <functional> | 7 #include <functional> |
8 | 8 |
9 #include "src/compiler/graph-inl.h" | 9 #include "src/compiler/graph-inl.h" |
10 | 10 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 entry.input_index = i + 1; | 111 entry.input_index = i + 1; |
112 if (input != node && Recurse(input)) return; | 112 if (input != node && Recurse(input)) return; |
113 } | 113 } |
114 | 114 |
115 // Remember the node count before reduction. | 115 // Remember the node count before reduction. |
116 const int node_count = graph()->NodeCount(); | 116 const int node_count = graph()->NodeCount(); |
117 | 117 |
118 // All inputs should be visited or on stack. Apply reductions to node. | 118 // All inputs should be visited or on stack. Apply reductions to node. |
119 Reduction reduction = Reduce(node); | 119 Reduction reduction = Reduce(node); |
120 | 120 |
| 121 // If there was no reduction, pop {node} and continue. |
| 122 if (!reduction.Changed()) return Pop(); |
| 123 |
| 124 // Check if the reduction is an in-place update of the {node}. |
| 125 Node* const replacement = reduction.replacement(); |
| 126 if (replacement == node) { |
| 127 // In-place update of {node}, may need to recurse on an input. |
| 128 for (int i = 0; i < node->InputCount(); ++i) { |
| 129 Node* input = node->InputAt(i); |
| 130 entry.input_index = i + 1; |
| 131 if (input != node && Recurse(input)) return; |
| 132 } |
| 133 } |
| 134 |
121 // After reducing the node, pop it off the stack. | 135 // After reducing the node, pop it off the stack. |
122 Pop(); | 136 Pop(); |
123 | 137 |
124 // If there was a reduction, revisit the uses and reduce the replacement. | 138 // Revisit all uses of the node. |
125 if (reduction.Changed()) { | 139 for (Node* const use : node->uses()) { |
126 for (Node* const use : node->uses()) { | 140 // Don't revisit this node if it refers to itself. |
127 // Don't revisit this node if it refers to itself. | 141 if (use != node) Revisit(use); |
128 if (use != node) Revisit(use); | 142 } |
129 } | 143 |
130 Node* const replacement = reduction.replacement(); | 144 // Check if we have a new replacement. |
131 if (replacement != node) { | 145 if (replacement != node) { |
132 if (node == graph()->start()) graph()->SetStart(replacement); | 146 if (node == graph()->start()) graph()->SetStart(replacement); |
133 if (node == graph()->end()) graph()->SetEnd(replacement); | 147 if (node == graph()->end()) graph()->SetEnd(replacement); |
134 // If {node} was replaced by an old node, unlink {node} and assume that | 148 // If {node} was replaced by an old node, unlink {node} and assume that |
135 // {replacement} was already reduced and finish. | 149 // {replacement} was already reduced and finish. |
136 if (replacement->id() < node_count) { | 150 if (replacement->id() < node_count) { |
137 node->ReplaceUses(replacement); | 151 node->ReplaceUses(replacement); |
| 152 node->Kill(); |
| 153 } else { |
| 154 // Otherwise {node} was replaced by a new node. Replace all old uses of |
| 155 // {node} with {replacement}. New nodes created by this reduction can |
| 156 // use {node}. |
| 157 node->ReplaceUsesIf( |
| 158 [node_count](Node* const node) { return node->id() < node_count; }, |
| 159 replacement); |
| 160 // Unlink {node} if it's no longer used. |
| 161 if (node->uses().empty()) { |
138 node->Kill(); | 162 node->Kill(); |
139 } else { | 163 } |
140 // Otherwise {node} was replaced by a new node. Replace all old uses of | |
141 // {node} with {replacement}. New nodes created by this reduction can | |
142 // use {node}. | |
143 node->ReplaceUsesIf([node_count](Node* const node) { | |
144 return node->id() < node_count; | |
145 }, | |
146 replacement); | |
147 // Unlink {node} if it's no longer used. | |
148 if (node->uses().empty()) { | |
149 node->Kill(); | |
150 } | |
151 | 164 |
152 // If there was a replacement, reduce it after popping {node}. | 165 // If there was a replacement, reduce it after popping {node}. |
153 Recurse(replacement); | 166 Recurse(replacement); |
154 } | |
155 } | 167 } |
156 } | 168 } |
157 } | 169 } |
158 | 170 |
159 | 171 |
160 void GraphReducer::Pop() { | 172 void GraphReducer::Pop() { |
161 Node* node = stack_.top().node; | 173 Node* node = stack_.top().node; |
162 state_.Set(node, State::kVisited); | 174 state_.Set(node, State::kVisited); |
163 stack_.pop(); | 175 stack_.pop(); |
164 } | 176 } |
(...skipping 16 matching lines...) Expand all Loading... |
181 void GraphReducer::Revisit(Node* node) { | 193 void GraphReducer::Revisit(Node* node) { |
182 if (state_.Get(node) == State::kVisited) { | 194 if (state_.Get(node) == State::kVisited) { |
183 state_.Set(node, State::kRevisit); | 195 state_.Set(node, State::kRevisit); |
184 revisit_.push(node); | 196 revisit_.push(node); |
185 } | 197 } |
186 } | 198 } |
187 | 199 |
188 } // namespace compiler | 200 } // namespace compiler |
189 } // namespace internal | 201 } // namespace internal |
190 } // namespace v8 | 202 } // namespace v8 |
OLD | NEW |