Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: src/compiler/graph-reducer.cc

Issue 1122423003: [turbofan] Add support for advanced reducers. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address Ben's comments Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <functional> 5 #include <functional>
6 6
7 #include "src/compiler/graph.h" 7 #include "src/compiler/graph.h"
8 #include "src/compiler/graph-reducer.h" 8 #include "src/compiler/graph-reducer.h"
9 #include "src/compiler/node.h" 9 #include "src/compiler/node.h"
10 10
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 namespace compiler { 13 namespace compiler {
14 14
15 bool Reducer::Finish() { return true; }
16
17
15 enum class GraphReducer::State : uint8_t { 18 enum class GraphReducer::State : uint8_t {
16 kUnvisited, 19 kUnvisited,
17 kRevisit, 20 kRevisit,
18 kOnStack, 21 kOnStack,
19 kVisited 22 kVisited
20 }; 23 };
21 24
22 25
23 GraphReducer::GraphReducer(Graph* graph, Zone* zone) 26 GraphReducer::GraphReducer(Graph* graph, Zone* zone)
24 : graph_(graph), 27 : graph_(graph),
25 state_(graph, 4), 28 state_(graph, 4),
26 reducers_(zone), 29 reducers_(zone),
27 revisit_(zone), 30 revisit_(zone),
28 stack_(zone) {} 31 stack_(zone) {}
29 32
30 33
34 GraphReducer::~GraphReducer() {}
35
36
31 void GraphReducer::AddReducer(Reducer* reducer) { 37 void GraphReducer::AddReducer(Reducer* reducer) {
32 reducers_.push_back(reducer); 38 reducers_.push_back(reducer);
33 } 39 }
34 40
35 41
36 void GraphReducer::ReduceNode(Node* node) { 42 void GraphReducer::ReduceNode(Node* node) {
37 DCHECK(stack_.empty()); 43 DCHECK(stack_.empty());
38 DCHECK(revisit_.empty()); 44 DCHECK(revisit_.empty());
39 Push(node); 45 Push(node);
40 for (;;) { 46 for (;;) {
(...skipping 11 matching lines...) Expand all
52 } 58 }
53 } else { 59 } else {
54 break; 60 break;
55 } 61 }
56 } 62 }
57 DCHECK(revisit_.empty()); 63 DCHECK(revisit_.empty());
58 DCHECK(stack_.empty()); 64 DCHECK(stack_.empty());
59 } 65 }
60 66
61 67
62 void GraphReducer::ReduceGraph() { ReduceNode(graph()->end()); } 68 void GraphReducer::ReduceGraph() {
69 for (;;) {
70 ReduceNode(graph()->end());
71 if (Finish()) break;
72 // Reset all marks on the graph in preparation to re-reduce the graph.
73 state_.Reset(graph());
74 }
75 }
63 76
64 77
65 Reduction GraphReducer::Reduce(Node* const node) { 78 Reduction GraphReducer::Reduce(Node* const node) {
66 auto skip = reducers_.end(); 79 auto skip = reducers_.end();
67 for (auto i = reducers_.begin(); i != reducers_.end();) { 80 for (auto i = reducers_.begin(); i != reducers_.end();) {
68 if (i != skip) { 81 if (i != skip) {
69 Reduction reduction = (*i)->Reduce(node); 82 Reduction reduction = (*i)->Reduce(node);
70 if (!reduction.Changed()) { 83 if (!reduction.Changed()) {
71 // No change from this reducer. 84 // No change from this reducer.
72 } else if (reduction.replacement() == node) { 85 } else if (reduction.replacement() == node) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 for (int i = 0; i < node->InputCount(); ++i) { 141 for (int i = 0; i < node->InputCount(); ++i) {
129 Node* input = node->InputAt(i); 142 Node* input = node->InputAt(i);
130 entry.input_index = i + 1; 143 entry.input_index = i + 1;
131 if (input != node && Recurse(input)) return; 144 if (input != node && Recurse(input)) return;
132 } 145 }
133 } 146 }
134 147
135 // After reducing the node, pop it off the stack. 148 // After reducing the node, pop it off the stack.
136 Pop(); 149 Pop();
137 150
138 // Revisit all uses of the node.
139 for (Node* const use : node->uses()) {
140 // Don't revisit this node if it refers to itself.
141 if (use != node) Revisit(use);
142 }
143
144 // Check if we have a new replacement. 151 // Check if we have a new replacement.
145 if (replacement != node) { 152 if (replacement != node) {
146 if (node == graph()->start()) graph()->SetStart(replacement);
147 if (node == graph()->end()) graph()->SetEnd(replacement);
148 // If {node} was replaced by an old node, unlink {node} and assume that 153 // If {node} was replaced by an old node, unlink {node} and assume that
149 // {replacement} was already reduced and finish. 154 // {replacement} was already reduced and finish.
150 if (replacement->id() < node_count) { 155 if (replacement->id() < node_count) {
151 node->ReplaceUses(replacement); 156 Replace(node, replacement);
152 node->Kill();
153 } else { 157 } else {
154 // Otherwise {node} was replaced by a new node. Replace all old uses of 158 // Otherwise {node} was replaced by a new node. Replace all old uses of
155 // {node} with {replacement}. New nodes created by this reduction can 159 // {node} with {replacement}. New nodes created by this reduction can
156 // use {node}. 160 // use {node}.
161 if (node == graph()->start()) graph()->SetStart(replacement);
162 if (node == graph()->end()) graph()->SetEnd(replacement);
157 for (Edge edge : node->use_edges()) { 163 for (Edge edge : node->use_edges()) {
158 if (edge.from()->id() < node_count) { 164 Node* const user = edge.from();
165 if (user->id() < node_count) {
159 edge.UpdateTo(replacement); 166 edge.UpdateTo(replacement);
167 // Don't revisit this node if it refers to itself.
168 if (user != node) Revisit(user);
160 } 169 }
161 } 170 }
162 // Unlink {node} if it's no longer used. 171 // Unlink {node} if it's no longer used.
163 if (node->uses().empty()) { 172 if (node->uses().empty()) node->Kill();
164 node->Kill();
165 }
166 173
167 // If there was a replacement, reduce it after popping {node}. 174 // If there was a replacement, reduce it after popping {node}.
168 Recurse(replacement); 175 Recurse(replacement);
169 } 176 }
177 } else {
178 // Revisit all uses of the node.
179 for (Node* const user : node->uses()) {
180 // Don't revisit this node if it refers to itself.
181 if (user != node) Revisit(user);
182 }
170 } 183 }
171 } 184 }
172 185
173 186
187 void GraphReducer::Replace(Node* node, Node* replacement) {
titzer 2015/05/06 09:22:08 I prefer the simplification in my other CL which m
Benedikt Meurer 2015/05/06 09:33:30 Done.
188 if (node == graph()->start()) graph()->SetStart(replacement);
189 if (node == graph()->end()) graph()->SetEnd(replacement);
190 for (Edge edge : node->use_edges()) {
191 Node* const user = edge.from();
192 edge.UpdateTo(replacement);
193 // Don't revisit this node if it refers to itself.
194 if (user != node) Revisit(user);
195 }
196 node->Kill();
197 }
198
199
174 void GraphReducer::Pop() { 200 void GraphReducer::Pop() {
175 Node* node = stack_.top().node; 201 Node* node = stack_.top().node;
176 state_.Set(node, State::kVisited); 202 state_.Set(node, State::kVisited);
177 stack_.pop(); 203 stack_.pop();
178 } 204 }
179 205
180 206
181 void GraphReducer::Push(Node* const node) { 207 void GraphReducer::Push(Node* const node) {
182 DCHECK(state_.Get(node) != State::kOnStack); 208 DCHECK(state_.Get(node) != State::kOnStack);
183 state_.Set(node, State::kOnStack); 209 state_.Set(node, State::kOnStack);
(...skipping 11 matching lines...) Expand all
195 void GraphReducer::Revisit(Node* node) { 221 void GraphReducer::Revisit(Node* node) {
196 if (state_.Get(node) == State::kVisited) { 222 if (state_.Get(node) == State::kVisited) {
197 state_.Set(node, State::kRevisit); 223 state_.Set(node, State::kRevisit);
198 revisit_.push(node); 224 revisit_.push(node);
199 } 225 }
200 } 226 }
201 227
202 } // namespace compiler 228 } // namespace compiler
203 } // namespace internal 229 } // namespace internal
204 } // namespace v8 230 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698