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