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 |