1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/compiler/control-flow-optimizer.h"
6 #include "src/compiler/js-operator.h"
7 #include "src/compiler/machine-operator.h"
8 #include "test/unittests/compiler/graph-unittest.h"
9 #include "test/unittests/compiler/node-test-utils.h"
10 #include "testing/gmock-support.h"
11 
12 using testing::AllOf;
13 using testing::Capture;
14 using testing::CaptureEq;
15 
16 namespace v8 {
17 namespace internal {
18 namespace compiler {
19 
20 class ControlFlowOptimizerTest : public GraphTest {
21  public:
ControlFlowOptimizerTest(int num_parameters=3)22   explicit ControlFlowOptimizerTest(int num_parameters = 3)
23       : GraphTest(num_parameters), machine_(zone()), javascript_(zone()) {}
24   ~ControlFlowOptimizerTest() override = default;
25 
26  protected:
Optimize()27   void Optimize() {
28     ControlFlowOptimizer optimizer(graph(), common(), machine(), tick_counter(),
29                                    zone());
30     optimizer.Optimize();
31   }
32 
javascript()33   JSOperatorBuilder* javascript() { return &javascript_; }
machine()34   MachineOperatorBuilder* machine() { return &machine_; }
35 
36  private:
37   MachineOperatorBuilder machine_;
38   JSOperatorBuilder javascript_;
39 };
40 
41 
TEST_F(ControlFlowOptimizerTest,BuildSwitch1)42 TEST_F(ControlFlowOptimizerTest, BuildSwitch1) {
43   Node* index = Parameter(0);
44   Node* branch0 = graph()->NewNode(
45       common()->Branch(),
46       graph()->NewNode(machine()->Word32Equal(), index, Int32Constant(0)),
47       start());
48   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
49   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
50   Node* branch1 = graph()->NewNode(
51       common()->Branch(),
52       graph()->NewNode(machine()->Word32Equal(), index, Int32Constant(1)),
53       if_false0);
54   Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
55   Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
56   Node* merge =
57       graph()->NewNode(common()->Merge(3), if_true0, if_true1, if_false1);
58   graph()->SetEnd(graph()->NewNode(common()->End(1), merge));
59   Optimize();
60   Capture<Node*> switch_capture;
61   EXPECT_THAT(
62       end(), IsEnd(IsMerge(
63                  IsIfValue(IfValueParameters(0, 1), CaptureEq(&switch_capture)),
64                  IsIfValue(IfValueParameters(1, 2), CaptureEq(&switch_capture)),
65                  IsIfDefault(AllOf(CaptureEq(&switch_capture),
66                                    IsSwitch(index, start()))))));
67 }
68 
69 
TEST_F(ControlFlowOptimizerTest,BuildSwitch2)70 TEST_F(ControlFlowOptimizerTest, BuildSwitch2) {
71   Node* input = Parameter(0);
72   Node* context = Parameter(1);
73   Node* index = graph()->NewNode(javascript()->ToNumber(), input, context,
74                                  start(), start(), start());
75   Node* if_success = graph()->NewNode(common()->IfSuccess(), index);
76   Node* branch0 = graph()->NewNode(
77       common()->Branch(),
78       graph()->NewNode(machine()->Word32Equal(), index, Int32Constant(0)),
79       if_success);
80   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
81   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
82   Node* branch1 = graph()->NewNode(
83       common()->Branch(),
84       graph()->NewNode(machine()->Word32Equal(), index, Int32Constant(1)),
85       if_false0);
86   Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
87   Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
88   Node* merge =
89       graph()->NewNode(common()->Merge(3), if_true0, if_true1, if_false1);
90   graph()->SetEnd(graph()->NewNode(common()->End(1), merge));
91   Optimize();
92   Capture<Node*> switch_capture;
93   EXPECT_THAT(
94       end(), IsEnd(IsMerge(
95                  IsIfValue(IfValueParameters(0, 1), CaptureEq(&switch_capture)),
96                  IsIfValue(IfValueParameters(1, 2), CaptureEq(&switch_capture)),
97                  IsIfDefault(AllOf(CaptureEq(&switch_capture),
98                                    IsSwitch(index, IsIfSuccess(index)))))));
99 }
100 
101 }  // namespace compiler
102 }  // namespace internal
103 }  // namespace v8
104