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

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

Issue 867583002: Convert compiler cctest to unit tests, part 1 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review feedback Created 5 years, 11 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/cctest/compiler/test-graph-reducer.cc ('k') | no next file » | 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" 6 #include "src/compiler/graph-reducer.h"
7 #include "src/compiler/node.h" 7 #include "src/compiler/node.h"
8 #include "src/compiler/operator.h" 8 #include "src/compiler/operator.h"
9 #include "test/unittests/test-utils.h" 9 #include "test/unittests/test-utils.h"
10 #include "testing/gmock/include/gmock/gmock.h" 10 #include "testing/gmock/include/gmock/gmock.h"
11 11
12 using testing::_; 12 using testing::_;
13 using testing::DefaultValue; 13 using testing::DefaultValue;
14 using testing::Return; 14 using testing::Return;
15 using testing::Sequence; 15 using testing::Sequence;
16 using testing::StrictMock; 16 using testing::StrictMock;
17 17
18 namespace v8 { 18 namespace v8 {
19 namespace internal { 19 namespace internal {
20 namespace compiler { 20 namespace compiler {
21 21
22 namespace {
23
22 struct TestOperator : public Operator { 24 struct TestOperator : public Operator {
23 TestOperator(Operator::Opcode opcode, Operator::Properties properties, 25 TestOperator(Operator::Opcode opcode, Operator::Properties properties,
24 size_t value_in, size_t value_out) 26 const char* op_name, size_t value_in, size_t value_out)
25 : Operator(opcode, properties, "TestOp", value_in, 0, 0, value_out, 0, 27 : Operator(opcode, properties, op_name, value_in, 0, 0, value_out, 0, 0) {
26 0) {} 28 }
27 }; 29 };
28 30
29 31
30 namespace { 32 const uint8_t kOpcodeA0 = 10;
33 const uint8_t kOpcodeA1 = 11;
34 const uint8_t kOpcodeA2 = 12;
35 const uint8_t kOpcodeB0 = 20;
36 const uint8_t kOpcodeB1 = 21;
37 const uint8_t kOpcodeB2 = 22;
38 const uint8_t kOpcodeC0 = 30;
39 const uint8_t kOpcodeC1 = 31;
40 const uint8_t kOpcodeC2 = 32;
31 41
32 TestOperator OP0(0, Operator::kNoWrite, 0, 1); 42 static TestOperator kOpA0(kOpcodeA0, Operator::kNoWrite, "opa1", 0, 1);
33 TestOperator OP1(1, Operator::kNoProperties, 1, 1); 43 static TestOperator kOpA1(kOpcodeA1, Operator::kNoProperties, "opa2", 1, 1);
34 44 static TestOperator kOpA2(kOpcodeA2, Operator::kNoProperties, "opa3", 2, 1);
45 static TestOperator kOpB0(kOpcodeB0, Operator::kNoWrite, "opa0", 0, 0);
46 static TestOperator kOpB1(kOpcodeB1, Operator::kNoWrite, "opa1", 1, 0);
47 static TestOperator kOpB2(kOpcodeB2, Operator::kNoWrite, "opa2", 2, 0);
48 static TestOperator kOpC0(kOpcodeC0, Operator::kNoWrite, "opc0", 0, 0);
49 static TestOperator kOpC1(kOpcodeC1, Operator::kNoWrite, "opc1", 1, 0);
50 static TestOperator kOpC2(kOpcodeC2, Operator::kNoWrite, "opc2", 2, 0);
35 51
36 struct MockReducer : public Reducer { 52 struct MockReducer : public Reducer {
37 MOCK_METHOD1(Reduce, Reduction(Node*)); 53 MOCK_METHOD1(Reduce, Reduction(Node*));
38 }; 54 };
39 55
56
57 // Replaces all "A" operators with "B" operators without creating new nodes.
58 class InPlaceABReducer : public Reducer {
59 public:
60 virtual Reduction Reduce(Node* node) {
61 switch (node->op()->opcode()) {
62 case kOpcodeA0:
63 EXPECT_EQ(0, node->InputCount());
64 node->set_op(&kOpB0);
65 return Replace(node);
66 case kOpcodeA1:
67 EXPECT_EQ(1, node->InputCount());
68 node->set_op(&kOpB1);
69 return Replace(node);
70 case kOpcodeA2:
71 EXPECT_EQ(2, node->InputCount());
72 node->set_op(&kOpB2);
73 return Replace(node);
74 }
75 return NoChange();
76 }
77 };
78
79
80 // Replaces all "A" operators with "B" operators by allocating new nodes.
81 class NewABReducer : public Reducer {
82 public:
83 explicit NewABReducer(Graph* graph) : graph_(graph) {}
84 virtual Reduction Reduce(Node* node) {
85 switch (node->op()->opcode()) {
86 case kOpcodeA0:
87 EXPECT_EQ(0, node->InputCount());
88 return Replace(graph_->NewNode(&kOpB0));
89 case kOpcodeA1:
90 EXPECT_EQ(1, node->InputCount());
91 return Replace(graph_->NewNode(&kOpB1, node->InputAt(0)));
92 case kOpcodeA2:
93 EXPECT_EQ(2, node->InputCount());
94 return Replace(
95 graph_->NewNode(&kOpB2, node->InputAt(0), node->InputAt(1)));
96 }
97 return NoChange();
98 }
99 Graph* graph_;
100 };
101
102
103 // Wraps all "kOpA0" nodes in "kOpB1" operators by allocating new nodes.
104 class A0Wrapper FINAL : public Reducer {
105 public:
106 explicit A0Wrapper(Graph* graph) : graph_(graph) {}
107 virtual Reduction Reduce(Node* node) OVERRIDE {
108 switch (node->op()->opcode()) {
109 case kOpcodeA0:
110 EXPECT_EQ(0, node->InputCount());
111 return Replace(graph_->NewNode(&kOpB1, node));
112 }
113 return NoChange();
114 }
115 Graph* graph_;
116 };
117
118
119 // Wraps all "kOpB0" nodes in two "kOpC1" operators by allocating new nodes.
120 class B0Wrapper FINAL : public Reducer {
121 public:
122 explicit B0Wrapper(Graph* graph) : graph_(graph) {}
123 virtual Reduction Reduce(Node* node) OVERRIDE {
124 switch (node->op()->opcode()) {
125 case kOpcodeB0:
126 EXPECT_EQ(0, node->InputCount());
127 return Replace(graph_->NewNode(&kOpC1, graph_->NewNode(&kOpC1, node)));
128 }
129 return NoChange();
130 }
131 Graph* graph_;
132 };
133
134
135 // Replaces all "kOpA1" nodes with the first input.
136 class A1Forwarder : public Reducer {
137 virtual Reduction Reduce(Node* node) {
138 switch (node->op()->opcode()) {
139 case kOpcodeA1:
140 EXPECT_EQ(1, node->InputCount());
141 return Replace(node->InputAt(0));
142 }
143 return NoChange();
144 }
145 };
146
147
148 // Replaces all "kOpB1" nodes with the first input.
149 class B1Forwarder : public Reducer {
150 virtual Reduction Reduce(Node* node) {
151 switch (node->op()->opcode()) {
152 case kOpcodeB1:
153 EXPECT_EQ(1, node->InputCount());
154 return Replace(node->InputAt(0));
155 }
156 return NoChange();
157 }
158 };
159
160
161 // Replaces all "B" operators with "C" operators without creating new nodes.
162 class InPlaceBCReducer : public Reducer {
163 public:
164 virtual Reduction Reduce(Node* node) {
165 switch (node->op()->opcode()) {
166 case kOpcodeB0:
167 EXPECT_EQ(0, node->InputCount());
168 node->set_op(&kOpC0);
169 return Replace(node);
170 case kOpcodeB1:
171 EXPECT_EQ(1, node->InputCount());
172 node->set_op(&kOpC1);
173 return Replace(node);
174 case kOpcodeB2:
175 EXPECT_EQ(2, node->InputCount());
176 node->set_op(&kOpC2);
177 return Replace(node);
178 }
179 return NoChange();
180 }
181 };
182
183
184 // Swaps the inputs to "kOp2A" and "kOp2B" nodes based on ids.
185 class AB2Sorter : public Reducer {
186 virtual Reduction Reduce(Node* node) {
187 switch (node->op()->opcode()) {
188 case kOpcodeA2:
189 case kOpcodeB2:
190 EXPECT_EQ(2, node->InputCount());
191 Node* x = node->InputAt(0);
192 Node* y = node->InputAt(1);
193 if (x->id() > y->id()) {
194 node->ReplaceInput(0, y);
195 node->ReplaceInput(1, x);
196 return Replace(node);
197 }
198 }
199 return NoChange();
200 }
201 };
202
203
40 } // namespace 204 } // namespace
41 205
42 206
43 class GraphReducerTest : public TestWithZone { 207 class GraphReducerTest : public TestWithZone {
44 public: 208 public:
45 GraphReducerTest() : graph_(zone()) {} 209 GraphReducerTest() : graph_(zone()) {}
46 210
47 static void SetUpTestCase() { 211 static void SetUpTestCase() {
48 TestWithZone::SetUpTestCase(); 212 TestWithZone::SetUpTestCase();
49 DefaultValue<Reduction>::Set(Reducer::NoChange()); 213 DefaultValue<Reduction>::Set(Reducer::NoChange());
(...skipping 19 matching lines...) Expand all
69 } 233 }
70 234
71 void ReduceNode(Node* node, Reducer* r1, Reducer* r2, Reducer* r3) { 235 void ReduceNode(Node* node, Reducer* r1, Reducer* r2, Reducer* r3) {
72 GraphReducer reducer(graph(), zone()); 236 GraphReducer reducer(graph(), zone());
73 reducer.AddReducer(r1); 237 reducer.AddReducer(r1);
74 reducer.AddReducer(r2); 238 reducer.AddReducer(r2);
75 reducer.AddReducer(r3); 239 reducer.AddReducer(r3);
76 reducer.ReduceNode(node); 240 reducer.ReduceNode(node);
77 } 241 }
78 242
243 void ReduceGraph(Reducer* r1) {
244 GraphReducer reducer(graph(), zone());
245 reducer.AddReducer(r1);
246 reducer.ReduceGraph();
247 }
248
249 void ReduceGraph(Reducer* r1, Reducer* r2) {
250 GraphReducer reducer(graph(), zone());
251 reducer.AddReducer(r1);
252 reducer.AddReducer(r2);
253 reducer.ReduceGraph();
254 }
255
256 void ReduceGraph(Reducer* r1, Reducer* r2, Reducer* r3) {
257 GraphReducer reducer(graph(), zone());
258 reducer.AddReducer(r1);
259 reducer.AddReducer(r2);
260 reducer.AddReducer(r3);
261 reducer.ReduceGraph();
262 }
263
79 Graph* graph() { return &graph_; } 264 Graph* graph() { return &graph_; }
80 265
81 private: 266 private:
82 Graph graph_; 267 Graph graph_;
83 }; 268 };
84 269
85 270
86 TEST_F(GraphReducerTest, NodeIsDeadAfterReplace) { 271 TEST_F(GraphReducerTest, NodeIsDeadAfterReplace) {
87 StrictMock<MockReducer> r; 272 StrictMock<MockReducer> r;
88 Node* node0 = graph()->NewNode(&OP0); 273 Node* node0 = graph()->NewNode(&kOpA0);
89 Node* node1 = graph()->NewNode(&OP1, node0); 274 Node* node1 = graph()->NewNode(&kOpA1, node0);
90 Node* node2 = graph()->NewNode(&OP1, node0); 275 Node* node2 = graph()->NewNode(&kOpA1, node0);
91 EXPECT_CALL(r, Reduce(node0)).WillOnce(Return(Reducer::NoChange())); 276 EXPECT_CALL(r, Reduce(node0)).WillOnce(Return(Reducer::NoChange()));
92 EXPECT_CALL(r, Reduce(node1)).WillOnce(Return(Reducer::Replace(node2))); 277 EXPECT_CALL(r, Reduce(node1)).WillOnce(Return(Reducer::Replace(node2)));
93 ReduceNode(node1, &r); 278 ReduceNode(node1, &r);
94 EXPECT_FALSE(node0->IsDead()); 279 EXPECT_FALSE(node0->IsDead());
95 EXPECT_TRUE(node1->IsDead()); 280 EXPECT_TRUE(node1->IsDead());
96 EXPECT_FALSE(node2->IsDead()); 281 EXPECT_FALSE(node2->IsDead());
97 } 282 }
98 283
99 284
100 TEST_F(GraphReducerTest, ReduceOnceForEveryReducer) { 285 TEST_F(GraphReducerTest, ReduceOnceForEveryReducer) {
101 StrictMock<MockReducer> r1, r2; 286 StrictMock<MockReducer> r1, r2;
102 Node* node0 = graph()->NewNode(&OP0); 287 Node* node0 = graph()->NewNode(&kOpA0);
103 EXPECT_CALL(r1, Reduce(node0)); 288 EXPECT_CALL(r1, Reduce(node0));
104 EXPECT_CALL(r2, Reduce(node0)); 289 EXPECT_CALL(r2, Reduce(node0));
105 ReduceNode(node0, &r1, &r2); 290 ReduceNode(node0, &r1, &r2);
106 } 291 }
107 292
108 293
109 TEST_F(GraphReducerTest, ReduceAgainAfterChanged) { 294 TEST_F(GraphReducerTest, ReduceAgainAfterChanged) {
110 Sequence s1, s2, s3; 295 Sequence s1, s2, s3;
111 StrictMock<MockReducer> r1, r2, r3; 296 StrictMock<MockReducer> r1, r2, r3;
112 Node* node0 = graph()->NewNode(&OP0); 297 Node* node0 = graph()->NewNode(&kOpA0);
113 EXPECT_CALL(r1, Reduce(node0)); 298 EXPECT_CALL(r1, Reduce(node0));
114 EXPECT_CALL(r2, Reduce(node0)); 299 EXPECT_CALL(r2, Reduce(node0));
115 EXPECT_CALL(r3, Reduce(node0)).InSequence(s1, s2, s3).WillOnce( 300 EXPECT_CALL(r3, Reduce(node0)).InSequence(s1, s2, s3).WillOnce(
116 Return(Reducer::Changed(node0))); 301 Return(Reducer::Changed(node0)));
117 EXPECT_CALL(r1, Reduce(node0)).InSequence(s1); 302 EXPECT_CALL(r1, Reduce(node0)).InSequence(s1);
118 EXPECT_CALL(r2, Reduce(node0)).InSequence(s2); 303 EXPECT_CALL(r2, Reduce(node0)).InSequence(s2);
119 ReduceNode(node0, &r1, &r2, &r3); 304 ReduceNode(node0, &r1, &r2, &r3);
120 } 305 }
121 306
307
308 TEST_F(GraphReducerTest, ReduceGraphFromEnd1) {
309 StrictMock<MockReducer> r1;
310 Node* n = graph()->NewNode(&kOpA0);
311 Node* end = graph()->NewNode(&kOpA1, n);
312 graph()->SetEnd(end);
313 Sequence s;
314 EXPECT_CALL(r1, Reduce(n));
315 EXPECT_CALL(r1, Reduce(end));
316 ReduceGraph(&r1);
317 }
318
319
320 TEST_F(GraphReducerTest, ReduceGraphFromEnd2) {
321 StrictMock<MockReducer> r1;
322 Node* n1 = graph()->NewNode(&kOpA0);
323 Node* n2 = graph()->NewNode(&kOpA1, n1);
324 Node* n3 = graph()->NewNode(&kOpA1, n1);
325 Node* end = graph()->NewNode(&kOpA2, n2, n3);
326 graph()->SetEnd(end);
327 Sequence s1, s2;
328 EXPECT_CALL(r1, Reduce(n1)).InSequence(s1, s2);
329 EXPECT_CALL(r1, Reduce(n2)).InSequence(s1);
330 EXPECT_CALL(r1, Reduce(n3)).InSequence(s2);
331 EXPECT_CALL(r1, Reduce(end)).InSequence(s1, s2);
332 ReduceGraph(&r1);
333 }
334
335
336 TEST_F(GraphReducerTest, ReduceInPlace1) {
337 Node* n1 = graph()->NewNode(&kOpA0);
338 Node* end = graph()->NewNode(&kOpA1, n1);
339 graph()->SetEnd(end);
340
341 // Tests A* => B* with in-place updates.
342 InPlaceABReducer r;
343 for (int i = 0; i < 3; i++) {
344 int before = graph()->NodeCount();
345 ReduceGraph(&r);
346 EXPECT_EQ(before, graph()->NodeCount());
347 EXPECT_EQ(&kOpB0, n1->op());
348 EXPECT_EQ(&kOpB1, end->op());
349 EXPECT_EQ(n1, end->InputAt(0));
350 }
351 }
352
353
354 TEST_F(GraphReducerTest, ReduceInPlace2) {
355 Node* n1 = graph()->NewNode(&kOpA0);
356 Node* n2 = graph()->NewNode(&kOpA1, n1);
357 Node* n3 = graph()->NewNode(&kOpA1, n1);
358 Node* end = graph()->NewNode(&kOpA2, n2, n3);
359 graph()->SetEnd(end);
360
361 // Tests A* => B* with in-place updates.
362 InPlaceABReducer r;
363 for (int i = 0; i < 3; i++) {
364 int before = graph()->NodeCount();
365 ReduceGraph(&r);
366 EXPECT_EQ(before, graph()->NodeCount());
titzer 2015/01/22 14:01:24 We can also start to use the NodeMatcher infrastru
367 EXPECT_EQ(&kOpB0, n1->op());
368 EXPECT_EQ(&kOpB1, n2->op());
369 EXPECT_EQ(n1, n2->InputAt(0));
370 EXPECT_EQ(&kOpB1, n3->op());
371 EXPECT_EQ(n1, n3->InputAt(0));
372 EXPECT_EQ(&kOpB2, end->op());
373 EXPECT_EQ(n2, end->InputAt(0));
374 EXPECT_EQ(n3, end->InputAt(1));
375 }
376 }
377
378
379 TEST_F(GraphReducerTest, ReduceNew1) {
380 Node* n1 = graph()->NewNode(&kOpA0);
381 Node* n2 = graph()->NewNode(&kOpA1, n1);
382 Node* n3 = graph()->NewNode(&kOpA1, n1);
383 Node* end = graph()->NewNode(&kOpA2, n2, n3);
384 graph()->SetEnd(end);
385
386 NewABReducer r(graph());
387 // Tests A* => B* while creating new nodes.
388 for (int i = 0; i < 3; i++) {
389 int before = graph()->NodeCount();
390 ReduceGraph(&r);
391 if (i == 0) {
392 EXPECT_NE(before, graph()->NodeCount());
393 } else {
394 EXPECT_EQ(before, graph()->NodeCount());
395 }
396 Node* nend = graph()->end();
397 EXPECT_NE(end, nend); // end() should be updated too.
398
399 Node* nn2 = nend->InputAt(0);
400 Node* nn3 = nend->InputAt(1);
401 Node* nn1 = nn2->InputAt(0);
402
403 EXPECT_EQ(nn1, nn3->InputAt(0));
404
405 EXPECT_EQ(&kOpB0, nn1->op());
406 EXPECT_EQ(&kOpB1, nn2->op());
407 EXPECT_EQ(&kOpB1, nn3->op());
408 EXPECT_EQ(&kOpB2, nend->op());
409 }
410 }
411
412
413 TEST_F(GraphReducerTest, Wrapping1) {
414 Node* end = graph()->NewNode(&kOpA0);
415 graph()->SetEnd(end);
416 EXPECT_EQ(1, graph()->NodeCount());
417
418 A0Wrapper r(graph());
419
420 ReduceGraph(&r);
421 EXPECT_EQ(2, graph()->NodeCount());
422
423 Node* nend = graph()->end();
424 EXPECT_NE(end, nend);
425 EXPECT_EQ(&kOpB1, nend->op());
426 EXPECT_EQ(1, nend->InputCount());
427 EXPECT_EQ(end, nend->InputAt(0));
428 }
429
430
431 TEST_F(GraphReducerTest, Wrapping2) {
432 Node* end = graph()->NewNode(&kOpB0);
433 graph()->SetEnd(end);
434 EXPECT_EQ(1, graph()->NodeCount());
435
436 B0Wrapper r(graph());
437
438 ReduceGraph(&r);
439 EXPECT_EQ(3, graph()->NodeCount());
440
441 Node* nend = graph()->end();
442 EXPECT_NE(end, nend);
443 EXPECT_EQ(&kOpC1, nend->op());
444 EXPECT_EQ(1, nend->InputCount());
445
446 Node* n1 = nend->InputAt(0);
447 EXPECT_NE(end, n1);
448 EXPECT_EQ(&kOpC1, n1->op());
449 EXPECT_EQ(1, n1->InputCount());
450 EXPECT_EQ(end, n1->InputAt(0));
451 }
452
453
454 TEST_F(GraphReducerTest, Forwarding1) {
455 Node* n1 = graph()->NewNode(&kOpA0);
456 Node* end = graph()->NewNode(&kOpA1, n1);
457 graph()->SetEnd(end);
458
459 A1Forwarder r;
460
461 // Tests A1(x) => x
462 for (int i = 0; i < 3; i++) {
463 int before = graph()->NodeCount();
464 ReduceGraph(&r);
465 EXPECT_EQ(before, graph()->NodeCount());
466 EXPECT_EQ(&kOpA0, n1->op());
467 EXPECT_EQ(n1, graph()->end());
468 }
469 }
470
471
472 TEST_F(GraphReducerTest, Forwarding2) {
473 Node* n1 = graph()->NewNode(&kOpA0);
474 Node* n2 = graph()->NewNode(&kOpA1, n1);
475 Node* n3 = graph()->NewNode(&kOpA1, n1);
476 Node* end = graph()->NewNode(&kOpA2, n2, n3);
477 graph()->SetEnd(end);
478
479 A1Forwarder r;
480
481 // Tests reducing A2(A1(x), A1(y)) => A2(x, y).
482 for (int i = 0; i < 3; i++) {
483 int before = graph()->NodeCount();
484 ReduceGraph(&r);
485 EXPECT_EQ(before, graph()->NodeCount());
486 EXPECT_EQ(&kOpA0, n1->op());
487 EXPECT_EQ(n1, end->InputAt(0));
488 EXPECT_EQ(n1, end->InputAt(1));
489 EXPECT_EQ(&kOpA2, end->op());
490 EXPECT_EQ(0, n2->UseCount());
491 EXPECT_EQ(0, n3->UseCount());
492 }
493 }
494
495
496 TEST_F(GraphReducerTest, Forwarding3) {
497 // Tests reducing a chain of A1(A1(A1(A1(x)))) => x.
498 for (int i = 0; i < 8; i++) {
499 Node* n1 = graph()->NewNode(&kOpA0);
500 Node* end = n1;
501 for (int j = 0; j < i; j++) {
502 end = graph()->NewNode(&kOpA1, end);
503 }
504 graph()->SetEnd(end);
505
506 A1Forwarder r;
507
508 for (int i = 0; i < 3; i++) {
509 int before = graph()->NodeCount();
510 ReduceGraph(&r);
511 EXPECT_EQ(before, graph()->NodeCount());
512 EXPECT_EQ(&kOpA0, n1->op());
513 EXPECT_EQ(n1, graph()->end());
514 }
515 }
516 }
517
518
519 TEST_F(GraphReducerTest, ReduceForward1) {
520 Node* n1 = graph()->NewNode(&kOpA0);
521 Node* n2 = graph()->NewNode(&kOpA1, n1);
522 Node* n3 = graph()->NewNode(&kOpA1, n1);
523 Node* end = graph()->NewNode(&kOpA2, n2, n3);
524 graph()->SetEnd(end);
525
526 InPlaceABReducer r;
527 B1Forwarder f;
528
529 // Tests first reducing A => B, then B1(x) => x.
530 for (int i = 0; i < 3; i++) {
531 int before = graph()->NodeCount();
532 ReduceGraph(&r, &f);
533 EXPECT_EQ(before, graph()->NodeCount());
534 EXPECT_EQ(&kOpB0, n1->op());
535 EXPECT_TRUE(n2->IsDead());
536 EXPECT_EQ(n1, end->InputAt(0));
537 EXPECT_TRUE(n3->IsDead());
538 EXPECT_EQ(n1, end->InputAt(0));
539 EXPECT_EQ(&kOpB2, end->op());
540 EXPECT_EQ(0, n2->UseCount());
541 EXPECT_EQ(0, n3->UseCount());
542 }
543 }
544
545
546 TEST_F(GraphReducerTest, Sorter1) {
547 AB2Sorter r;
548 for (int i = 0; i < 6; i++) {
549 Node* n1 = graph()->NewNode(&kOpA0);
550 Node* n2 = graph()->NewNode(&kOpA1, n1);
551 Node* n3 = graph()->NewNode(&kOpA1, n1);
552 Node* end = NULL; // Initialize to please the compiler.
553
554 if (i == 0) end = graph()->NewNode(&kOpA2, n2, n3);
555 if (i == 1) end = graph()->NewNode(&kOpA2, n3, n2);
556 if (i == 2) end = graph()->NewNode(&kOpA2, n2, n1);
557 if (i == 3) end = graph()->NewNode(&kOpA2, n1, n2);
558 if (i == 4) end = graph()->NewNode(&kOpA2, n3, n1);
559 if (i == 5) end = graph()->NewNode(&kOpA2, n1, n3);
560
561 graph()->SetEnd(end);
562
563 int before = graph()->NodeCount();
564 ReduceGraph(&r);
565 EXPECT_EQ(before, graph()->NodeCount());
566 EXPECT_EQ(&kOpA0, n1->op());
567 EXPECT_EQ(&kOpA1, n2->op());
568 EXPECT_EQ(&kOpA1, n3->op());
569 EXPECT_EQ(&kOpA2, end->op());
570 EXPECT_EQ(end, graph()->end());
571 EXPECT_LE(end->InputAt(0)->id(), end->InputAt(1)->id());
572 }
573 }
574
575
576 // Generate a node graph with the given permutations.
577 void GenDAG(Graph* graph, int* p3, int* p2, int* p1) {
578 Node* level4 = graph->NewNode(&kOpA0);
579 Node* level3[] = {graph->NewNode(&kOpA1, level4),
580 graph->NewNode(&kOpA1, level4)};
581
582 Node* level2[] = {graph->NewNode(&kOpA1, level3[p3[0]]),
583 graph->NewNode(&kOpA1, level3[p3[1]]),
584 graph->NewNode(&kOpA1, level3[p3[0]]),
585 graph->NewNode(&kOpA1, level3[p3[1]])};
586
587 Node* level1[] = {graph->NewNode(&kOpA2, level2[p2[0]], level2[p2[1]]),
588 graph->NewNode(&kOpA2, level2[p2[2]], level2[p2[3]])};
589
590 Node* end = graph->NewNode(&kOpA2, level1[p1[0]], level1[p1[1]]);
591 graph->SetEnd(end);
592 }
593
594
595 TEST_F(GraphReducerTest, SortForwardReduce) {
596 // Tests combined reductions on a series of DAGs.
597 for (int j = 0; j < 2; j++) {
598 int p3[] = {j, 1 - j};
599 for (int m = 0; m < 2; m++) {
600 int p1[] = {m, 1 - m};
601 for (int k = 0; k < 24; k++) { // All permutations of 0, 1, 2, 3
602 int p2[] = {-1, -1, -1, -1};
603 int n = k;
604 for (int d = 4; d >= 1; d--) { // Construct permutation.
605 int p = n % d;
606 for (int z = 0; z < 4; z++) {
607 if (p2[z] == -1) {
608 if (p == 0) p2[z] = d - 1;
609 p--;
610 }
611 }
612 n = n / d;
613 }
614
615 GenDAG(graph(), p3, p2, p1);
616
617 AB2Sorter r1;
618 A1Forwarder r2;
619 InPlaceABReducer r3;
620
621 ReduceGraph(&r1, &r2, &r3);
622
623 Node* end = graph()->end();
624 EXPECT_EQ(&kOpB2, end->op());
625 Node* n1 = end->InputAt(0);
626 Node* n2 = end->InputAt(1);
627 EXPECT_NE(n1, n2);
628 EXPECT_LT(n1->id(), n2->id());
629 EXPECT_EQ(&kOpB2, n1->op());
630 EXPECT_EQ(&kOpB2, n2->op());
631 Node* n4 = n1->InputAt(0);
632 EXPECT_EQ(&kOpB0, n4->op());
633 EXPECT_EQ(n4, n1->InputAt(1));
634 EXPECT_EQ(n4, n2->InputAt(0));
635 EXPECT_EQ(n4, n2->InputAt(1));
636 }
637 }
638 }
639 }
640
641
642 TEST_F(GraphReducerTest, Order) {
643 // Test that the order of reducers doesn't matter, as they should be
644 // rerun for changed nodes.
645 for (int i = 0; i < 2; i++) {
646 Node* n1 = graph()->NewNode(&kOpA0);
647 Node* end = graph()->NewNode(&kOpA1, n1);
648 graph()->SetEnd(end);
649
650 InPlaceABReducer abr;
651 InPlaceBCReducer bcr;
652
653 // Tests A* => C* with in-place updates.
654 for (int j = 0; j < 3; j++) {
655 int before = graph()->NodeCount();
656 if (i == 0) {
657 ReduceGraph(&abr, &bcr);
658 } else {
659 ReduceGraph(&bcr, &abr);
660 }
661
662 EXPECT_EQ(before, graph()->NodeCount());
663 EXPECT_EQ(&kOpC0, n1->op());
664 EXPECT_EQ(&kOpC1, end->op());
665 EXPECT_EQ(n1, end->InputAt(0));
666 }
667 }
668 }
669
670
122 } // namespace compiler 671 } // namespace compiler
123 } // namespace internal 672 } // namespace internal
124 } // namespace v8 673 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/compiler/test-graph-reducer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698