blob: dbdd4bb62f68cc486b2d162140f30b9b5af8812e [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2014 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/graph.h"
6#include "src/compiler/graph-reducer.h"
7#include "src/compiler/operator.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008#include "test/unittests/test-utils.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "testing/gmock/include/gmock/gmock.h"
10
11using testing::_;
12using testing::DefaultValue;
13using testing::Return;
14using testing::Sequence;
15using testing::StrictMock;
16
17namespace v8 {
18namespace internal {
19namespace compiler {
20
Emily Bernierd0a1eb72015-03-24 16:35:39 -040021struct TestOperator : public Operator {
22 TestOperator(Operator::Opcode opcode, Operator::Properties properties,
23 size_t value_in, size_t value_out)
24 : Operator(opcode, properties, "TestOp", value_in, 0, 0, value_out, 0,
25 0) {}
26};
27
28
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029namespace {
30
Emily Bernierd0a1eb72015-03-24 16:35:39 -040031TestOperator OP0(0, Operator::kNoWrite, 0, 1);
32TestOperator OP1(1, Operator::kNoProperties, 1, 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033
34
35struct MockReducer : public Reducer {
36 MOCK_METHOD1(Reduce, Reduction(Node*));
37};
38
39} // namespace
40
41
42class GraphReducerTest : public TestWithZone {
43 public:
44 GraphReducerTest() : graph_(zone()) {}
45
46 static void SetUpTestCase() {
47 TestWithZone::SetUpTestCase();
48 DefaultValue<Reduction>::Set(Reducer::NoChange());
49 }
50
51 static void TearDownTestCase() {
52 DefaultValue<Reduction>::Clear();
53 TestWithZone::TearDownTestCase();
54 }
55
56 protected:
57 void ReduceNode(Node* node, Reducer* r) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040058 GraphReducer reducer(graph(), zone());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059 reducer.AddReducer(r);
60 reducer.ReduceNode(node);
61 }
62
63 void ReduceNode(Node* node, Reducer* r1, Reducer* r2) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040064 GraphReducer reducer(graph(), zone());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065 reducer.AddReducer(r1);
66 reducer.AddReducer(r2);
67 reducer.ReduceNode(node);
68 }
69
70 void ReduceNode(Node* node, Reducer* r1, Reducer* r2, Reducer* r3) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040071 GraphReducer reducer(graph(), zone());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000072 reducer.AddReducer(r1);
73 reducer.AddReducer(r2);
74 reducer.AddReducer(r3);
75 reducer.ReduceNode(node);
76 }
77
78 Graph* graph() { return &graph_; }
79
80 private:
81 Graph graph_;
82};
83
84
85TEST_F(GraphReducerTest, NodeIsDeadAfterReplace) {
86 StrictMock<MockReducer> r;
87 Node* node0 = graph()->NewNode(&OP0);
88 Node* node1 = graph()->NewNode(&OP1, node0);
89 Node* node2 = graph()->NewNode(&OP1, node0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040090 EXPECT_CALL(r, Reduce(node0)).WillOnce(Return(Reducer::NoChange()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 EXPECT_CALL(r, Reduce(node1)).WillOnce(Return(Reducer::Replace(node2)));
92 ReduceNode(node1, &r);
93 EXPECT_FALSE(node0->IsDead());
94 EXPECT_TRUE(node1->IsDead());
95 EXPECT_FALSE(node2->IsDead());
96}
97
98
99TEST_F(GraphReducerTest, ReduceOnceForEveryReducer) {
100 StrictMock<MockReducer> r1, r2;
101 Node* node0 = graph()->NewNode(&OP0);
102 EXPECT_CALL(r1, Reduce(node0));
103 EXPECT_CALL(r2, Reduce(node0));
104 ReduceNode(node0, &r1, &r2);
105}
106
107
108TEST_F(GraphReducerTest, ReduceAgainAfterChanged) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400109 Sequence s1, s2, s3;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110 StrictMock<MockReducer> r1, r2, r3;
111 Node* node0 = graph()->NewNode(&OP0);
112 EXPECT_CALL(r1, Reduce(node0));
113 EXPECT_CALL(r2, Reduce(node0));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400114 EXPECT_CALL(r3, Reduce(node0)).InSequence(s1, s2, s3).WillOnce(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115 Return(Reducer::Changed(node0)));
116 EXPECT_CALL(r1, Reduce(node0)).InSequence(s1);
117 EXPECT_CALL(r2, Reduce(node0)).InSequence(s2);
118 ReduceNode(node0, &r1, &r2, &r3);
119}
120
121} // namespace compiler
122} // namespace internal
123} // namespace v8