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

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: Move comment 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
« no previous file with comments | « src/compiler/graph-reducer.h ('k') | src/compiler/node-marker.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include <limits>
6 7
7 #include "src/compiler/graph.h" 8 #include "src/compiler/graph.h"
8 #include "src/compiler/graph-reducer.h" 9 #include "src/compiler/graph-reducer.h"
9 #include "src/compiler/node.h" 10 #include "src/compiler/node.h"
10 11
11 namespace v8 { 12 namespace v8 {
12 namespace internal { 13 namespace internal {
13 namespace compiler { 14 namespace compiler {
14 15
16 bool Reducer::Finish() { return true; }
17
18
15 enum class GraphReducer::State : uint8_t { 19 enum class GraphReducer::State : uint8_t {
16 kUnvisited, 20 kUnvisited,
17 kRevisit, 21 kRevisit,
18 kOnStack, 22 kOnStack,
19 kVisited 23 kVisited
20 }; 24 };
21 25
22 26
23 GraphReducer::GraphReducer(Graph* graph, Zone* zone) 27 GraphReducer::GraphReducer(Graph* graph, Zone* zone)
24 : graph_(graph), 28 : graph_(graph),
25 state_(graph, 4), 29 state_(graph, 4),
26 reducers_(zone), 30 reducers_(zone),
27 revisit_(zone), 31 revisit_(zone),
28 stack_(zone) {} 32 stack_(zone) {}
29 33
30 34
35 GraphReducer::~GraphReducer() {}
36
37
31 void GraphReducer::AddReducer(Reducer* reducer) { 38 void GraphReducer::AddReducer(Reducer* reducer) {
32 reducers_.push_back(reducer); 39 reducers_.push_back(reducer);
33 } 40 }
34 41
35 42
36 void GraphReducer::ReduceNode(Node* node) { 43 void GraphReducer::ReduceNode(Node* node) {
37 DCHECK(stack_.empty()); 44 DCHECK(stack_.empty());
38 DCHECK(revisit_.empty()); 45 DCHECK(revisit_.empty());
39 Push(node); 46 Push(node);
40 for (;;) { 47 for (;;) {
(...skipping 11 matching lines...) Expand all
52 } 59 }
53 } else { 60 } else {
54 break; 61 break;
55 } 62 }
56 } 63 }
57 DCHECK(revisit_.empty()); 64 DCHECK(revisit_.empty());
58 DCHECK(stack_.empty()); 65 DCHECK(stack_.empty());
59 } 66 }
60 67
61 68
62 void GraphReducer::ReduceGraph() { ReduceNode(graph()->end()); } 69 void GraphReducer::ReduceGraph() {
70 for (;;) {
71 ReduceNode(graph()->end());
72 // TODO(turbofan): Remove this once the dead node trimming is in the
73 // GraphReducer.
74 bool done = true;
75 for (Reducer* const reducer : reducers_) {
76 if (!reducer->Finish()) {
77 done = false;
78 break;
79 }
80 }
81 if (done) break;
82 // Reset all marks on the graph in preparation to re-reduce the graph.
83 state_.Reset(graph());
84 }
85 }
63 86
64 87
65 Reduction GraphReducer::Reduce(Node* const node) { 88 Reduction GraphReducer::Reduce(Node* const node) {
66 auto skip = reducers_.end(); 89 auto skip = reducers_.end();
67 for (auto i = reducers_.begin(); i != reducers_.end();) { 90 for (auto i = reducers_.begin(); i != reducers_.end();) {
68 if (i != skip) { 91 if (i != skip) {
69 Reduction reduction = (*i)->Reduce(node); 92 Reduction reduction = (*i)->Reduce(node);
70 if (!reduction.Changed()) { 93 if (!reduction.Changed()) {
71 // No change from this reducer. 94 // No change from this reducer.
72 } else if (reduction.replacement() == node) { 95 } else if (reduction.replacement() == node) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 Node* input = node->InputAt(i); 128 Node* input = node->InputAt(i);
106 entry.input_index = i + 1; 129 entry.input_index = i + 1;
107 if (input != node && Recurse(input)) return; 130 if (input != node && Recurse(input)) return;
108 } 131 }
109 for (int i = 0; i < start; i++) { 132 for (int i = 0; i < start; i++) {
110 Node* input = node->InputAt(i); 133 Node* input = node->InputAt(i);
111 entry.input_index = i + 1; 134 entry.input_index = i + 1;
112 if (input != node && Recurse(input)) return; 135 if (input != node && Recurse(input)) return;
113 } 136 }
114 137
115 // Remember the node count before reduction. 138 // Remember the max node id before reduction.
116 const int node_count = graph()->NodeCount(); 139 NodeId const max_id = graph()->NodeCount() - 1;
117 140
118 // All inputs should be visited or on stack. Apply reductions to node. 141 // All inputs should be visited or on stack. Apply reductions to node.
119 Reduction reduction = Reduce(node); 142 Reduction reduction = Reduce(node);
120 143
121 // If there was no reduction, pop {node} and continue. 144 // If there was no reduction, pop {node} and continue.
122 if (!reduction.Changed()) return Pop(); 145 if (!reduction.Changed()) return Pop();
123 146
124 // Check if the reduction is an in-place update of the {node}. 147 // Check if the reduction is an in-place update of the {node}.
125 Node* const replacement = reduction.replacement(); 148 Node* const replacement = reduction.replacement();
126 if (replacement == node) { 149 if (replacement == node) {
127 // In-place update of {node}, may need to recurse on an input. 150 // In-place update of {node}, may need to recurse on an input.
128 for (int i = 0; i < node->InputCount(); ++i) { 151 for (int i = 0; i < node->InputCount(); ++i) {
129 Node* input = node->InputAt(i); 152 Node* input = node->InputAt(i);
130 entry.input_index = i + 1; 153 entry.input_index = i + 1;
131 if (input != node && Recurse(input)) return; 154 if (input != node && Recurse(input)) return;
132 } 155 }
133 } 156 }
134 157
135 // After reducing the node, pop it off the stack. 158 // After reducing the node, pop it off the stack.
136 Pop(); 159 Pop();
137 160
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. 161 // Check if we have a new replacement.
145 if (replacement != node) { 162 if (replacement != node) {
146 if (node == graph()->start()) graph()->SetStart(replacement); 163 Replace(node, replacement, max_id);
147 if (node == graph()->end()) graph()->SetEnd(replacement); 164 } else {
148 // If {node} was replaced by an old node, unlink {node} and assume that 165 // Revisit all uses of the node.
149 // {replacement} was already reduced and finish. 166 for (Node* const user : node->uses()) {
150 if (replacement->id() < node_count) { 167 // Don't revisit this node if it refers to itself.
151 node->ReplaceUses(replacement); 168 if (user != node) Revisit(user);
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 for (Edge edge : node->use_edges()) {
158 if (edge.from()->id() < node_count) {
159 edge.UpdateTo(replacement);
160 }
161 }
162 // Unlink {node} if it's no longer used.
163 if (node->uses().empty()) {
164 node->Kill();
165 }
166
167 // If there was a replacement, reduce it after popping {node}.
168 Recurse(replacement);
169 } 169 }
170 } 170 }
171 } 171 }
172 172
173
174 void GraphReducer::Replace(Node* node, Node* replacement) {
175 Replace(node, replacement, std::numeric_limits<NodeId>::max());
176 }
177
178
179 void GraphReducer::Replace(Node* node, Node* replacement, NodeId max_id) {
180 if (node == graph()->start()) graph()->SetStart(replacement);
181 if (node == graph()->end()) graph()->SetEnd(replacement);
182 if (replacement->id() <= max_id) {
183 // {replacement} is an old node, so unlink {node} and assume that
184 // {replacement} was already reduced and finish.
185 for (Edge edge : node->use_edges()) {
186 Node* const user = edge.from();
187 edge.UpdateTo(replacement);
188 // Don't revisit this node if it refers to itself.
189 if (user != node) Revisit(user);
190 }
191 node->Kill();
192 } else {
193 // Replace all old uses of {node} with {replacement}, but allow new nodes
194 // created by this reduction to use {node}.
195 for (Edge edge : node->use_edges()) {
196 Node* const user = edge.from();
197 if (user->id() <= max_id) {
198 edge.UpdateTo(replacement);
199 // Don't revisit this node if it refers to itself.
200 if (user != node) Revisit(user);
201 }
202 }
203 // Unlink {node} if it's no longer used.
204 if (node->uses().empty()) node->Kill();
205
206 // If there was a replacement, reduce it after popping {node}.
207 Recurse(replacement);
208 }
209 }
210
173 211
174 void GraphReducer::Pop() { 212 void GraphReducer::Pop() {
175 Node* node = stack_.top().node; 213 Node* node = stack_.top().node;
176 state_.Set(node, State::kVisited); 214 state_.Set(node, State::kVisited);
177 stack_.pop(); 215 stack_.pop();
178 } 216 }
179 217
180 218
181 void GraphReducer::Push(Node* const node) { 219 void GraphReducer::Push(Node* const node) {
182 DCHECK(state_.Get(node) != State::kOnStack); 220 DCHECK(state_.Get(node) != State::kOnStack);
(...skipping 12 matching lines...) Expand all
195 void GraphReducer::Revisit(Node* node) { 233 void GraphReducer::Revisit(Node* node) {
196 if (state_.Get(node) == State::kVisited) { 234 if (state_.Get(node) == State::kVisited) {
197 state_.Set(node, State::kRevisit); 235 state_.Set(node, State::kRevisit);
198 revisit_.push(node); 236 revisit_.push(node);
199 } 237 }
200 } 238 }
201 239
202 } // namespace compiler 240 } // namespace compiler
203 } // namespace internal 241 } // namespace internal
204 } // namespace v8 242 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/graph-reducer.h ('k') | src/compiler/node-marker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698