Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: test/unittests/compiler/graph-reducer-unittest.cc

Issue 1122423003: [turbofan] Add support for advanced reducers. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Move comment Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/unittests/compiler/graph-reducer-unittest.h ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/graph.h" 5 #include "src/compiler/graph.h"
6 #include "src/compiler/graph-reducer.h"
7 #include "src/compiler/node.h" 6 #include "src/compiler/node.h"
8 #include "src/compiler/operator.h" 7 #include "src/compiler/operator.h"
8 #include "test/unittests/compiler/graph-reducer-unittest.h"
9 #include "test/unittests/test-utils.h" 9 #include "test/unittests/test-utils.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 10
12 using testing::_; 11 using testing::_;
13 using testing::DefaultValue; 12 using testing::DefaultValue;
14 using testing::Return; 13 using testing::Return;
15 using testing::Sequence; 14 using testing::Sequence;
16 using testing::StrictMock; 15 using testing::StrictMock;
17 16
18 namespace v8 { 17 namespace v8 {
19 namespace internal { 18 namespace internal {
20 namespace compiler { 19 namespace compiler {
(...skipping 27 matching lines...) Expand all
48 static TestOperator kOpC0(kOpcodeC0, Operator::kNoWrite, "opc0", 0, 0); 47 static TestOperator kOpC0(kOpcodeC0, Operator::kNoWrite, "opc0", 0, 0);
49 static TestOperator kOpC1(kOpcodeC1, Operator::kNoWrite, "opc1", 1, 0); 48 static TestOperator kOpC1(kOpcodeC1, Operator::kNoWrite, "opc1", 1, 0);
50 static TestOperator kOpC2(kOpcodeC2, Operator::kNoWrite, "opc2", 2, 0); 49 static TestOperator kOpC2(kOpcodeC2, Operator::kNoWrite, "opc2", 2, 0);
51 50
52 struct MockReducer : public Reducer { 51 struct MockReducer : public Reducer {
53 MOCK_METHOD1(Reduce, Reduction(Node*)); 52 MOCK_METHOD1(Reduce, Reduction(Node*));
54 }; 53 };
55 54
56 55
57 // Replaces all "A" operators with "B" operators without creating new nodes. 56 // Replaces all "A" operators with "B" operators without creating new nodes.
58 class InPlaceABReducer : public Reducer { 57 class InPlaceABReducer final : public Reducer {
59 public: 58 public:
60 virtual Reduction Reduce(Node* node) { 59 Reduction Reduce(Node* node) final {
61 switch (node->op()->opcode()) { 60 switch (node->op()->opcode()) {
62 case kOpcodeA0: 61 case kOpcodeA0:
63 EXPECT_EQ(0, node->InputCount()); 62 EXPECT_EQ(0, node->InputCount());
64 node->set_op(&kOpB0); 63 node->set_op(&kOpB0);
65 return Replace(node); 64 return Replace(node);
66 case kOpcodeA1: 65 case kOpcodeA1:
67 EXPECT_EQ(1, node->InputCount()); 66 EXPECT_EQ(1, node->InputCount());
68 node->set_op(&kOpB1); 67 node->set_op(&kOpB1);
69 return Replace(node); 68 return Replace(node);
70 case kOpcodeA2: 69 case kOpcodeA2:
71 EXPECT_EQ(2, node->InputCount()); 70 EXPECT_EQ(2, node->InputCount());
72 node->set_op(&kOpB2); 71 node->set_op(&kOpB2);
73 return Replace(node); 72 return Replace(node);
74 } 73 }
75 return NoChange(); 74 return NoChange();
76 } 75 }
77 }; 76 };
78 77
79 78
80 // Replaces all "A" operators with "B" operators by allocating new nodes. 79 // Replaces all "A" operators with "B" operators by allocating new nodes.
81 class NewABReducer : public Reducer { 80 class NewABReducer final : public Reducer {
82 public: 81 public:
83 explicit NewABReducer(Graph* graph) : graph_(graph) {} 82 explicit NewABReducer(Graph* graph) : graph_(graph) {}
84 virtual Reduction Reduce(Node* node) { 83
84 Reduction Reduce(Node* node) final {
85 switch (node->op()->opcode()) { 85 switch (node->op()->opcode()) {
86 case kOpcodeA0: 86 case kOpcodeA0:
87 EXPECT_EQ(0, node->InputCount()); 87 EXPECT_EQ(0, node->InputCount());
88 return Replace(graph_->NewNode(&kOpB0)); 88 return Replace(graph_->NewNode(&kOpB0));
89 case kOpcodeA1: 89 case kOpcodeA1:
90 EXPECT_EQ(1, node->InputCount()); 90 EXPECT_EQ(1, node->InputCount());
91 return Replace(graph_->NewNode(&kOpB1, node->InputAt(0))); 91 return Replace(graph_->NewNode(&kOpB1, node->InputAt(0)));
92 case kOpcodeA2: 92 case kOpcodeA2:
93 EXPECT_EQ(2, node->InputCount()); 93 EXPECT_EQ(2, node->InputCount());
94 return Replace( 94 return Replace(
95 graph_->NewNode(&kOpB2, node->InputAt(0), node->InputAt(1))); 95 graph_->NewNode(&kOpB2, node->InputAt(0), node->InputAt(1)));
96 } 96 }
97 return NoChange(); 97 return NoChange();
98 } 98 }
99 Graph* graph_; 99
100 private:
101 Graph* const graph_;
100 }; 102 };
101 103
102 104
103 // Wraps all "kOpA0" nodes in "kOpB1" operators by allocating new nodes. 105 // Wraps all "kOpA0" nodes in "kOpB1" operators by allocating new nodes.
104 class A0Wrapper final : public Reducer { 106 class A0Wrapper final : public Reducer {
105 public: 107 public:
106 explicit A0Wrapper(Graph* graph) : graph_(graph) {} 108 explicit A0Wrapper(Graph* graph) : graph_(graph) {}
107 virtual Reduction Reduce(Node* node) override { 109
110 Reduction Reduce(Node* node) final {
108 switch (node->op()->opcode()) { 111 switch (node->op()->opcode()) {
109 case kOpcodeA0: 112 case kOpcodeA0:
110 EXPECT_EQ(0, node->InputCount()); 113 EXPECT_EQ(0, node->InputCount());
111 return Replace(graph_->NewNode(&kOpB1, node)); 114 return Replace(graph_->NewNode(&kOpB1, node));
112 } 115 }
113 return NoChange(); 116 return NoChange();
114 } 117 }
115 Graph* graph_; 118
119 private:
120 Graph* const graph_;
116 }; 121 };
117 122
118 123
119 // Wraps all "kOpB0" nodes in two "kOpC1" operators by allocating new nodes. 124 // Wraps all "kOpB0" nodes in two "kOpC1" operators by allocating new nodes.
120 class B0Wrapper final : public Reducer { 125 class B0Wrapper final : public Reducer {
121 public: 126 public:
122 explicit B0Wrapper(Graph* graph) : graph_(graph) {} 127 explicit B0Wrapper(Graph* graph) : graph_(graph) {}
123 virtual Reduction Reduce(Node* node) override { 128
129 Reduction Reduce(Node* node) final {
124 switch (node->op()->opcode()) { 130 switch (node->op()->opcode()) {
125 case kOpcodeB0: 131 case kOpcodeB0:
126 EXPECT_EQ(0, node->InputCount()); 132 EXPECT_EQ(0, node->InputCount());
127 return Replace(graph_->NewNode(&kOpC1, graph_->NewNode(&kOpC1, node))); 133 return Replace(graph_->NewNode(&kOpC1, graph_->NewNode(&kOpC1, node)));
128 } 134 }
129 return NoChange(); 135 return NoChange();
130 } 136 }
131 Graph* graph_; 137
138 private:
139 Graph* const graph_;
132 }; 140 };
133 141
134 142
135 // Replaces all "kOpA1" nodes with the first input. 143 // Replaces all "kOpA1" nodes with the first input.
136 class A1Forwarder : public Reducer { 144 class A1Forwarder final : public Reducer {
137 virtual Reduction Reduce(Node* node) { 145 public:
146 Reduction Reduce(Node* node) final {
138 switch (node->op()->opcode()) { 147 switch (node->op()->opcode()) {
139 case kOpcodeA1: 148 case kOpcodeA1:
140 EXPECT_EQ(1, node->InputCount()); 149 EXPECT_EQ(1, node->InputCount());
141 return Replace(node->InputAt(0)); 150 return Replace(node->InputAt(0));
142 } 151 }
143 return NoChange(); 152 return NoChange();
144 } 153 }
145 }; 154 };
146 155
147 156
148 // Replaces all "kOpB1" nodes with the first input. 157 // Replaces all "kOpB1" nodes with the first input.
149 class B1Forwarder : public Reducer { 158 class B1Forwarder final : public Reducer {
150 virtual Reduction Reduce(Node* node) { 159 public:
160 Reduction Reduce(Node* node) final {
151 switch (node->op()->opcode()) { 161 switch (node->op()->opcode()) {
152 case kOpcodeB1: 162 case kOpcodeB1:
153 EXPECT_EQ(1, node->InputCount()); 163 EXPECT_EQ(1, node->InputCount());
154 return Replace(node->InputAt(0)); 164 return Replace(node->InputAt(0));
155 } 165 }
156 return NoChange(); 166 return NoChange();
157 } 167 }
158 }; 168 };
159 169
160 170
161 // Replaces all "B" operators with "C" operators without creating new nodes. 171 // Replaces all "B" operators with "C" operators without creating new nodes.
162 class InPlaceBCReducer : public Reducer { 172 class InPlaceBCReducer final : public Reducer {
163 public: 173 public:
164 virtual Reduction Reduce(Node* node) { 174 Reduction Reduce(Node* node) final {
165 switch (node->op()->opcode()) { 175 switch (node->op()->opcode()) {
166 case kOpcodeB0: 176 case kOpcodeB0:
167 EXPECT_EQ(0, node->InputCount()); 177 EXPECT_EQ(0, node->InputCount());
168 node->set_op(&kOpC0); 178 node->set_op(&kOpC0);
169 return Replace(node); 179 return Replace(node);
170 case kOpcodeB1: 180 case kOpcodeB1:
171 EXPECT_EQ(1, node->InputCount()); 181 EXPECT_EQ(1, node->InputCount());
172 node->set_op(&kOpC1); 182 node->set_op(&kOpC1);
173 return Replace(node); 183 return Replace(node);
174 case kOpcodeB2: 184 case kOpcodeB2:
175 EXPECT_EQ(2, node->InputCount()); 185 EXPECT_EQ(2, node->InputCount());
176 node->set_op(&kOpC2); 186 node->set_op(&kOpC2);
177 return Replace(node); 187 return Replace(node);
178 } 188 }
179 return NoChange(); 189 return NoChange();
180 } 190 }
181 }; 191 };
182 192
183 193
184 // Swaps the inputs to "kOp2A" and "kOp2B" nodes based on ids. 194 // Swaps the inputs to "kOp2A" and "kOp2B" nodes based on ids.
185 class AB2Sorter : public Reducer { 195 class AB2Sorter final : public Reducer {
186 virtual Reduction Reduce(Node* node) { 196 public:
197 Reduction Reduce(Node* node) final {
187 switch (node->op()->opcode()) { 198 switch (node->op()->opcode()) {
188 case kOpcodeA2: 199 case kOpcodeA2:
189 case kOpcodeB2: 200 case kOpcodeB2:
190 EXPECT_EQ(2, node->InputCount()); 201 EXPECT_EQ(2, node->InputCount());
191 Node* x = node->InputAt(0); 202 Node* x = node->InputAt(0);
192 Node* y = node->InputAt(1); 203 Node* y = node->InputAt(1);
193 if (x->id() > y->id()) { 204 if (x->id() > y->id()) {
194 node->ReplaceInput(0, y); 205 node->ReplaceInput(0, y);
195 node->ReplaceInput(1, x); 206 node->ReplaceInput(1, x);
196 return Replace(node); 207 return Replace(node);
197 } 208 }
198 } 209 }
199 return NoChange(); 210 return NoChange();
200 } 211 }
201 }; 212 };
202 213
214 } // namespace
203 215
204 } // namespace 216
217 class AdvancedReducerTest : public TestWithZone {
218 public:
219 AdvancedReducerTest() : graph_(zone()) {}
220
221 protected:
222 Graph* graph() { return &graph_; }
223
224 private:
225 Graph graph_;
226 };
227
228
229 TEST_F(AdvancedReducerTest, Replace) {
230 struct DummyReducer final : public AdvancedReducer {
231 explicit DummyReducer(Editor* editor) : AdvancedReducer(editor) {}
232 Reduction Reduce(Node* node) final {
233 Replace(node, node);
234 return NoChange();
235 }
236 };
237 StrictMock<MockAdvancedReducerEditor> e;
238 DummyReducer r(&e);
239 Node* node0 = graph()->NewNode(&kOpA0);
240 Node* node1 = graph()->NewNode(&kOpA1, node0);
241 EXPECT_CALL(e, Replace(node0, node0));
242 EXPECT_CALL(e, Replace(node1, node1));
243 EXPECT_FALSE(r.Reduce(node0).Changed());
244 EXPECT_FALSE(r.Reduce(node1).Changed());
245 }
246
247
248 TEST_F(AdvancedReducerTest, Revisit) {
249 struct DummyReducer final : public AdvancedReducer {
250 explicit DummyReducer(Editor* editor) : AdvancedReducer(editor) {}
251 Reduction Reduce(Node* node) final {
252 Revisit(node);
253 return NoChange();
254 }
255 };
256 StrictMock<MockAdvancedReducerEditor> e;
257 DummyReducer r(&e);
258 Node* node0 = graph()->NewNode(&kOpA0);
259 Node* node1 = graph()->NewNode(&kOpA1, node0);
260 EXPECT_CALL(e, Revisit(node0));
261 EXPECT_CALL(e, Revisit(node1));
262 EXPECT_FALSE(r.Reduce(node0).Changed());
263 EXPECT_FALSE(r.Reduce(node1).Changed());
264 }
205 265
206 266
207 class GraphReducerTest : public TestWithZone { 267 class GraphReducerTest : public TestWithZone {
208 public: 268 public:
209 GraphReducerTest() : graph_(zone()) {} 269 GraphReducerTest() : graph_(zone()) {}
210 270
211 static void SetUpTestCase() { 271 static void SetUpTestCase() {
212 TestWithZone::SetUpTestCase(); 272 TestWithZone::SetUpTestCase();
213 DefaultValue<Reduction>::Set(Reducer::NoChange()); 273 DefaultValue<Reduction>::Set(Reducer::NoChange());
214 } 274 }
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 EXPECT_EQ(&kOpA0, n1->op()); 626 EXPECT_EQ(&kOpA0, n1->op());
567 EXPECT_EQ(&kOpA1, n2->op()); 627 EXPECT_EQ(&kOpA1, n2->op());
568 EXPECT_EQ(&kOpA1, n3->op()); 628 EXPECT_EQ(&kOpA1, n3->op());
569 EXPECT_EQ(&kOpA2, end->op()); 629 EXPECT_EQ(&kOpA2, end->op());
570 EXPECT_EQ(end, graph()->end()); 630 EXPECT_EQ(end, graph()->end());
571 EXPECT_LE(end->InputAt(0)->id(), end->InputAt(1)->id()); 631 EXPECT_LE(end->InputAt(0)->id(), end->InputAt(1)->id());
572 } 632 }
573 } 633 }
574 634
575 635
636 namespace {
637
576 // Generate a node graph with the given permutations. 638 // Generate a node graph with the given permutations.
577 void GenDAG(Graph* graph, int* p3, int* p2, int* p1) { 639 void GenDAG(Graph* graph, int* p3, int* p2, int* p1) {
578 Node* level4 = graph->NewNode(&kOpA0); 640 Node* level4 = graph->NewNode(&kOpA0);
579 Node* level3[] = {graph->NewNode(&kOpA1, level4), 641 Node* level3[] = {graph->NewNode(&kOpA1, level4),
580 graph->NewNode(&kOpA1, level4)}; 642 graph->NewNode(&kOpA1, level4)};
581 643
582 Node* level2[] = {graph->NewNode(&kOpA1, level3[p3[0]]), 644 Node* level2[] = {graph->NewNode(&kOpA1, level3[p3[0]]),
583 graph->NewNode(&kOpA1, level3[p3[1]]), 645 graph->NewNode(&kOpA1, level3[p3[1]]),
584 graph->NewNode(&kOpA1, level3[p3[0]]), 646 graph->NewNode(&kOpA1, level3[p3[0]]),
585 graph->NewNode(&kOpA1, level3[p3[1]])}; 647 graph->NewNode(&kOpA1, level3[p3[1]])};
586 648
587 Node* level1[] = {graph->NewNode(&kOpA2, level2[p2[0]], level2[p2[1]]), 649 Node* level1[] = {graph->NewNode(&kOpA2, level2[p2[0]], level2[p2[1]]),
588 graph->NewNode(&kOpA2, level2[p2[2]], level2[p2[3]])}; 650 graph->NewNode(&kOpA2, level2[p2[2]], level2[p2[3]])};
589 651
590 Node* end = graph->NewNode(&kOpA2, level1[p1[0]], level1[p1[1]]); 652 Node* end = graph->NewNode(&kOpA2, level1[p1[0]], level1[p1[1]]);
591 graph->SetEnd(end); 653 graph->SetEnd(end);
592 } 654 }
593 655
656 } // namespace
657
594 658
595 TEST_F(GraphReducerTest, SortForwardReduce) { 659 TEST_F(GraphReducerTest, SortForwardReduce) {
596 // Tests combined reductions on a series of DAGs. 660 // Tests combined reductions on a series of DAGs.
597 for (int j = 0; j < 2; j++) { 661 for (int j = 0; j < 2; j++) {
598 int p3[] = {j, 1 - j}; 662 int p3[] = {j, 1 - j};
599 for (int m = 0; m < 2; m++) { 663 for (int m = 0; m < 2; m++) {
600 int p1[] = {m, 1 - m}; 664 int p1[] = {m, 1 - m};
601 for (int k = 0; k < 24; k++) { // All permutations of 0, 1, 2, 3 665 for (int k = 0; k < 24; k++) { // All permutations of 0, 1, 2, 3
602 int p2[] = {-1, -1, -1, -1}; 666 int p2[] = {-1, -1, -1, -1};
603 int n = k; 667 int n = k;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 } 724 }
661 725
662 EXPECT_EQ(before, graph()->NodeCount()); 726 EXPECT_EQ(before, graph()->NodeCount());
663 EXPECT_EQ(&kOpC0, n1->op()); 727 EXPECT_EQ(&kOpC0, n1->op());
664 EXPECT_EQ(&kOpC1, end->op()); 728 EXPECT_EQ(&kOpC1, end->op());
665 EXPECT_EQ(n1, end->InputAt(0)); 729 EXPECT_EQ(n1, end->InputAt(0));
666 } 730 }
667 } 731 }
668 } 732 }
669 733
670
671 } // namespace compiler 734 } // namespace compiler
672 } // namespace internal 735 } // namespace internal
673 } // namespace v8 736 } // namespace v8
OLDNEW
« no previous file with comments | « test/unittests/compiler/graph-reducer-unittest.h ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698