| 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 |