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