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/common-operator.h"
6 : #include "src/compiler/node-properties.h"
7 : #include "test/unittests/test-utils.h"
8 : #include "testing/gmock/include/gmock/gmock.h"
9 :
10 : using testing::AnyOf;
11 : using testing::ElementsAre;
12 : using testing::IsNull;
13 :
14 : namespace v8 {
15 : namespace internal {
16 : namespace compiler {
17 : namespace node_properties_unittest {
18 :
19 10 : class NodePropertiesTest : public TestWithZone {
20 : public:
21 : Node* NewMockNode(const Operator* op) {
22 9 : return Node::New(zone(), 0, op, 0, nullptr, false);
23 : }
24 : Node* NewMockNode(const Operator* op, Node* n1) {
25 11 : Node* nodes[] = {n1};
26 11 : return Node::New(zone(), 0, op, arraysize(nodes), nodes, false);
27 : }
28 : Node* NewMockNode(const Operator* op, Node* n1, Node* n2) {
29 2 : Node* nodes[] = {n1, n2};
30 2 : return Node::New(zone(), 0, op, arraysize(nodes), nodes, false);
31 : }
32 : };
33 :
34 : namespace {
35 :
36 6176 : const Operator kMockOperator(IrOpcode::kDead, Operator::kNoProperties,
37 3088 : "MockOperator", 0, 0, 0, 1, 1, 2);
38 6176 : const Operator kMockCallOperator(IrOpcode::kCall, Operator::kNoProperties,
39 3088 : "MockCallOperator", 0, 0, 0, 0, 0, 2);
40 :
41 : } // namespace
42 :
43 :
44 15444 : TEST_F(NodePropertiesTest, ReplaceUses) {
45 1 : CommonOperatorBuilder common(zone());
46 : Node* node = NewMockNode(&kMockOperator);
47 : Node* effect = NewMockNode(&kMockOperator);
48 1 : Node* use_value = NewMockNode(common.Return(), node);
49 1 : Node* use_effect = NewMockNode(common.EffectPhi(1), node);
50 1 : Node* use_success = NewMockNode(common.IfSuccess(), node);
51 1 : Node* use_exception = NewMockNode(common.IfException(), effect, node);
52 1 : Node* r_value = NewMockNode(&kMockOperator);
53 1 : Node* r_effect = NewMockNode(&kMockOperator);
54 1 : Node* r_success = NewMockNode(&kMockOperator);
55 1 : Node* r_exception = NewMockNode(&kMockOperator);
56 1 : NodeProperties::ReplaceUses(node, r_value, r_effect, r_success, r_exception);
57 2 : EXPECT_EQ(r_value, use_value->InputAt(0));
58 2 : EXPECT_EQ(r_effect, use_effect->InputAt(0));
59 2 : EXPECT_EQ(r_success, use_success->InputAt(0));
60 2 : EXPECT_EQ(r_exception, use_exception->InputAt(1));
61 2 : EXPECT_EQ(0, node->UseCount());
62 2 : EXPECT_EQ(1, r_value->UseCount());
63 2 : EXPECT_EQ(1, r_effect->UseCount());
64 2 : EXPECT_EQ(1, r_success->UseCount());
65 2 : EXPECT_EQ(1, r_exception->UseCount());
66 2 : EXPECT_THAT(r_value->uses(), ElementsAre(use_value));
67 2 : EXPECT_THAT(r_effect->uses(), ElementsAre(use_effect));
68 2 : EXPECT_THAT(r_success->uses(), ElementsAre(use_success));
69 2 : EXPECT_THAT(r_exception->uses(), ElementsAre(use_exception));
70 1 : }
71 :
72 :
73 15444 : TEST_F(NodePropertiesTest, FindProjection) {
74 1 : CommonOperatorBuilder common(zone());
75 1 : Node* start = NewMockNode(common.Start(1));
76 2 : Node* proj0 = NewMockNode(common.Projection(0), start);
77 2 : Node* proj1 = NewMockNode(common.Projection(1), start);
78 2 : EXPECT_EQ(proj0, NodeProperties::FindProjection(start, 0));
79 2 : EXPECT_EQ(proj1, NodeProperties::FindProjection(start, 1));
80 1 : EXPECT_THAT(NodeProperties::FindProjection(start, 2), IsNull());
81 1 : EXPECT_THAT(NodeProperties::FindProjection(start, 1234567890), IsNull());
82 1 : }
83 :
84 :
85 15444 : TEST_F(NodePropertiesTest, CollectControlProjections_Branch) {
86 : Node* result[2];
87 1 : CommonOperatorBuilder common(zone());
88 1 : Node* branch = NewMockNode(common.Branch());
89 2 : Node* if_false = NewMockNode(common.IfFalse(), branch);
90 2 : Node* if_true = NewMockNode(common.IfTrue(), branch);
91 1 : NodeProperties::CollectControlProjections(branch, result, arraysize(result));
92 1 : EXPECT_EQ(if_true, result[0]);
93 1 : EXPECT_EQ(if_false, result[1]);
94 1 : }
95 :
96 :
97 15444 : TEST_F(NodePropertiesTest, CollectControlProjections_Call) {
98 : Node* result[2];
99 1 : CommonOperatorBuilder common(zone());
100 : Node* call = NewMockNode(&kMockCallOperator);
101 2 : Node* if_ex = NewMockNode(common.IfException(), call, call);
102 2 : Node* if_ok = NewMockNode(common.IfSuccess(), call);
103 1 : NodeProperties::CollectControlProjections(call, result, arraysize(result));
104 1 : EXPECT_EQ(if_ok, result[0]);
105 1 : EXPECT_EQ(if_ex, result[1]);
106 1 : }
107 :
108 :
109 15444 : TEST_F(NodePropertiesTest, CollectControlProjections_Switch) {
110 : Node* result[3];
111 1 : CommonOperatorBuilder common(zone());
112 1 : Node* sw = NewMockNode(common.Switch(3));
113 2 : Node* if_default = NewMockNode(common.IfDefault(), sw);
114 1 : Node* if_value1 = NewMockNode(common.IfValue(1), sw);
115 1 : Node* if_value2 = NewMockNode(common.IfValue(2), sw);
116 1 : NodeProperties::CollectControlProjections(sw, result, arraysize(result));
117 1 : EXPECT_THAT(result[0], AnyOf(if_value1, if_value2));
118 1 : EXPECT_THAT(result[1], AnyOf(if_value1, if_value2));
119 1 : EXPECT_EQ(if_default, result[2]);
120 1 : }
121 :
122 : } // namespace node_properties_unittest
123 : } // namespace compiler
124 : } // namespace internal
125 9264 : } // namespace v8
|