| 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/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
| 9 #include "src/compiler/generic-node-inl.h" | 9 #include "src/compiler/generic-node-inl.h" |
| 10 #include "src/compiler/generic-node.h" | 10 #include "src/compiler/generic-node.h" |
| 11 #include "src/compiler/graph.h" | 11 #include "src/compiler/graph.h" |
| 12 #include "src/compiler/graph-visualizer.h" | 12 #include "src/compiler/graph-visualizer.h" |
| 13 #include "src/compiler/js-operator.h" | 13 #include "src/compiler/js-operator.h" |
| 14 #include "src/compiler/machine-operator.h" | 14 #include "src/compiler/machine-operator.h" |
| 15 #include "src/compiler/node.h" | 15 #include "src/compiler/node.h" |
| 16 #include "src/compiler/operator.h" | 16 #include "src/compiler/operator.h" |
| 17 #include "src/compiler/schedule.h" | 17 #include "src/compiler/schedule.h" |
| 18 #include "src/compiler/scheduler.h" | 18 #include "src/compiler/scheduler.h" |
| 19 #include "src/compiler/verifier.h" |
| 19 | 20 |
| 20 using namespace v8::internal; | 21 using namespace v8::internal; |
| 21 using namespace v8::internal::compiler; | 22 using namespace v8::internal::compiler; |
| 22 | 23 |
| 24 // TODO(titzer): pull RPO tests out to their own file. |
| 23 struct TestLoop { | 25 struct TestLoop { |
| 24 int count; | 26 int count; |
| 25 BasicBlock** nodes; | 27 BasicBlock** nodes; |
| 26 BasicBlock* header() { return nodes[0]; } | 28 BasicBlock* header() { return nodes[0]; } |
| 27 BasicBlock* last() { return nodes[count - 1]; } | 29 BasicBlock* last() { return nodes[count - 1]; } |
| 28 ~TestLoop() { delete[] nodes; } | 30 ~TestLoop() { delete[] nodes; } |
| 29 }; | 31 }; |
| 30 | 32 |
| 31 | 33 |
| 32 static TestLoop* CreateLoop(Schedule* schedule, int count) { | 34 static TestLoop* CreateLoop(Schedule* schedule, int count) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 58 CHECK_EQ(body_size, (header->loop_end_ - header->rpo_number_)); | 60 CHECK_EQ(body_size, (header->loop_end_ - header->rpo_number_)); |
| 59 for (int i = 0; i < body_size; i++) { | 61 for (int i = 0; i < body_size; i++) { |
| 60 int num = blocks[i]->rpo_number_; | 62 int num = blocks[i]->rpo_number_; |
| 61 CHECK(num >= header->rpo_number_ && num < header->loop_end_); | 63 CHECK(num >= header->rpo_number_ && num < header->loop_end_); |
| 62 CHECK(header->LoopContains(blocks[i])); | 64 CHECK(header->LoopContains(blocks[i])); |
| 63 CHECK(header->IsLoopHeader() || blocks[i]->loop_header_ == header); | 65 CHECK(header->IsLoopHeader() || blocks[i]->loop_header_ == header); |
| 64 } | 66 } |
| 65 } | 67 } |
| 66 | 68 |
| 67 | 69 |
| 70 static int GetScheduledNodeCount(Schedule* schedule) { |
| 71 int node_count = 0; |
| 72 for (BasicBlockVectorIter i = schedule->rpo_order()->begin(); |
| 73 i != schedule->rpo_order()->end(); ++i) { |
| 74 BasicBlock* block = *i; |
| 75 for (BasicBlock::const_iterator j = block->begin(); j != block->end(); |
| 76 ++j) { |
| 77 ++node_count; |
| 78 } |
| 79 BasicBlock::Control control = block->control_; |
| 80 if (control != BasicBlock::kNone) { |
| 81 ++node_count; |
| 82 } |
| 83 } |
| 84 return node_count; |
| 85 } |
| 86 |
| 87 |
| 88 static Schedule* ComputeAndVerifySchedule(int expected, Graph* graph) { |
| 89 if (FLAG_trace_turbo) { |
| 90 OFStream os(stdout); |
| 91 os << AsDOT(*graph); |
| 92 } |
| 93 |
| 94 Schedule* schedule = Scheduler::ComputeSchedule(graph); |
| 95 |
| 96 if (FLAG_trace_turbo_scheduler) { |
| 97 OFStream os(stdout); |
| 98 os << *schedule << endl; |
| 99 } |
| 100 ScheduleVerifier::Run(schedule); |
| 101 CHECK_EQ(expected, GetScheduledNodeCount(schedule)); |
| 102 return schedule; |
| 103 } |
| 104 |
| 105 |
| 68 TEST(RPODegenerate1) { | 106 TEST(RPODegenerate1) { |
| 69 HandleAndZoneScope scope; | 107 HandleAndZoneScope scope; |
| 70 Schedule schedule(scope.main_zone()); | 108 Schedule schedule(scope.main_zone()); |
| 71 | 109 |
| 72 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule); | 110 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule); |
| 73 CheckRPONumbers(order, 1, false); | 111 CheckRPONumbers(order, 1, false); |
| 74 CHECK_EQ(schedule.start(), order->at(0)); | 112 CHECK_EQ(schedule.start(), order->at(0)); |
| 75 } | 113 } |
| 76 | 114 |
| 77 | 115 |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 | 636 |
| 599 Node* p1 = graph.NewNode(builder.Parameter(0), graph.start()); | 637 Node* p1 = graph.NewNode(builder.Parameter(0), graph.start()); |
| 600 Node* ret = graph.NewNode(builder.Return(), p1, graph.start(), graph.start()); | 638 Node* ret = graph.NewNode(builder.Return(), p1, graph.start(), graph.start()); |
| 601 | 639 |
| 602 graph.SetEnd(graph.NewNode(builder.End(), ret)); | 640 graph.SetEnd(graph.NewNode(builder.End(), ret)); |
| 603 | 641 |
| 604 USE(Scheduler::ComputeSchedule(&graph)); | 642 USE(Scheduler::ComputeSchedule(&graph)); |
| 605 } | 643 } |
| 606 | 644 |
| 607 | 645 |
| 608 static int GetScheduledNodeCount(Schedule* schedule) { | |
| 609 int node_count = 0; | |
| 610 for (BasicBlockVectorIter i = schedule->rpo_order()->begin(); | |
| 611 i != schedule->rpo_order()->end(); ++i) { | |
| 612 BasicBlock* block = *i; | |
| 613 for (BasicBlock::const_iterator j = block->begin(); j != block->end(); | |
| 614 ++j) { | |
| 615 ++node_count; | |
| 616 } | |
| 617 BasicBlock::Control control = block->control_; | |
| 618 if (control != BasicBlock::kNone) { | |
| 619 ++node_count; | |
| 620 } | |
| 621 } | |
| 622 return node_count; | |
| 623 } | |
| 624 | |
| 625 | |
| 626 static void PrintGraph(Graph* graph) { | |
| 627 OFStream os(stdout); | |
| 628 os << AsDOT(*graph); | |
| 629 } | |
| 630 | |
| 631 | |
| 632 static void PrintSchedule(Schedule* schedule) { | |
| 633 OFStream os(stdout); | |
| 634 os << *schedule << endl; | |
| 635 } | |
| 636 | |
| 637 | |
| 638 TEST(BuildScheduleIfSplit) { | 646 TEST(BuildScheduleIfSplit) { |
| 639 HandleAndZoneScope scope; | 647 HandleAndZoneScope scope; |
| 640 Graph graph(scope.main_zone()); | 648 Graph graph(scope.main_zone()); |
| 641 CommonOperatorBuilder builder(scope.main_zone()); | 649 CommonOperatorBuilder builder(scope.main_zone()); |
| 642 JSOperatorBuilder js_builder(scope.main_zone()); | 650 JSOperatorBuilder js_builder(scope.main_zone()); |
| 643 graph.SetStart(graph.NewNode(builder.Start(3))); | 651 graph.SetStart(graph.NewNode(builder.Start(3))); |
| 644 | 652 |
| 645 Node* p1 = graph.NewNode(builder.Parameter(0), graph.start()); | 653 Node* p1 = graph.NewNode(builder.Parameter(0), graph.start()); |
| 646 Node* p2 = graph.NewNode(builder.Parameter(1), graph.start()); | 654 Node* p2 = graph.NewNode(builder.Parameter(1), graph.start()); |
| 647 Node* p3 = graph.NewNode(builder.Parameter(2), graph.start()); | 655 Node* p3 = graph.NewNode(builder.Parameter(2), graph.start()); |
| 648 Node* p4 = graph.NewNode(builder.Parameter(3), graph.start()); | 656 Node* p4 = graph.NewNode(builder.Parameter(3), graph.start()); |
| 649 Node* p5 = graph.NewNode(builder.Parameter(4), graph.start()); | 657 Node* p5 = graph.NewNode(builder.Parameter(4), graph.start()); |
| 650 Node* cmp = graph.NewNode(js_builder.LessThanOrEqual(), p1, p2, p3, | 658 Node* cmp = graph.NewNode(js_builder.LessThanOrEqual(), p1, p2, p3, |
| 651 graph.start(), graph.start()); | 659 graph.start(), graph.start()); |
| 652 Node* branch = graph.NewNode(builder.Branch(), cmp, graph.start()); | 660 Node* branch = graph.NewNode(builder.Branch(), cmp, graph.start()); |
| 653 Node* true_branch = graph.NewNode(builder.IfTrue(), branch); | 661 Node* true_branch = graph.NewNode(builder.IfTrue(), branch); |
| 654 Node* false_branch = graph.NewNode(builder.IfFalse(), branch); | 662 Node* false_branch = graph.NewNode(builder.IfFalse(), branch); |
| 655 | 663 |
| 656 Node* ret1 = graph.NewNode(builder.Return(), p4, graph.start(), true_branch); | 664 Node* ret1 = graph.NewNode(builder.Return(), p4, graph.start(), true_branch); |
| 657 Node* ret2 = graph.NewNode(builder.Return(), p5, graph.start(), false_branch); | 665 Node* ret2 = graph.NewNode(builder.Return(), p5, graph.start(), false_branch); |
| 658 Node* merge = graph.NewNode(builder.Merge(2), ret1, ret2); | 666 Node* merge = graph.NewNode(builder.Merge(2), ret1, ret2); |
| 659 graph.SetEnd(graph.NewNode(builder.End(), merge)); | 667 graph.SetEnd(graph.NewNode(builder.End(), merge)); |
| 660 | 668 |
| 661 PrintGraph(&graph); | 669 ComputeAndVerifySchedule(13, &graph); |
| 662 | |
| 663 Schedule* schedule = Scheduler::ComputeSchedule(&graph); | |
| 664 | |
| 665 PrintSchedule(schedule); | |
| 666 | |
| 667 | |
| 668 CHECK_EQ(13, GetScheduledNodeCount(schedule)); | |
| 669 } | 670 } |
| 670 | 671 |
| 671 | 672 |
| 672 TEST(BuildScheduleIfSplitWithEffects) { | 673 TEST(BuildScheduleIfSplitWithEffects) { |
| 673 HandleAndZoneScope scope; | 674 HandleAndZoneScope scope; |
| 674 Isolate* isolate = scope.main_isolate(); | 675 Isolate* isolate = scope.main_isolate(); |
| 675 Graph graph(scope.main_zone()); | 676 Graph graph(scope.main_zone()); |
| 676 CommonOperatorBuilder common_builder(scope.main_zone()); | 677 CommonOperatorBuilder common_builder(scope.main_zone()); |
| 677 JSOperatorBuilder js_builder(scope.main_zone()); | 678 JSOperatorBuilder js_builder(scope.main_zone()); |
| 678 Operator* op; | 679 Operator* op; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 n20->ReplaceInput(4, n18); | 805 n20->ReplaceInput(4, n18); |
| 805 n21->ReplaceInput(0, n20); | 806 n21->ReplaceInput(0, n20); |
| 806 n21->ReplaceInput(1, n20); | 807 n21->ReplaceInput(1, n20); |
| 807 n21->ReplaceInput(2, n18); | 808 n21->ReplaceInput(2, n18); |
| 808 n22->ReplaceInput(1, n21); | 809 n22->ReplaceInput(1, n21); |
| 809 n23->ReplaceInput(0, n22); | 810 n23->ReplaceInput(0, n22); |
| 810 | 811 |
| 811 graph.SetStart(n0); | 812 graph.SetStart(n0); |
| 812 graph.SetEnd(n23); | 813 graph.SetEnd(n23); |
| 813 | 814 |
| 814 PrintGraph(&graph); | 815 ComputeAndVerifySchedule(20, &graph); |
| 815 | |
| 816 Schedule* schedule = Scheduler::ComputeSchedule(&graph); | |
| 817 | |
| 818 PrintSchedule(schedule); | |
| 819 | |
| 820 CHECK_EQ(20, GetScheduledNodeCount(schedule)); | |
| 821 } | 816 } |
| 822 | 817 |
| 823 | 818 |
| 824 TEST(BuildScheduleSimpleLoop) { | 819 TEST(BuildScheduleSimpleLoop) { |
| 825 HandleAndZoneScope scope; | 820 HandleAndZoneScope scope; |
| 826 Isolate* isolate = scope.main_isolate(); | 821 Isolate* isolate = scope.main_isolate(); |
| 827 Graph graph(scope.main_zone()); | 822 Graph graph(scope.main_zone()); |
| 828 CommonOperatorBuilder common_builder(scope.main_zone()); | 823 CommonOperatorBuilder common_builder(scope.main_zone()); |
| 829 JSOperatorBuilder js_builder(scope.main_zone()); | 824 JSOperatorBuilder js_builder(scope.main_zone()); |
| 830 Operator* op; | 825 Operator* op; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 923 op = common_builder.IfFalse(); | 918 op = common_builder.IfFalse(); |
| 924 Node* n15 = graph.NewNode(op, nil); | 919 Node* n15 = graph.NewNode(op, nil); |
| 925 USE(n15); | 920 USE(n15); |
| 926 n15->ReplaceInput(0, n13); | 921 n15->ReplaceInput(0, n13); |
| 927 n19->ReplaceInput(2, n15); | 922 n19->ReplaceInput(2, n15); |
| 928 n20->ReplaceInput(0, n19); | 923 n20->ReplaceInput(0, n19); |
| 929 | 924 |
| 930 graph.SetStart(n0); | 925 graph.SetStart(n0); |
| 931 graph.SetEnd(n20); | 926 graph.SetEnd(n20); |
| 932 | 927 |
| 933 PrintGraph(&graph); | 928 ComputeAndVerifySchedule(19, &graph); |
| 934 | |
| 935 Schedule* schedule = Scheduler::ComputeSchedule(&graph); | |
| 936 | |
| 937 PrintSchedule(schedule); | |
| 938 | |
| 939 CHECK_EQ(19, GetScheduledNodeCount(schedule)); | |
| 940 } | 929 } |
| 941 | 930 |
| 942 | 931 |
| 943 TEST(BuildScheduleComplexLoops) { | 932 TEST(BuildScheduleComplexLoops) { |
| 944 HandleAndZoneScope scope; | 933 HandleAndZoneScope scope; |
| 945 Isolate* isolate = scope.main_isolate(); | 934 Isolate* isolate = scope.main_isolate(); |
| 946 Graph graph(scope.main_zone()); | 935 Graph graph(scope.main_zone()); |
| 947 CommonOperatorBuilder common_builder(scope.main_zone()); | 936 CommonOperatorBuilder common_builder(scope.main_zone()); |
| 948 JSOperatorBuilder js_builder(scope.main_zone()); | 937 JSOperatorBuilder js_builder(scope.main_zone()); |
| 949 Operator* op; | 938 Operator* op; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1177 op = common_builder.IfFalse(); | 1166 op = common_builder.IfFalse(); |
| 1178 Node* n42 = graph.NewNode(op, nil); | 1167 Node* n42 = graph.NewNode(op, nil); |
| 1179 USE(n42); | 1168 USE(n42); |
| 1180 n42->ReplaceInput(0, n40); | 1169 n42->ReplaceInput(0, n40); |
| 1181 n45->ReplaceInput(2, n42); | 1170 n45->ReplaceInput(2, n42); |
| 1182 n46->ReplaceInput(0, n45); | 1171 n46->ReplaceInput(0, n45); |
| 1183 | 1172 |
| 1184 graph.SetStart(n0); | 1173 graph.SetStart(n0); |
| 1185 graph.SetEnd(n46); | 1174 graph.SetEnd(n46); |
| 1186 | 1175 |
| 1187 PrintGraph(&graph); | 1176 ComputeAndVerifySchedule(46, &graph); |
| 1188 | |
| 1189 Schedule* schedule = Scheduler::ComputeSchedule(&graph); | |
| 1190 | |
| 1191 PrintSchedule(schedule); | |
| 1192 | |
| 1193 CHECK_EQ(46, GetScheduledNodeCount(schedule)); | |
| 1194 } | 1177 } |
| 1195 | 1178 |
| 1196 | 1179 |
| 1197 TEST(BuildScheduleBreakAndContinue) { | 1180 TEST(BuildScheduleBreakAndContinue) { |
| 1198 HandleAndZoneScope scope; | 1181 HandleAndZoneScope scope; |
| 1199 Isolate* isolate = scope.main_isolate(); | 1182 Isolate* isolate = scope.main_isolate(); |
| 1200 Graph graph(scope.main_zone()); | 1183 Graph graph(scope.main_zone()); |
| 1201 CommonOperatorBuilder common_builder(scope.main_zone()); | 1184 CommonOperatorBuilder common_builder(scope.main_zone()); |
| 1202 JSOperatorBuilder js_builder(scope.main_zone()); | 1185 JSOperatorBuilder js_builder(scope.main_zone()); |
| 1203 Operator* op; | 1186 Operator* op; |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 n19->ReplaceInput(0, n17); | 1496 n19->ReplaceInput(0, n17); |
| 1514 n56->ReplaceInput(4, n19); | 1497 n56->ReplaceInput(4, n19); |
| 1515 n57->ReplaceInput(0, n56); | 1498 n57->ReplaceInput(0, n56); |
| 1516 n57->ReplaceInput(1, n56); | 1499 n57->ReplaceInput(1, n56); |
| 1517 n57->ReplaceInput(2, n19); | 1500 n57->ReplaceInput(2, n19); |
| 1518 n58->ReplaceInput(0, n57); | 1501 n58->ReplaceInput(0, n57); |
| 1519 | 1502 |
| 1520 graph.SetStart(n0); | 1503 graph.SetStart(n0); |
| 1521 graph.SetEnd(n58); | 1504 graph.SetEnd(n58); |
| 1522 | 1505 |
| 1523 PrintGraph(&graph); | 1506 ComputeAndVerifySchedule(62, &graph); |
| 1524 | |
| 1525 Schedule* schedule = Scheduler::ComputeSchedule(&graph); | |
| 1526 | |
| 1527 PrintSchedule(schedule); | |
| 1528 | |
| 1529 CHECK_EQ(62, GetScheduledNodeCount(schedule)); | |
| 1530 } | 1507 } |
| 1531 | 1508 |
| 1532 | 1509 |
| 1533 TEST(BuildScheduleSimpleLoopWithCodeMotion) { | 1510 TEST(BuildScheduleSimpleLoopWithCodeMotion) { |
| 1534 HandleAndZoneScope scope; | 1511 HandleAndZoneScope scope; |
| 1535 Isolate* isolate = scope.main_isolate(); | 1512 Isolate* isolate = scope.main_isolate(); |
| 1536 Graph graph(scope.main_zone()); | 1513 Graph graph(scope.main_zone()); |
| 1537 CommonOperatorBuilder common_builder(scope.main_zone()); | 1514 CommonOperatorBuilder common_builder(scope.main_zone()); |
| 1538 JSOperatorBuilder js_builder(scope.main_zone()); | 1515 JSOperatorBuilder js_builder(scope.main_zone()); |
| 1539 MachineOperatorBuilder machine_builder(scope.main_zone()); | 1516 MachineOperatorBuilder machine_builder(scope.main_zone()); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1644 op = common_builder.IfFalse(); | 1621 op = common_builder.IfFalse(); |
| 1645 Node* n18 = graph.NewNode(op, nil); | 1622 Node* n18 = graph.NewNode(op, nil); |
| 1646 USE(n18); | 1623 USE(n18); |
| 1647 n18->ReplaceInput(0, n16); | 1624 n18->ReplaceInput(0, n16); |
| 1648 n21->ReplaceInput(2, n18); | 1625 n21->ReplaceInput(2, n18); |
| 1649 n22->ReplaceInput(0, n21); | 1626 n22->ReplaceInput(0, n21); |
| 1650 | 1627 |
| 1651 graph.SetStart(n0); | 1628 graph.SetStart(n0); |
| 1652 graph.SetEnd(n22); | 1629 graph.SetEnd(n22); |
| 1653 | 1630 |
| 1654 PrintGraph(&graph); | 1631 Schedule* schedule = ComputeAndVerifySchedule(19, &graph); |
| 1655 | |
| 1656 Schedule* schedule = Scheduler::ComputeSchedule(&graph); | |
| 1657 | |
| 1658 PrintSchedule(schedule); | |
| 1659 | |
| 1660 CHECK_EQ(19, GetScheduledNodeCount(schedule)); | |
| 1661 | |
| 1662 // Make sure the integer-only add gets hoisted to a different block that the | 1632 // Make sure the integer-only add gets hoisted to a different block that the |
| 1663 // JSAdd. | 1633 // JSAdd. |
| 1664 CHECK(schedule->block(n19) != schedule->block(n20)); | 1634 CHECK(schedule->block(n19) != schedule->block(n20)); |
| 1665 } | 1635 } |
| 1666 | 1636 |
| 1667 | 1637 |
| 1668 #if V8_TURBOFAN_TARGET | 1638 #if V8_TURBOFAN_TARGET |
| 1669 | 1639 |
| 1670 // So we can get a real JS function. | 1640 // So we can get a real JS function. |
| 1671 static Handle<JSFunction> Compile(const char* source) { | 1641 static Handle<JSFunction> Compile(const char* source) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 lazy_deopt_node); // control | 1734 lazy_deopt_node); // control |
| 1765 | 1735 |
| 1766 Node* merge_node = | 1736 Node* merge_node = |
| 1767 graph.NewNode(common.Merge(2), return_node, deoptimization_node); | 1737 graph.NewNode(common.Merge(2), return_node, deoptimization_node); |
| 1768 | 1738 |
| 1769 Node* end_node = graph.NewNode(common.End(), merge_node); | 1739 Node* end_node = graph.NewNode(common.End(), merge_node); |
| 1770 | 1740 |
| 1771 graph.SetStart(start_node); | 1741 graph.SetStart(start_node); |
| 1772 graph.SetEnd(end_node); | 1742 graph.SetEnd(end_node); |
| 1773 | 1743 |
| 1774 PrintGraph(&graph); | 1744 Schedule* schedule = ComputeAndVerifySchedule(12, &graph); |
| 1775 | |
| 1776 Schedule* schedule = Scheduler::ComputeSchedule(&graph); | |
| 1777 | |
| 1778 PrintSchedule(schedule); | |
| 1779 | 1745 |
| 1780 // Tests: | 1746 // Tests: |
| 1781 // Continuation and deopt have basic blocks. | 1747 // Continuation and deopt have basic blocks. |
| 1782 BasicBlock* cont_block = schedule->block(cont_node); | 1748 BasicBlock* cont_block = schedule->block(cont_node); |
| 1783 BasicBlock* deopt_block = schedule->block(lazy_deopt_node); | 1749 BasicBlock* deopt_block = schedule->block(lazy_deopt_node); |
| 1784 BasicBlock* call_block = schedule->block(call_node); | 1750 BasicBlock* call_block = schedule->block(call_node); |
| 1785 CHECK_NE(NULL, cont_block); | 1751 CHECK_NE(NULL, cont_block); |
| 1786 CHECK_NE(NULL, deopt_block); | 1752 CHECK_NE(NULL, deopt_block); |
| 1787 CHECK_NE(NULL, call_block); | 1753 CHECK_NE(NULL, call_block); |
| 1788 // The basic blocks are different. | 1754 // The basic blocks are different. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1799 // The lazy deopt block contains framestate + bailout (and nothing else). | 1765 // The lazy deopt block contains framestate + bailout (and nothing else). |
| 1800 CHECK_EQ(deoptimization_node, deopt_block->control_input_); | 1766 CHECK_EQ(deoptimization_node, deopt_block->control_input_); |
| 1801 CHECK_EQ(5, static_cast<int>(deopt_block->nodes_.size())); | 1767 CHECK_EQ(5, static_cast<int>(deopt_block->nodes_.size())); |
| 1802 CHECK_EQ(lazy_deopt_node, deopt_block->nodes_[0]); | 1768 CHECK_EQ(lazy_deopt_node, deopt_block->nodes_[0]); |
| 1803 CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[1]->op()->opcode()); | 1769 CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[1]->op()->opcode()); |
| 1804 CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[2]->op()->opcode()); | 1770 CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[2]->op()->opcode()); |
| 1805 CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[3]->op()->opcode()); | 1771 CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[3]->op()->opcode()); |
| 1806 CHECK_EQ(state_node, deopt_block->nodes_[4]); | 1772 CHECK_EQ(state_node, deopt_block->nodes_[4]); |
| 1807 } | 1773 } |
| 1808 | 1774 |
| 1775 |
| 1776 static Node* CreateDiamond(Graph* graph, CommonOperatorBuilder* common, |
| 1777 Node* cond) { |
| 1778 Node* tv = graph->NewNode(common->Int32Constant(6)); |
| 1779 Node* fv = graph->NewNode(common->Int32Constant(7)); |
| 1780 Node* br = graph->NewNode(common->Branch(), cond, graph->start()); |
| 1781 Node* t = graph->NewNode(common->IfTrue(), br); |
| 1782 Node* f = graph->NewNode(common->IfFalse(), br); |
| 1783 Node* m = graph->NewNode(common->Merge(2), t, f); |
| 1784 Node* phi = graph->NewNode(common->Phi(2), tv, fv, m); |
| 1785 return phi; |
| 1786 } |
| 1787 |
| 1788 |
| 1789 TEST(FloatingDiamond1) { |
| 1790 HandleAndZoneScope scope; |
| 1791 Graph graph(scope.main_zone()); |
| 1792 CommonOperatorBuilder common(scope.main_zone()); |
| 1793 |
| 1794 Node* start = graph.NewNode(common.Start(1)); |
| 1795 graph.SetStart(start); |
| 1796 |
| 1797 Node* p0 = graph.NewNode(common.Parameter(0), start); |
| 1798 Node* d1 = CreateDiamond(&graph, &common, p0); |
| 1799 Node* ret = graph.NewNode(common.Return(), d1, start, start); |
| 1800 Node* end = graph.NewNode(common.End(), ret, start); |
| 1801 |
| 1802 graph.SetEnd(end); |
| 1803 |
| 1804 ComputeAndVerifySchedule(13, &graph); |
| 1805 } |
| 1806 |
| 1807 |
| 1808 TEST(FloatingDiamond2) { |
| 1809 HandleAndZoneScope scope; |
| 1810 Graph graph(scope.main_zone()); |
| 1811 CommonOperatorBuilder common(scope.main_zone()); |
| 1812 MachineOperatorBuilder machine(scope.main_zone()); |
| 1813 |
| 1814 Node* start = graph.NewNode(common.Start(2)); |
| 1815 graph.SetStart(start); |
| 1816 |
| 1817 Node* p0 = graph.NewNode(common.Parameter(0), start); |
| 1818 Node* p1 = graph.NewNode(common.Parameter(1), start); |
| 1819 Node* d1 = CreateDiamond(&graph, &common, p0); |
| 1820 Node* d2 = CreateDiamond(&graph, &common, p1); |
| 1821 Node* add = graph.NewNode(machine.Int32Add(), d1, d2); |
| 1822 Node* ret = graph.NewNode(common.Return(), add, start, start); |
| 1823 Node* end = graph.NewNode(common.End(), ret, start); |
| 1824 |
| 1825 graph.SetEnd(end); |
| 1826 |
| 1827 ComputeAndVerifySchedule(24, &graph); |
| 1828 } |
| 1829 |
| 1830 |
| 1831 TEST(FloatingDiamond3) { |
| 1832 HandleAndZoneScope scope; |
| 1833 Graph graph(scope.main_zone()); |
| 1834 CommonOperatorBuilder common(scope.main_zone()); |
| 1835 MachineOperatorBuilder machine(scope.main_zone()); |
| 1836 |
| 1837 Node* start = graph.NewNode(common.Start(2)); |
| 1838 graph.SetStart(start); |
| 1839 |
| 1840 Node* p0 = graph.NewNode(common.Parameter(0), start); |
| 1841 Node* p1 = graph.NewNode(common.Parameter(1), start); |
| 1842 Node* d1 = CreateDiamond(&graph, &common, p0); |
| 1843 Node* d2 = CreateDiamond(&graph, &common, p1); |
| 1844 Node* add = graph.NewNode(machine.Int32Add(), d1, d2); |
| 1845 Node* d3 = CreateDiamond(&graph, &common, add); |
| 1846 Node* ret = graph.NewNode(common.Return(), d3, start, start); |
| 1847 Node* end = graph.NewNode(common.End(), ret, start); |
| 1848 |
| 1849 graph.SetEnd(end); |
| 1850 |
| 1851 ComputeAndVerifySchedule(33, &graph); |
| 1852 } |
| 1853 |
| 1809 #endif | 1854 #endif |
| OLD | NEW |