OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <vector> | 5 #include <vector> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "graph-tester.h" | 9 #include "graph-tester.h" |
10 #include "src/compiler/common-operator.h" | 10 #include "src/compiler/common-operator.h" |
11 #include "src/compiler/generic-node.h" | 11 #include "src/compiler/generic-node.h" |
12 #include "src/compiler/generic-node-inl.h" | 12 #include "src/compiler/generic-node-inl.h" |
13 #include "src/compiler/graph.h" | 13 #include "src/compiler/graph.h" |
14 #include "src/compiler/graph-inl.h" | 14 #include "src/compiler/graph-inl.h" |
15 #include "src/compiler/graph-visualizer.h" | 15 #include "src/compiler/graph-visualizer.h" |
16 #include "src/compiler/operator.h" | 16 #include "src/compiler/operator.h" |
17 | 17 |
18 using namespace v8::internal; | 18 using namespace v8::internal; |
19 using namespace v8::internal::compiler; | 19 using namespace v8::internal::compiler; |
20 | 20 |
21 static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite, | 21 static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite, |
22 "dummy", 0, 0, 0, 1, 0, 0); | 22 "dummy", 0, 0, 0, 1, 0, 0); |
23 | 23 |
24 class PreNodeVisitor : public NullNodeVisitor { | 24 class PreNodeVisitor : public NullNodeVisitor { |
25 public: | 25 public: |
26 GenericGraphVisit::Control Pre(Node* node) { | 26 void Pre(Node* node) { |
27 printf("NODE ID: %d\n", node->id()); | 27 printf("NODE ID: %d\n", node->id()); |
28 nodes_.push_back(node); | 28 nodes_.push_back(node); |
29 return GenericGraphVisit::CONTINUE; | |
30 } | 29 } |
31 std::vector<Node*> nodes_; | 30 std::vector<Node*> nodes_; |
32 }; | 31 }; |
33 | 32 |
34 | 33 |
35 class PostNodeVisitor : public NullNodeVisitor { | 34 class PostNodeVisitor : public NullNodeVisitor { |
36 public: | 35 public: |
37 GenericGraphVisit::Control Post(Node* node) { | 36 void Post(Node* node) { |
38 printf("NODE ID: %d\n", node->id()); | 37 printf("NODE ID: %d\n", node->id()); |
39 nodes_.push_back(node); | 38 nodes_.push_back(node); |
40 return GenericGraphVisit::CONTINUE; | |
41 } | 39 } |
42 std::vector<Node*> nodes_; | 40 std::vector<Node*> nodes_; |
43 }; | 41 }; |
44 | 42 |
45 | 43 |
46 TEST(TestUseNodeVisitEmpty) { | 44 TEST(TestUseNodeVisitEmpty) { |
47 GraphWithStartNodeTester graph; | 45 GraphWithStartNodeTester graph; |
48 | 46 |
49 PreNodeVisitor node_visitor; | 47 PreNodeVisitor node_visitor; |
50 graph.VisitNodeUsesFromStart(&node_visitor); | 48 graph.VisitNodeUsesFromStart(&node_visitor); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 PreNodeVisitor node_visitor; | 164 PreNodeVisitor node_visitor; |
167 graph.VisitNodeUsesFromStart(&node_visitor); | 165 graph.VisitNodeUsesFromStart(&node_visitor); |
168 | 166 |
169 CHECK_EQ(3, static_cast<int>(node_visitor.nodes_.size())); | 167 CHECK_EQ(3, static_cast<int>(node_visitor.nodes_.size())); |
170 CHECK(n0->id() == node_visitor.nodes_[0]->id()); | 168 CHECK(n0->id() == node_visitor.nodes_[0]->id()); |
171 CHECK(n1->id() == node_visitor.nodes_[1]->id()); | 169 CHECK(n1->id() == node_visitor.nodes_[1]->id()); |
172 CHECK(n2->id() == node_visitor.nodes_[2]->id()); | 170 CHECK(n2->id() == node_visitor.nodes_[2]->id()); |
173 } | 171 } |
174 | 172 |
175 | 173 |
176 struct ReenterNodeVisitor : NullNodeVisitor { | |
177 GenericGraphVisit::Control Pre(Node* node) { | |
178 printf("[%d] PRE NODE: %d\n", static_cast<int>(nodes_.size()), node->id()); | |
179 nodes_.push_back(node->id()); | |
180 int size = static_cast<int>(nodes_.size()); | |
181 switch (node->id()) { | |
182 case 0: | |
183 return size < 6 ? GenericGraphVisit::REENTER : GenericGraphVisit::SKIP; | |
184 case 1: | |
185 return size < 4 ? GenericGraphVisit::DEFER | |
186 : GenericGraphVisit::CONTINUE; | |
187 default: | |
188 return GenericGraphVisit::REENTER; | |
189 } | |
190 } | |
191 | |
192 GenericGraphVisit::Control Post(Node* node) { | |
193 printf("[%d] POST NODE: %d\n", static_cast<int>(nodes_.size()), node->id()); | |
194 nodes_.push_back(-node->id()); | |
195 return node->id() == 4 ? GenericGraphVisit::REENTER | |
196 : GenericGraphVisit::CONTINUE; | |
197 } | |
198 | |
199 void PreEdge(Node* from, int index, Node* to) { | |
200 printf("[%d] PRE EDGE: %d-%d\n", static_cast<int>(edges_.size()), | |
201 from->id(), to->id()); | |
202 edges_.push_back(std::make_pair(from->id(), to->id())); | |
203 } | |
204 | |
205 void PostEdge(Node* from, int index, Node* to) { | |
206 printf("[%d] POST EDGE: %d-%d\n", static_cast<int>(edges_.size()), | |
207 from->id(), to->id()); | |
208 edges_.push_back(std::make_pair(-from->id(), -to->id())); | |
209 } | |
210 | |
211 std::vector<int> nodes_; | |
212 std::vector<std::pair<int, int> > edges_; | |
213 }; | |
214 | |
215 | |
216 TEST(TestUseNodeReenterVisit) { | |
217 GraphWithStartNodeTester graph; | |
218 Node* n0 = graph.start_node(); | |
219 Node* n1 = graph.NewNode(&dummy_operator, n0); | |
220 Node* n2 = graph.NewNode(&dummy_operator, n0); | |
221 Node* n3 = graph.NewNode(&dummy_operator, n2); | |
222 Node* n4 = graph.NewNode(&dummy_operator, n0); | |
223 Node* n5 = graph.NewNode(&dummy_operator, n4); | |
224 n0->AppendInput(graph.main_zone(), n3); | |
225 graph.SetStart(n0); | |
226 graph.SetEnd(n5); | |
227 | |
228 ReenterNodeVisitor visitor; | |
229 graph.VisitNodeUsesFromStart(&visitor); | |
230 | |
231 CHECK_EQ(22, static_cast<int>(visitor.nodes_.size())); | |
232 CHECK_EQ(24, static_cast<int>(visitor.edges_.size())); | |
233 | |
234 CHECK(n0->id() == visitor.nodes_[0]); | |
235 CHECK(n0->id() == visitor.edges_[0].first); | |
236 CHECK(n1->id() == visitor.edges_[0].second); | |
237 CHECK(n1->id() == visitor.nodes_[1]); | |
238 // N1 is deferred. | |
239 CHECK(-n1->id() == visitor.edges_[1].second); | |
240 CHECK(-n0->id() == visitor.edges_[1].first); | |
241 CHECK(n0->id() == visitor.edges_[2].first); | |
242 CHECK(n2->id() == visitor.edges_[2].second); | |
243 CHECK(n2->id() == visitor.nodes_[2]); | |
244 CHECK(n2->id() == visitor.edges_[3].first); | |
245 CHECK(n3->id() == visitor.edges_[3].second); | |
246 CHECK(n3->id() == visitor.nodes_[3]); | |
247 // Circle back to N0, which we may reenter for now. | |
248 CHECK(n3->id() == visitor.edges_[4].first); | |
249 CHECK(n0->id() == visitor.edges_[4].second); | |
250 CHECK(n0->id() == visitor.nodes_[4]); | |
251 CHECK(n0->id() == visitor.edges_[5].first); | |
252 CHECK(n1->id() == visitor.edges_[5].second); | |
253 CHECK(n1->id() == visitor.nodes_[5]); | |
254 // This time N1 is no longer deferred. | |
255 CHECK(-n1->id() == visitor.nodes_[6]); | |
256 CHECK(-n1->id() == visitor.edges_[6].second); | |
257 CHECK(-n0->id() == visitor.edges_[6].first); | |
258 CHECK(n0->id() == visitor.edges_[7].first); | |
259 CHECK(n2->id() == visitor.edges_[7].second); | |
260 CHECK(n2->id() == visitor.nodes_[7]); | |
261 CHECK(n2->id() == visitor.edges_[8].first); | |
262 CHECK(n3->id() == visitor.edges_[8].second); | |
263 CHECK(n3->id() == visitor.nodes_[8]); | |
264 CHECK(n3->id() == visitor.edges_[9].first); | |
265 CHECK(n0->id() == visitor.edges_[9].second); | |
266 CHECK(n0->id() == visitor.nodes_[9]); | |
267 // This time we break at N0 and skip it. | |
268 CHECK(-n0->id() == visitor.edges_[10].second); | |
269 CHECK(-n3->id() == visitor.edges_[10].first); | |
270 CHECK(-n3->id() == visitor.nodes_[10]); | |
271 CHECK(-n3->id() == visitor.edges_[11].second); | |
272 CHECK(-n2->id() == visitor.edges_[11].first); | |
273 CHECK(-n2->id() == visitor.nodes_[11]); | |
274 CHECK(-n2->id() == visitor.edges_[12].second); | |
275 CHECK(-n0->id() == visitor.edges_[12].first); | |
276 CHECK(n0->id() == visitor.edges_[13].first); | |
277 CHECK(n4->id() == visitor.edges_[13].second); | |
278 CHECK(n4->id() == visitor.nodes_[12]); | |
279 CHECK(n4->id() == visitor.edges_[14].first); | |
280 CHECK(n5->id() == visitor.edges_[14].second); | |
281 CHECK(n5->id() == visitor.nodes_[13]); | |
282 CHECK(-n5->id() == visitor.nodes_[14]); | |
283 CHECK(-n5->id() == visitor.edges_[15].second); | |
284 CHECK(-n4->id() == visitor.edges_[15].first); | |
285 CHECK(-n4->id() == visitor.nodes_[15]); | |
286 CHECK(-n4->id() == visitor.edges_[16].second); | |
287 CHECK(-n0->id() == visitor.edges_[16].first); | |
288 CHECK(-n0->id() == visitor.nodes_[16]); | |
289 CHECK(-n0->id() == visitor.edges_[17].second); | |
290 CHECK(-n3->id() == visitor.edges_[17].first); | |
291 CHECK(-n3->id() == visitor.nodes_[17]); | |
292 CHECK(-n3->id() == visitor.edges_[18].second); | |
293 CHECK(-n2->id() == visitor.edges_[18].first); | |
294 CHECK(-n2->id() == visitor.nodes_[18]); | |
295 CHECK(-n2->id() == visitor.edges_[19].second); | |
296 CHECK(-n0->id() == visitor.edges_[19].first); | |
297 // N4 may be reentered. | |
298 CHECK(n0->id() == visitor.edges_[20].first); | |
299 CHECK(n4->id() == visitor.edges_[20].second); | |
300 CHECK(n4->id() == visitor.nodes_[19]); | |
301 CHECK(n4->id() == visitor.edges_[21].first); | |
302 CHECK(n5->id() == visitor.edges_[21].second); | |
303 CHECK(-n5->id() == visitor.edges_[22].second); | |
304 CHECK(-n4->id() == visitor.edges_[22].first); | |
305 CHECK(-n4->id() == visitor.nodes_[20]); | |
306 CHECK(-n4->id() == visitor.edges_[23].second); | |
307 CHECK(-n0->id() == visitor.edges_[23].first); | |
308 CHECK(-n0->id() == visitor.nodes_[21]); | |
309 } | |
310 | |
311 | |
312 TEST(TestPrintNodeGraphToNodeGraphviz) { | 174 TEST(TestPrintNodeGraphToNodeGraphviz) { |
313 GraphWithStartNodeTester graph; | 175 GraphWithStartNodeTester graph; |
314 Node* n2 = graph.NewNode(&dummy_operator, graph.start()); | 176 Node* n2 = graph.NewNode(&dummy_operator, graph.start()); |
315 Node* n3 = graph.NewNode(&dummy_operator, graph.start()); | 177 Node* n3 = graph.NewNode(&dummy_operator, graph.start()); |
316 Node* n4 = graph.NewNode(&dummy_operator, n2); | 178 Node* n4 = graph.NewNode(&dummy_operator, n2); |
317 Node* n5 = graph.NewNode(&dummy_operator, n2); | 179 Node* n5 = graph.NewNode(&dummy_operator, n2); |
318 Node* n6 = graph.NewNode(&dummy_operator, n3); | 180 Node* n6 = graph.NewNode(&dummy_operator, n3); |
319 Node* n7 = graph.NewNode(&dummy_operator, n3); | 181 Node* n7 = graph.NewNode(&dummy_operator, n3); |
320 Node* n8 = graph.NewNode(&dummy_operator, n5); | 182 Node* n8 = graph.NewNode(&dummy_operator, n5); |
321 Node* n9 = graph.NewNode(&dummy_operator, n5); | 183 Node* n9 = graph.NewNode(&dummy_operator, n5); |
322 Node* n10 = graph.NewNode(&dummy_operator, n9); | 184 Node* n10 = graph.NewNode(&dummy_operator, n9); |
323 Node* n11 = graph.NewNode(&dummy_operator, n9); | 185 Node* n11 = graph.NewNode(&dummy_operator, n9); |
324 Node* end_dependencies[6] = {n4, n8, n10, n11, n6, n7}; | 186 Node* end_dependencies[6] = {n4, n8, n10, n11, n6, n7}; |
325 Node* n12 = graph.NewNode(&dummy_operator, 6, end_dependencies); | 187 Node* n12 = graph.NewNode(&dummy_operator, 6, end_dependencies); |
326 graph.SetEnd(n12); | 188 graph.SetEnd(n12); |
327 | 189 |
328 OFStream os(stdout); | 190 OFStream os(stdout); |
329 os << AsDOT(graph); | 191 os << AsDOT(graph); |
330 } | 192 } |
OLD | NEW |