| 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/v8.h" | 5 #include "src/v8.h" |
| 6 #include "test/cctest/cctest.h" | 6 #include "test/cctest/cctest.h" |
| 7 | 7 |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/compiler/all-nodes.h" | 9 #include "src/compiler/all-nodes.h" |
| 10 #include "src/compiler/common-operator.h" | 10 #include "src/compiler/common-operator.h" |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 } | 136 } |
| 137 return node; | 137 return node; |
| 138 } | 138 } |
| 139 | 139 |
| 140 const Operator* op(int count, bool effect) { | 140 const Operator* op(int count, bool effect) { |
| 141 return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count); | 141 return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count); |
| 142 } | 142 } |
| 143 | 143 |
| 144 void ReduceGraph() { ControlReducer::ReduceGraph(main_zone(), &jsgraph); } | 144 void ReduceGraph() { ControlReducer::ReduceGraph(main_zone(), &jsgraph); } |
| 145 | 145 |
| 146 // Checks one-step reduction of a phi. | |
| 147 void ReducePhi(Node* expect, Node* phi) { | |
| 148 Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, phi); | |
| 149 CHECK_EQ(expect, result); | |
| 150 ReducePhiIterative(expect, phi); // iterative should give the same result. | |
| 151 } | |
| 152 | |
| 153 // Checks one-step reduction of a phi. | |
| 154 void ReducePhiNonIterative(Node* expect, Node* phi) { | |
| 155 Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, phi); | |
| 156 CHECK_EQ(expect, result); | |
| 157 } | |
| 158 | |
| 159 void ReducePhiIterative(Node* expect, Node* phi) { | |
| 160 p0->ReplaceInput(0, start); // hack: parameters may be trimmed. | |
| 161 Node* ret = graph.NewNode(common.Return(), phi, start, start); | |
| 162 Node* end = graph.NewNode(common.End(1), ret); | |
| 163 graph.SetEnd(end); | |
| 164 ControlReducer::ReduceGraph(main_zone(), &jsgraph); | |
| 165 CheckInputs(end, ret); | |
| 166 CheckInputs(ret, expect, start, start); | |
| 167 } | |
| 168 | |
| 169 void ReduceMerge(Node* expect, Node* merge) { | 146 void ReduceMerge(Node* expect, Node* merge) { |
| 170 Node* result = ControlReducer::ReduceMerge(&jsgraph, merge); | 147 Node* result = ControlReducer::ReduceMerge(&jsgraph, merge); |
| 171 CHECK_EQ(expect, result); | 148 CHECK_EQ(expect, result); |
| 172 } | 149 } |
| 173 | 150 |
| 174 void ReduceMergeIterative(Node* expect, Node* merge) { | 151 void ReduceMergeIterative(Node* expect, Node* merge) { |
| 175 p0->ReplaceInput(0, start); // hack: parameters may be trimmed. | 152 p0->ReplaceInput(0, start); // hack: parameters may be trimmed. |
| 176 Node* end = graph.NewNode(common.End(1), merge); | 153 Node* end = graph.NewNode(common.End(1), merge); |
| 177 graph.SetEnd(end); | 154 graph.SetEnd(end); |
| 178 ReduceGraph(); | 155 ReduceGraph(); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 CHECK_EQ(3, d.phi->InputCount()); | 283 CHECK_EQ(3, d.phi->InputCount()); |
| 307 CHECK_EQ(d.merge, d.phi->InputAt(2)); | 284 CHECK_EQ(d.merge, d.phi->InputAt(2)); |
| 308 } else { | 285 } else { |
| 309 Check(d.phi); | 286 Check(d.phi); |
| 310 } | 287 } |
| 311 } | 288 } |
| 312 } | 289 } |
| 313 }; | 290 }; |
| 314 | 291 |
| 315 | 292 |
| 316 TEST(CReducePhi1) { | |
| 317 ControlReducerTester R; | |
| 318 | |
| 319 R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0])); | |
| 320 R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1])); | |
| 321 R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2])); | |
| 322 R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3])); | |
| 323 } | |
| 324 | |
| 325 | |
| 326 TEST(CReducePhi1_dead) { | |
| 327 ControlReducerTester R; | |
| 328 | |
| 329 R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead)); | |
| 330 R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1], R.dead)); | |
| 331 R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2], R.dead)); | |
| 332 R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3], R.dead)); | |
| 333 | |
| 334 R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0])); | |
| 335 R.ReducePhi(R.leaf[1], R.Phi(R.dead, R.leaf[1])); | |
| 336 R.ReducePhi(R.leaf[2], R.Phi(R.dead, R.leaf[2])); | |
| 337 R.ReducePhi(R.leaf[3], R.Phi(R.dead, R.leaf[3])); | |
| 338 } | |
| 339 | |
| 340 | |
| 341 TEST(CReducePhi1_dead2) { | |
| 342 ControlReducerTester R; | |
| 343 | |
| 344 R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead, R.dead)); | |
| 345 R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0], R.dead)); | |
| 346 R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.dead, R.leaf[0])); | |
| 347 } | |
| 348 | |
| 349 | |
| 350 TEST(CReducePhi2a) { | |
| 351 ControlReducerTester R; | |
| 352 | |
| 353 for (size_t i = 0; i < kNumLeafs; i++) { | |
| 354 Node* a = R.leaf[i]; | |
| 355 R.ReducePhi(a, R.Phi(a, a)); | |
| 356 } | |
| 357 } | |
| 358 | |
| 359 | |
| 360 TEST(CReducePhi2b) { | |
| 361 ControlReducerTester R; | |
| 362 | |
| 363 for (size_t i = 0; i < kNumLeafs; i++) { | |
| 364 Node* a = R.leaf[i]; | |
| 365 R.ReducePhi(a, R.Phi(R.self, a)); | |
| 366 R.ReducePhi(a, R.Phi(a, R.self)); | |
| 367 } | |
| 368 } | |
| 369 | |
| 370 | |
| 371 TEST(CReducePhi2c) { | |
| 372 ControlReducerTester R; | |
| 373 | |
| 374 for (size_t i = 1; i < kNumLeafs; i++) { | |
| 375 Node* a = R.leaf[i], *b = R.leaf[0]; | |
| 376 Node* phi1 = R.Phi(b, a); | |
| 377 R.ReducePhi(phi1, phi1); | |
| 378 | |
| 379 Node* phi2 = R.Phi(a, b); | |
| 380 R.ReducePhi(phi2, phi2); | |
| 381 } | |
| 382 } | |
| 383 | |
| 384 | |
| 385 TEST(CReducePhi2_dead) { | |
| 386 ControlReducerTester R; | |
| 387 | |
| 388 for (size_t i = 0; i < kNumLeafs; i++) { | |
| 389 Node* a = R.leaf[i]; | |
| 390 R.ReducePhi(a, R.Phi(a, a, R.dead)); | |
| 391 R.ReducePhi(a, R.Phi(a, R.dead, a)); | |
| 392 R.ReducePhi(a, R.Phi(R.dead, a, a)); | |
| 393 } | |
| 394 | |
| 395 for (size_t i = 0; i < kNumLeafs; i++) { | |
| 396 Node* a = R.leaf[i]; | |
| 397 R.ReducePhi(a, R.Phi(R.self, a)); | |
| 398 R.ReducePhi(a, R.Phi(a, R.self)); | |
| 399 R.ReducePhi(a, R.Phi(R.self, a, R.dead)); | |
| 400 R.ReducePhi(a, R.Phi(a, R.self, R.dead)); | |
| 401 } | |
| 402 | |
| 403 for (size_t i = 1; i < kNumLeafs; i++) { | |
| 404 Node* a = R.leaf[i], *b = R.leaf[0]; | |
| 405 Node* phi1 = R.Phi(b, a, R.dead); | |
| 406 R.ReducePhiNonIterative(phi1, phi1); | |
| 407 | |
| 408 Node* phi2 = R.Phi(a, b, R.dead); | |
| 409 R.ReducePhiNonIterative(phi2, phi2); | |
| 410 } | |
| 411 } | |
| 412 | |
| 413 | |
| 414 TEST(CReducePhi3) { | |
| 415 ControlReducerTester R; | |
| 416 | |
| 417 for (size_t i = 0; i < kNumLeafs; i++) { | |
| 418 Node* a = R.leaf[i]; | |
| 419 R.ReducePhi(a, R.Phi(a, a, a)); | |
| 420 } | |
| 421 | |
| 422 for (size_t i = 0; i < kNumLeafs; i++) { | |
| 423 Node* a = R.leaf[i]; | |
| 424 R.ReducePhi(a, R.Phi(R.self, a, a)); | |
| 425 R.ReducePhi(a, R.Phi(a, R.self, a)); | |
| 426 R.ReducePhi(a, R.Phi(a, a, R.self)); | |
| 427 } | |
| 428 | |
| 429 for (size_t i = 1; i < kNumLeafs; i++) { | |
| 430 Node* a = R.leaf[i], *b = R.leaf[0]; | |
| 431 Node* phi1 = R.Phi(b, a, a); | |
| 432 R.ReducePhi(phi1, phi1); | |
| 433 | |
| 434 Node* phi2 = R.Phi(a, b, a); | |
| 435 R.ReducePhi(phi2, phi2); | |
| 436 | |
| 437 Node* phi3 = R.Phi(a, a, b); | |
| 438 R.ReducePhi(phi3, phi3); | |
| 439 } | |
| 440 } | |
| 441 | |
| 442 | |
| 443 TEST(CReducePhi4) { | |
| 444 ControlReducerTester R; | |
| 445 | |
| 446 for (size_t i = 0; i < kNumLeafs; i++) { | |
| 447 Node* a = R.leaf[i]; | |
| 448 R.ReducePhi(a, R.Phi(a, a, a, a)); | |
| 449 } | |
| 450 | |
| 451 for (size_t i = 0; i < kNumLeafs; i++) { | |
| 452 Node* a = R.leaf[i]; | |
| 453 R.ReducePhi(a, R.Phi(R.self, a, a, a)); | |
| 454 R.ReducePhi(a, R.Phi(a, R.self, a, a)); | |
| 455 R.ReducePhi(a, R.Phi(a, a, R.self, a)); | |
| 456 R.ReducePhi(a, R.Phi(a, a, a, R.self)); | |
| 457 | |
| 458 R.ReducePhi(a, R.Phi(R.self, R.self, a, a)); | |
| 459 R.ReducePhi(a, R.Phi(a, R.self, R.self, a)); | |
| 460 R.ReducePhi(a, R.Phi(a, a, R.self, R.self)); | |
| 461 R.ReducePhi(a, R.Phi(R.self, a, a, R.self)); | |
| 462 } | |
| 463 | |
| 464 for (size_t i = 1; i < kNumLeafs; i++) { | |
| 465 Node* a = R.leaf[i], *b = R.leaf[0]; | |
| 466 Node* phi1 = R.Phi(b, a, a, a); | |
| 467 R.ReducePhi(phi1, phi1); | |
| 468 | |
| 469 Node* phi2 = R.Phi(a, b, a, a); | |
| 470 R.ReducePhi(phi2, phi2); | |
| 471 | |
| 472 Node* phi3 = R.Phi(a, a, b, a); | |
| 473 R.ReducePhi(phi3, phi3); | |
| 474 | |
| 475 Node* phi4 = R.Phi(a, a, a, b); | |
| 476 R.ReducePhi(phi4, phi4); | |
| 477 } | |
| 478 } | |
| 479 | |
| 480 | |
| 481 TEST(CReducePhi_iterative1) { | |
| 482 ControlReducerTester R; | |
| 483 | |
| 484 R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0]))); | |
| 485 R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.leaf[0])); | |
| 486 } | |
| 487 | |
| 488 | |
| 489 TEST(CReducePhi_iterative2) { | |
| 490 ControlReducerTester R; | |
| 491 | |
| 492 R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.Phi(R.leaf[0]))); | |
| 493 } | |
| 494 | |
| 495 | |
| 496 TEST(CReducePhi_iterative3) { | |
| 497 ControlReducerTester R; | |
| 498 | |
| 499 R.ReducePhiIterative(R.leaf[0], | |
| 500 R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.leaf[0]))); | |
| 501 R.ReducePhiIterative(R.leaf[0], | |
| 502 R.Phi(R.Phi(R.leaf[0], R.leaf[0]), R.leaf[0])); | |
| 503 } | |
| 504 | |
| 505 | |
| 506 TEST(CReducePhi_iterative4) { | |
| 507 ControlReducerTester R; | |
| 508 | |
| 509 R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.leaf[0]), | |
| 510 R.Phi(R.leaf[0], R.leaf[0]))); | |
| 511 | |
| 512 Node* p1 = R.Phi(R.leaf[0], R.leaf[0]); | |
| 513 R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1)); | |
| 514 | |
| 515 Node* p2 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]); | |
| 516 R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2, p2)); | |
| 517 | |
| 518 Node* p3 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]); | |
| 519 R.ReducePhiIterative(R.leaf[0], R.Phi(p3, p3, R.leaf[0])); | |
| 520 } | |
| 521 | |
| 522 | |
| 523 TEST(CReducePhi_iterative_self1) { | |
| 524 ControlReducerTester R; | |
| 525 | |
| 526 R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.self))); | |
| 527 R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.leaf[0])); | |
| 528 } | |
| 529 | |
| 530 | |
| 531 TEST(CReducePhi_iterative_self2) { | |
| 532 ControlReducerTester R; | |
| 533 | |
| 534 R.ReducePhiIterative( | |
| 535 R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.Phi(R.leaf[0], R.self))); | |
| 536 R.ReducePhiIterative( | |
| 537 R.leaf[0], R.Phi(R.Phi(R.self, R.leaf[0]), R.Phi(R.self, R.leaf[0]))); | |
| 538 | |
| 539 Node* p1 = R.Phi(R.leaf[0], R.self); | |
| 540 R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1)); | |
| 541 | |
| 542 Node* p2 = R.Phi(R.self, R.leaf[0]); | |
| 543 R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2)); | |
| 544 } | |
| 545 | |
| 546 | |
| 547 TEST(EReducePhi1) { | |
| 548 ControlReducerTester R; | |
| 549 | |
| 550 R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0])); | |
| 551 R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1])); | |
| 552 R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2])); | |
| 553 R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3])); | |
| 554 } | |
| 555 | |
| 556 | |
| 557 TEST(EReducePhi1_dead) { | |
| 558 ControlReducerTester R; | |
| 559 | |
| 560 R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead)); | |
| 561 R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1], R.dead)); | |
| 562 R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2], R.dead)); | |
| 563 R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3], R.dead)); | |
| 564 | |
| 565 R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0])); | |
| 566 R.ReducePhi(R.leaf[1], R.EffectPhi(R.dead, R.leaf[1])); | |
| 567 R.ReducePhi(R.leaf[2], R.EffectPhi(R.dead, R.leaf[2])); | |
| 568 R.ReducePhi(R.leaf[3], R.EffectPhi(R.dead, R.leaf[3])); | |
| 569 } | |
| 570 | |
| 571 | |
| 572 TEST(EReducePhi1_dead2) { | |
| 573 ControlReducerTester R; | |
| 574 | |
| 575 R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead, R.dead)); | |
| 576 R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0], R.dead)); | |
| 577 R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.dead, R.leaf[0])); | |
| 578 } | |
| 579 | |
| 580 | |
| 581 TEST(CMergeReduce_simple1) { | 293 TEST(CMergeReduce_simple1) { |
| 582 ControlReducerTester R; | 294 ControlReducerTester R; |
| 583 | 295 |
| 584 Node* merge = R.graph.NewNode(R.common.Merge(1), R.start); | 296 Node* merge = R.graph.NewNode(R.common.Merge(1), R.start); |
| 585 R.ReduceMerge(R.start, merge); | 297 R.ReduceMerge(R.start, merge); |
| 586 } | 298 } |
| 587 | 299 |
| 588 | 300 |
| 589 TEST(CMergeReduce_simple2) { | 301 TEST(CMergeReduce_simple2) { |
| 590 ControlReducerTester R; | 302 ControlReducerTester R; |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 TEST(CChainedDiamondsReduce_phi1) { | 687 TEST(CChainedDiamondsReduce_phi1) { |
| 976 ControlReducerTester R; | 688 ControlReducerTester R; |
| 977 Diamond d1(R, R.zero, R.one, R.zero); // foldable branch, phi. | 689 Diamond d1(R, R.zero, R.one, R.zero); // foldable branch, phi. |
| 978 Diamond d2(R, d1.phi); | 690 Diamond d2(R, d1.phi); |
| 979 d2.chain(d1); | 691 d2.chain(d1); |
| 980 | 692 |
| 981 R.ReduceMergeIterative(R.start, d2.merge); | 693 R.ReduceMergeIterative(R.start, d2.merge); |
| 982 } | 694 } |
| 983 | 695 |
| 984 | 696 |
| 985 TEST(CChainedDiamondsReduce_phi2) { | |
| 986 ControlReducerTester R; | |
| 987 Diamond d1(R, R.p0, R.jsgraph.TrueConstant(), | |
| 988 R.jsgraph.TrueConstant()); // redundant phi. | |
| 989 Diamond d2(R, d1.phi); | |
| 990 d2.chain(d1); | |
| 991 | |
| 992 R.ReduceMergeIterative(d1.merge, d2.merge); | |
| 993 } | |
| 994 | |
| 995 | |
| 996 TEST(CNestedDiamondsReduce_true_true_false) { | 697 TEST(CNestedDiamondsReduce_true_true_false) { |
| 997 ControlReducerTester R; | 698 ControlReducerTester R; |
| 998 Diamond d1(R, R.jsgraph.TrueConstant()); | 699 Diamond d1(R, R.jsgraph.TrueConstant()); |
| 999 Diamond d2(R, R.jsgraph.FalseConstant()); | 700 Diamond d2(R, R.jsgraph.FalseConstant()); |
| 1000 d2.nest(d1, true); | 701 d2.nest(d1, true); |
| 1001 | 702 |
| 1002 R.ReduceMergeIterative(R.start, d1.merge); | 703 R.ReduceMergeIterative(R.start, d1.merge); |
| 1003 } | 704 } |
| 1004 | 705 |
| 1005 | 706 |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 | 1110 |
| 1410 R.ReduceGraph(); // d1 gets folded true. | 1111 R.ReduceGraph(); // d1 gets folded true. |
| 1411 | 1112 |
| 1412 CheckInputs(ret, y2, R.start, R.start); | 1113 CheckInputs(ret, y2, R.start, R.start); |
| 1413 | 1114 |
| 1414 DeadChecker dead(&R.graph); | 1115 DeadChecker dead(&R.graph); |
| 1415 dead.Check(d1); | 1116 dead.Check(d1); |
| 1416 dead.Check(d2); | 1117 dead.Check(d2); |
| 1417 dead.Check(d3); | 1118 dead.Check(d3); |
| 1418 } | 1119 } |
| OLD | NEW |