Line data Source code
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:
22 2 : explicit ControlFlowOptimizerTest(int num_parameters = 3)
23 4 : : GraphTest(num_parameters), machine_(zone()), javascript_(zone()) {}
24 2 : ~ControlFlowOptimizerTest() override {}
25 :
26 : protected:
27 2 : void Optimize() {
28 2 : ControlFlowOptimizer optimizer(graph(), common(), machine(), zone());
29 2 : optimizer.Optimize();
30 2 : }
31 :
32 : JSOperatorBuilder* javascript() { return &javascript_; }
33 : MachineOperatorBuilder* machine() { return &machine_; }
34 :
35 : private:
36 : MachineOperatorBuilder machine_;
37 : JSOperatorBuilder javascript_;
38 : };
39 :
40 :
41 13160 : TEST_F(ControlFlowOptimizerTest, BuildSwitch1) {
42 1 : Node* index = Parameter(0);
43 : Node* branch0 = graph()->NewNode(
44 : common()->Branch(),
45 : graph()->NewNode(machine()->Word32Equal(), index, Int32Constant(0)),
46 2 : start());
47 1 : Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
48 1 : Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
49 : Node* branch1 = graph()->NewNode(
50 : common()->Branch(),
51 : graph()->NewNode(machine()->Word32Equal(), index, Int32Constant(1)),
52 2 : if_false0);
53 1 : Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
54 1 : Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
55 : Node* merge =
56 1 : graph()->NewNode(common()->Merge(3), if_true0, if_true1, if_false1);
57 1 : graph()->SetEnd(graph()->NewNode(common()->End(1), merge));
58 1 : Optimize();
59 : Capture<Node*> switch_capture;
60 20 : EXPECT_THAT(end(),
61 : IsEnd(IsMerge(IsIfValue(0, CaptureEq(&switch_capture)),
62 : IsIfValue(1, CaptureEq(&switch_capture)),
63 : IsIfDefault(AllOf(CaptureEq(&switch_capture),
64 0 : IsSwitch(index, start()))))));
65 1 : }
66 :
67 :
68 13160 : TEST_F(ControlFlowOptimizerTest, BuildSwitch2) {
69 1 : Node* input = Parameter(0);
70 1 : Node* context = Parameter(1);
71 : Node* index = graph()->NewNode(javascript()->ToNumber(), input, context,
72 1 : start(), start(), start());
73 1 : Node* if_success = graph()->NewNode(common()->IfSuccess(), index);
74 : Node* branch0 = graph()->NewNode(
75 : common()->Branch(),
76 : graph()->NewNode(machine()->Word32Equal(), index, Int32Constant(0)),
77 2 : if_success);
78 1 : Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
79 1 : Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
80 : Node* branch1 = graph()->NewNode(
81 : common()->Branch(),
82 : graph()->NewNode(machine()->Word32Equal(), index, Int32Constant(1)),
83 2 : if_false0);
84 1 : Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
85 1 : Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
86 : Node* merge =
87 1 : graph()->NewNode(common()->Merge(3), if_true0, if_true1, if_false1);
88 1 : graph()->SetEnd(graph()->NewNode(common()->End(1), merge));
89 1 : Optimize();
90 : Capture<Node*> switch_capture;
91 20 : EXPECT_THAT(
92 : end(),
93 : IsEnd(IsMerge(IsIfValue(0, CaptureEq(&switch_capture)),
94 : IsIfValue(1, CaptureEq(&switch_capture)),
95 : IsIfDefault(AllOf(CaptureEq(&switch_capture),
96 0 : IsSwitch(index, IsIfSuccess(index)))))));
97 1 : }
98 :
99 : } // namespace compiler
100 : } // namespace internal
101 7893 : } // namespace v8
|