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

Side by Side Diff: test/cctest/compiler/test-structured-machine-assembler.cc

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6 #include "test/cctest/cctest.h"
7
8 #include "src/base/utils/random-number-generator.h"
9 #include "src/compiler/structured-machine-assembler.h"
10 #include "test/cctest/compiler/codegen-tester.h"
11 #include "test/cctest/compiler/value-helper.h"
12
13 #if V8_TURBOFAN_TARGET
14
15 using namespace v8::internal::compiler;
16
17 typedef StructuredMachineAssembler::IfBuilder IfBuilder;
18 typedef StructuredMachineAssembler::LoopBuilder Loop;
19
20 namespace v8 {
21 namespace internal {
22 namespace compiler {
23
24 class StructuredMachineAssemblerFriend {
25 public:
26 static bool VariableAlive(StructuredMachineAssembler* m,
27 const Variable& var) {
28 CHECK(m->current_environment_ != NULL);
29 int offset = var.offset_;
30 return offset < static_cast<int>(m->CurrentVars()->size()) &&
31 m->CurrentVars()->at(offset) != NULL;
32 }
33 };
34
35 } } } // namespace v8::internal::compiler
36
37
38 TEST(RunVariable) {
39 StructuredMachineAssemblerTester<int32_t> m;
40
41 int32_t constant = 0x86c2bb16;
42
43 Variable v1 = m.NewVariable(m.Int32Constant(constant));
44 Variable v2 = m.NewVariable(v1.Get());
45 m.Return(v2.Get());
46
47 CHECK_EQ(constant, m.Call());
48 }
49
50
51 TEST(RunSimpleIf) {
52 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
53
54 int32_t constant = 0xc4a3e3a6;
55 {
56 IfBuilder cond(&m);
57 cond.If(m.Parameter(0)).Then();
58 m.Return(m.Int32Constant(constant));
59 }
60 m.Return(m.Word32Not(m.Int32Constant(constant)));
61
62 CHECK_EQ(~constant, m.Call(0));
63 CHECK_EQ(constant, m.Call(1));
64 }
65
66
67 TEST(RunSimpleIfVariable) {
68 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
69
70 int32_t constant = 0xdb6f20c2;
71 Variable var = m.NewVariable(m.Int32Constant(constant));
72 {
73 IfBuilder cond(&m);
74 cond.If(m.Parameter(0)).Then();
75 var.Set(m.Word32Not(var.Get()));
76 }
77 m.Return(var.Get());
78
79 CHECK_EQ(constant, m.Call(0));
80 CHECK_EQ(~constant, m.Call(1));
81 }
82
83
84 TEST(RunSimpleElse) {
85 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
86
87 int32_t constant = 0xfc5eadf4;
88 {
89 IfBuilder cond(&m);
90 cond.If(m.Parameter(0)).Else();
91 m.Return(m.Int32Constant(constant));
92 }
93 m.Return(m.Word32Not(m.Int32Constant(constant)));
94
95 CHECK_EQ(constant, m.Call(0));
96 CHECK_EQ(~constant, m.Call(1));
97 }
98
99
100 TEST(RunSimpleIfElse) {
101 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
102
103 int32_t constant = 0xaa9c8cd3;
104 {
105 IfBuilder cond(&m);
106 cond.If(m.Parameter(0)).Then();
107 m.Return(m.Int32Constant(constant));
108 cond.Else();
109 m.Return(m.Word32Not(m.Int32Constant(constant)));
110 }
111
112 CHECK_EQ(~constant, m.Call(0));
113 CHECK_EQ(constant, m.Call(1));
114 }
115
116
117 TEST(RunSimpleIfElseVariable) {
118 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
119
120 int32_t constant = 0x67b6f39c;
121 Variable var = m.NewVariable(m.Int32Constant(constant));
122 {
123 IfBuilder cond(&m);
124 cond.If(m.Parameter(0)).Then();
125 var.Set(m.Word32Not(m.Word32Not(var.Get())));
126 cond.Else();
127 var.Set(m.Word32Not(var.Get()));
128 }
129 m.Return(var.Get());
130
131 CHECK_EQ(~constant, m.Call(0));
132 CHECK_EQ(constant, m.Call(1));
133 }
134
135
136 TEST(RunSimpleIfNoThenElse) {
137 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
138
139 int32_t constant = 0xd5e550ed;
140 {
141 IfBuilder cond(&m);
142 cond.If(m.Parameter(0));
143 }
144 m.Return(m.Int32Constant(constant));
145
146 CHECK_EQ(constant, m.Call(0));
147 CHECK_EQ(constant, m.Call(1));
148 }
149
150
151 TEST(RunSimpleConjunctionVariable) {
152 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
153
154 int32_t constant = 0xf8fb9ec6;
155 Variable var = m.NewVariable(m.Int32Constant(constant));
156 {
157 IfBuilder cond(&m);
158 cond.If(m.Int32Constant(1)).And();
159 var.Set(m.Word32Not(var.Get()));
160 cond.If(m.Parameter(0)).Then();
161 var.Set(m.Word32Not(m.Word32Not(var.Get())));
162 cond.Else();
163 var.Set(m.Word32Not(var.Get()));
164 }
165 m.Return(var.Get());
166
167 CHECK_EQ(constant, m.Call(0));
168 CHECK_EQ(~constant, m.Call(1));
169 }
170
171
172 TEST(RunSimpleDisjunctionVariable) {
173 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
174
175 int32_t constant = 0x118f6ffc;
176 Variable var = m.NewVariable(m.Int32Constant(constant));
177 {
178 IfBuilder cond(&m);
179 cond.If(m.Int32Constant(0)).Or();
180 var.Set(m.Word32Not(var.Get()));
181 cond.If(m.Parameter(0)).Then();
182 var.Set(m.Word32Not(m.Word32Not(var.Get())));
183 cond.Else();
184 var.Set(m.Word32Not(var.Get()));
185 }
186 m.Return(var.Get());
187
188 CHECK_EQ(constant, m.Call(0));
189 CHECK_EQ(~constant, m.Call(1));
190 }
191
192
193 TEST(RunIfElse) {
194 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
195
196 {
197 IfBuilder cond(&m);
198 bool first = true;
199 FOR_INT32_INPUTS(i) {
200 Node* c = m.Int32Constant(*i);
201 if (first) {
202 cond.If(m.Word32Equal(m.Parameter(0), c)).Then();
203 m.Return(c);
204 first = false;
205 } else {
206 cond.Else();
207 cond.If(m.Word32Equal(m.Parameter(0), c)).Then();
208 m.Return(c);
209 }
210 }
211 }
212 m.Return(m.Int32Constant(333));
213
214 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, m.Call(*i)); }
215 }
216
217
218 enum IfBuilderBranchType {
219 kSkipBranch, kBranchFallsThrough, kBranchReturns
220 };
221
222
223 static IfBuilderBranchType all_branch_types[] = {
224 kSkipBranch, kBranchFallsThrough, kBranchReturns
225 };
226
227
228 static void RunIfBuilderDisjunction(size_t max, IfBuilderBranchType then_type,
229 IfBuilderBranchType else_type) {
230 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
231
232 std::vector<int32_t> inputs = ValueHelper::int32_vector();
233 std::vector<int32_t>::const_iterator i = inputs.begin();
234 int32_t hit = 0x8c723c9a;
235 int32_t miss = 0x88a6b9f3;
236 {
237 Node* p0 = m.Parameter(0);
238 IfBuilder cond(&m);
239 for (size_t j = 0; j < max; j++, ++i) {
240 CHECK(i != inputs.end()); // Thank you STL.
241 if (j > 0) cond.Or();
242 cond.If(m.Word32Equal(p0, m.Int32Constant(*i)));
243 }
244 switch (then_type) {
245 case kSkipBranch:
246 break;
247 case kBranchFallsThrough:
248 cond.Then();
249 break;
250 case kBranchReturns:
251 cond.Then();
252 m.Return(m.Int32Constant(hit));
253 break;
254 }
255 switch (else_type) {
256 case kSkipBranch:
257 break;
258 case kBranchFallsThrough:
259 cond.Else();
260 break;
261 case kBranchReturns:
262 cond.Else();
263 m.Return(m.Int32Constant(miss));
264 break;
265 }
266 }
267 if (then_type != kBranchReturns || else_type != kBranchReturns) {
268 m.Return(m.Int32Constant(miss));
269 }
270
271 if (then_type != kBranchReturns) hit = miss;
272
273 i = inputs.begin();
274 for (size_t j = 0; i != inputs.end(); j++, ++i) {
275 int32_t result = m.Call(*i);
276 CHECK_EQ(j < max ? hit : miss, result);
277 }
278 }
279
280
281 TEST(RunIfBuilderDisjunction) {
282 size_t len = ValueHelper::int32_vector().size() - 1;
283 size_t max = len > 10 ? 10 : len - 1;
284 for (size_t i = 0; i < ARRAY_SIZE(all_branch_types); i++) {
285 for (size_t j = 0; j < ARRAY_SIZE(all_branch_types); j++) {
286 for (size_t size = 1; size < max; size++) {
287 RunIfBuilderDisjunction(size, all_branch_types[i], all_branch_types[j]);
288 }
289 RunIfBuilderDisjunction(len, all_branch_types[i], all_branch_types[j]);
290 }
291 }
292 }
293
294
295 static void RunIfBuilderConjunction(size_t max, IfBuilderBranchType then_type,
296 IfBuilderBranchType else_type) {
297 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
298
299 std::vector<int32_t> inputs = ValueHelper::int32_vector();
300 std::vector<int32_t>::const_iterator i = inputs.begin();
301 int32_t hit = 0xa0ceb9ca;
302 int32_t miss = 0x226cafaa;
303 {
304 IfBuilder cond(&m);
305 Node* p0 = m.Parameter(0);
306 for (size_t j = 0; j < max; j++, ++i) {
307 if (j > 0) cond.And();
308 cond.If(m.Word32NotEqual(p0, m.Int32Constant(*i)));
309 }
310 switch (then_type) {
311 case kSkipBranch:
312 break;
313 case kBranchFallsThrough:
314 cond.Then();
315 break;
316 case kBranchReturns:
317 cond.Then();
318 m.Return(m.Int32Constant(hit));
319 break;
320 }
321 switch (else_type) {
322 case kSkipBranch:
323 break;
324 case kBranchFallsThrough:
325 cond.Else();
326 break;
327 case kBranchReturns:
328 cond.Else();
329 m.Return(m.Int32Constant(miss));
330 break;
331 }
332 }
333 if (then_type != kBranchReturns || else_type != kBranchReturns) {
334 m.Return(m.Int32Constant(miss));
335 }
336
337 if (then_type != kBranchReturns) hit = miss;
338
339 i = inputs.begin();
340 for (size_t j = 0; i != inputs.end(); j++, ++i) {
341 int32_t result = m.Call(*i);
342 CHECK_EQ(j >= max ? hit : miss, result);
343 }
344 }
345
346
347 TEST(RunIfBuilderConjunction) {
348 size_t len = ValueHelper::int32_vector().size() - 1;
349 size_t max = len > 10 ? 10 : len - 1;
350 for (size_t i = 0; i < ARRAY_SIZE(all_branch_types); i++) {
351 for (size_t j = 0; j < ARRAY_SIZE(all_branch_types); j++) {
352 for (size_t size = 1; size < max; size++) {
353 RunIfBuilderConjunction(size, all_branch_types[i], all_branch_types[j]);
354 }
355 RunIfBuilderConjunction(len, all_branch_types[i], all_branch_types[j]);
356 }
357 }
358 }
359
360
361 static void RunDisjunctionVariables(int disjunctions,
362 bool explicit_then,
363 bool explicit_else) {
364 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
365
366 int32_t constant = 0x65a09535;
367
368 Node* cmp_val = m.Int32Constant(constant);
369 Node* one = m.Int32Constant(1);
370 Variable var = m.NewVariable(m.Parameter(0));
371 {
372 IfBuilder cond(&m);
373 cond.If(m.Word32Equal(var.Get(), cmp_val));
374 for (int i = 0; i < disjunctions; i++) {
375 cond.Or();
376 var.Set(m.Int32Add(var.Get(), one));
377 cond.If(m.Word32Equal(var.Get(), cmp_val));
378 }
379 if (explicit_then) {
380 cond.Then();
381 }
382 if (explicit_else) {
383 cond.Else();
384 var.Set(m.Int32Add(var.Get(), one));
385 }
386 }
387 m.Return(var.Get());
388
389 int adds = disjunctions + (explicit_else ? 1 : 0);
390 int32_t input = constant - 2 * adds;
391 for (int i = 0; i < adds; i++) {
392 CHECK_EQ(input + adds, m.Call(input));
393 input++;
394 }
395 for (int i = 0; i < adds + 1; i++) {
396 CHECK_EQ(constant, m.Call(input));
397 input++;
398 }
399 for (int i = 0; i < adds; i++) {
400 CHECK_EQ(input + adds, m.Call(input));
401 input++;
402 }
403 }
404
405
406 TEST(RunDisjunctionVariables) {
407 for (int disjunctions = 0; disjunctions < 10; disjunctions++) {
408 RunDisjunctionVariables(disjunctions, false, false);
409 RunDisjunctionVariables(disjunctions, false, true);
410 RunDisjunctionVariables(disjunctions, true, false);
411 RunDisjunctionVariables(disjunctions, true, true);
412 }
413 }
414
415
416 static void RunConjunctionVariables(int conjunctions,
417 bool explicit_then,
418 bool explicit_else) {
419 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
420
421 int32_t constant = 0x2c7f4b45;
422 Node* cmp_val = m.Int32Constant(constant);
423 Node* one = m.Int32Constant(1);
424 Variable var = m.NewVariable(m.Parameter(0));
425 {
426 IfBuilder cond(&m);
427 cond.If(m.Word32NotEqual(var.Get(), cmp_val));
428 for (int i = 0; i < conjunctions; i++) {
429 cond.And();
430 var.Set(m.Int32Add(var.Get(), one));
431 cond.If(m.Word32NotEqual(var.Get(), cmp_val));
432 }
433 if (explicit_then) {
434 cond.Then();
435 var.Set(m.Int32Add(var.Get(), one));
436 }
437 if (explicit_else) {
438 cond.Else();
439 }
440 }
441 m.Return(var.Get());
442
443 int adds = conjunctions + (explicit_then ? 1 : 0);
444 int32_t input = constant - 2 * adds;
445 for (int i = 0; i < adds; i++) {
446 CHECK_EQ(input + adds, m.Call(input));
447 input++;
448 }
449 for (int i = 0; i < adds + 1; i++) {
450 CHECK_EQ(constant, m.Call(input));
451 input++;
452 }
453 for (int i = 0; i < adds; i++) {
454 CHECK_EQ(input + adds, m.Call(input));
455 input++;
456 }
457 }
458
459
460 TEST(RunConjunctionVariables) {
461 for (int conjunctions = 0; conjunctions < 10; conjunctions++) {
462 RunConjunctionVariables(conjunctions, false, false);
463 RunConjunctionVariables(conjunctions, false, true);
464 RunConjunctionVariables(conjunctions, true, false);
465 RunConjunctionVariables(conjunctions, true, true);
466 }
467 }
468
469
470 TEST(RunSimpleNestedIf) {
471 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32, kMachineWord32);
472 const size_t NUM_VALUES = 7;
473 std::vector<int32_t> inputs = ValueHelper::int32_vector();
474 CHECK(inputs.size() >= NUM_VALUES);
475 Node* values[NUM_VALUES];
476 for (size_t j = 0; j < NUM_VALUES; j++) {
477 values[j] = m.Int32Constant(inputs[j]);
478 }
479 {
480 IfBuilder if_0(&m);
481 if_0.If(m.Word32Equal(m.Parameter(0), values[0])).Then();
482 {
483 IfBuilder if_1(&m);
484 if_1.If(m.Word32Equal(m.Parameter(1), values[1])).Then();
485 {
486 m.Return(values[3]);
487 }
488 if_1.Else();
489 {
490 m.Return(values[4]);
491 }
492 }
493 if_0.Else();
494 {
495 IfBuilder if_1(&m);
496 if_1.If(m.Word32Equal(m.Parameter(1), values[2])).Then();
497 {
498 m.Return(values[5]);
499 }
500 if_1.Else();
501 {
502 m.Return(values[6]);
503 }
504 }
505 }
506
507 int32_t result = m.Call(inputs[0], inputs[1]);
508 CHECK_EQ(inputs[3], result);
509
510 result = m.Call(inputs[0], inputs[1] + 1);
511 CHECK_EQ(inputs[4], result);
512
513 result = m.Call(inputs[0] + 1, inputs[2]);
514 CHECK_EQ(inputs[5], result);
515
516 result = m.Call(inputs[0] + 1, inputs[2] + 1);
517 CHECK_EQ(inputs[6], result);
518 }
519
520
521 TEST(RunUnreachableBlockAfterIf) {
522 StructuredMachineAssemblerTester<int32_t> m;
523 {
524 IfBuilder cond(&m);
525 cond.If(m.Int32Constant(0)).Then();
526 m.Return(m.Int32Constant(1));
527 cond.Else();
528 m.Return(m.Int32Constant(2));
529 }
530 // This is unreachable.
531 m.Return(m.Int32Constant(3));
532 CHECK_EQ(2, m.Call());
533 }
534
535
536 TEST(RunUnreachableBlockAfterLoop) {
537 StructuredMachineAssemblerTester<int32_t> m;
538 {
539 Loop loop(&m);
540 m.Return(m.Int32Constant(1));
541 }
542 // This is unreachable.
543 m.Return(m.Int32Constant(3));
544 CHECK_EQ(1, m.Call());
545 }
546
547
548 TEST(RunSimpleLoop) {
549 StructuredMachineAssemblerTester<int32_t> m;
550 int32_t constant = 0x120c1f85;
551 {
552 Loop loop(&m);
553 m.Return(m.Int32Constant(constant));
554 }
555 CHECK_EQ(constant, m.Call());
556 }
557
558
559 TEST(RunSimpleLoopBreak) {
560 StructuredMachineAssemblerTester<int32_t> m;
561 int32_t constant = 0x10ddb0a6;
562 {
563 Loop loop(&m);
564 loop.Break();
565 }
566 m.Return(m.Int32Constant(constant));
567 CHECK_EQ(constant, m.Call());
568 }
569
570
571 TEST(RunCountToTen) {
572 StructuredMachineAssemblerTester<int32_t> m;
573 Variable i = m.NewVariable(m.Int32Constant(0));
574 Node* ten = m.Int32Constant(10);
575 Node* one = m.Int32Constant(1);
576 {
577 Loop loop(&m);
578 {
579 IfBuilder cond(&m);
580 cond.If(m.Word32Equal(i.Get(), ten)).Then();
581 loop.Break();
582 }
583 i.Set(m.Int32Add(i.Get(), one));
584 }
585 m.Return(i.Get());
586 CHECK_EQ(10, m.Call());
587 }
588
589
590 TEST(RunCountToTenAcc) {
591 StructuredMachineAssemblerTester<int32_t> m;
592 int32_t constant = 0xf27aed64;
593 Variable i = m.NewVariable(m.Int32Constant(0));
594 Variable var = m.NewVariable(m.Int32Constant(constant));
595 Node* ten = m.Int32Constant(10);
596 Node* one = m.Int32Constant(1);
597 {
598 Loop loop(&m);
599 {
600 IfBuilder cond(&m);
601 cond.If(m.Word32Equal(i.Get(), ten)).Then();
602 loop.Break();
603 }
604 i.Set(m.Int32Add(i.Get(), one));
605 var.Set(m.Int32Add(var.Get(), i.Get()));
606 }
607 m.Return(var.Get());
608
609 CHECK_EQ(constant + 10 + 9 * 5, m.Call());
610 }
611
612
613 TEST(RunSimpleNestedLoop) {
614 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
615
616 Node* zero = m.Int32Constant(0);
617 Node* one = m.Int32Constant(1);
618 Node* two = m.Int32Constant(2);
619 Node* three = m.Int32Constant(3);
620 {
621 Loop l1(&m);
622 {
623 Loop l2(&m);
624 {
625 IfBuilder cond(&m);
626 cond.If(m.Word32Equal(m.Parameter(0), one)).Then();
627 l1.Break();
628 }
629 {
630 Loop l3(&m);
631 {
632 IfBuilder cond(&m);
633 cond.If(m.Word32Equal(m.Parameter(0), two)).Then();
634 l2.Break();
635 cond.Else();
636 cond.If(m.Word32Equal(m.Parameter(0), three)).Then();
637 l3.Break();
638 }
639 m.Return(three);
640 }
641 m.Return(two);
642 }
643 m.Return(one);
644 }
645 m.Return(zero);
646
647 CHECK_EQ(0, m.Call(1));
648 CHECK_EQ(1, m.Call(2));
649 CHECK_EQ(2, m.Call(3));
650 CHECK_EQ(3, m.Call(4));
651 }
652
653
654 TEST(RunFib) {
655 StructuredMachineAssemblerTester<int32_t> m(kMachineWord32);
656
657 // Constants.
658 Node* zero = m.Int32Constant(0);
659 Node* one = m.Int32Constant(1);
660 Node* two = m.Int32Constant(2);
661 // Variables.
662 // cnt = input
663 Variable cnt = m.NewVariable(m.Parameter(0));
664 // if (cnt < 2) return i
665 {
666 IfBuilder lt2(&m);
667 lt2.If(m.Int32LessThan(cnt.Get(), two)).Then();
668 m.Return(cnt.Get());
669 }
670 // cnt -= 2
671 cnt.Set(m.Int32Sub(cnt.Get(), two));
672 // res = 1
673 Variable res = m.NewVariable(one);
674 {
675 // prv_0 = 1
676 // prv_1 = 1
677 Variable prv_0 = m.NewVariable(one);
678 Variable prv_1 = m.NewVariable(one);
679 // while (cnt != 0) {
680 Loop main(&m);
681 {
682 IfBuilder nz(&m);
683 nz.If(m.Word32Equal(cnt.Get(), zero)).Then();
684 main.Break();
685 }
686 // res = prv_0 + prv_1
687 // prv_0 = prv_1
688 // prv_1 = res
689 res.Set(m.Int32Add(prv_0.Get(), prv_1.Get()));
690 prv_0.Set(prv_1.Get());
691 prv_1.Set(res.Get());
692 // cnt--
693 cnt.Set(m.Int32Sub(cnt.Get(), one));
694 }
695 m.Return(res.Get());
696
697 int32_t values[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144};
698 for (size_t i = 0; i < ARRAY_SIZE(values); i++) {
699 CHECK_EQ(values[i], m.Call(static_cast<int32_t>(i)));
700 }
701 }
702
703
704 static int VariableIntroduction() {
705 while (true) {
706 int ret = 0;
707 for (int i = 0; i < 10; i++) {
708 for (int j = i; j < 10; j++) {
709 for (int k = j; k < 10; k++) {
710 ret++;
711 }
712 ret++;
713 }
714 ret++;
715 }
716 return ret;
717 }
718 }
719
720
721 TEST(RunVariableIntroduction) {
722 StructuredMachineAssemblerTester<int32_t> m;
723 Node* zero = m.Int32Constant(0);
724 Node* one = m.Int32Constant(1);
725 // Use an IfBuilder to get out of start block.
726 {
727 IfBuilder i0(&m);
728 i0.If(zero).Then();
729 m.Return(one);
730 }
731 Node* ten = m.Int32Constant(10);
732 Variable v0 =
733 m.NewVariable(zero); // Introduce variable outside of start block.
734 {
735 Loop l0(&m);
736 Variable ret = m.NewVariable(zero); // Introduce loop variable.
737 {
738 Loop l1(&m);
739 {
740 IfBuilder i1(&m);
741 i1.If(m.Word32Equal(v0.Get(), ten)).Then();
742 l1.Break();
743 }
744 Variable v1 = m.NewVariable(v0.Get()); // Introduce loop variable.
745 {
746 Loop l2(&m);
747 {
748 IfBuilder i2(&m);
749 i2.If(m.Word32Equal(v1.Get(), ten)).Then();
750 l2.Break();
751 }
752 Variable v2 = m.NewVariable(v1.Get()); // Introduce loop variable.
753 {
754 Loop l3(&m);
755 {
756 IfBuilder i3(&m);
757 i3.If(m.Word32Equal(v2.Get(), ten)).Then();
758 l3.Break();
759 }
760 ret.Set(m.Int32Add(ret.Get(), one));
761 v2.Set(m.Int32Add(v2.Get(), one));
762 }
763 ret.Set(m.Int32Add(ret.Get(), one));
764 v1.Set(m.Int32Add(v1.Get(), one));
765 }
766 ret.Set(m.Int32Add(ret.Get(), one));
767 v0.Set(m.Int32Add(v0.Get(), one));
768 }
769 m.Return(ret.Get()); // Return loop variable.
770 }
771 CHECK_EQ(VariableIntroduction(), m.Call());
772 }
773
774
775 TEST(RunIfBuilderVariableLiveness) {
776 StructuredMachineAssemblerTester<int32_t> m;
777 typedef i::compiler::StructuredMachineAssemblerFriend F;
778 Node* zero = m.Int32Constant(0);
779 Variable v_outer = m.NewVariable(zero);
780 IfBuilder cond(&m);
781 cond.If(zero).Then();
782 Variable v_then = m.NewVariable(zero);
783 CHECK(F::VariableAlive(&m, v_outer));
784 CHECK(F::VariableAlive(&m, v_then));
785 cond.Else();
786 Variable v_else = m.NewVariable(zero);
787 CHECK(F::VariableAlive(&m, v_outer));
788 CHECK(F::VariableAlive(&m, v_else));
789 CHECK(!F::VariableAlive(&m, v_then));
790 cond.End();
791 CHECK(F::VariableAlive(&m, v_outer));
792 CHECK(!F::VariableAlive(&m, v_then));
793 CHECK(!F::VariableAlive(&m, v_else));
794 }
795
796
797 TEST(RunSimpleExpression1) {
798 StructuredMachineAssemblerTester<int32_t> m;
799
800 int32_t constant = 0x0c2974ef;
801 Node* zero = m.Int32Constant(0);
802 Node* one = m.Int32Constant(1);
803 {
804 // if (((1 && 1) && 1) && 1) return constant; return 0;
805 IfBuilder cond(&m);
806 cond.OpenParen();
807 cond.OpenParen().If(one).And();
808 cond.If(one).CloseParen().And();
809 cond.If(one).CloseParen().And();
810 cond.If(one).Then();
811 m.Return(m.Int32Constant(constant));
812 }
813 m.Return(zero);
814
815 CHECK_EQ(constant, m.Call());
816 }
817
818
819 TEST(RunSimpleExpression2) {
820 StructuredMachineAssemblerTester<int32_t> m;
821
822 int32_t constant = 0x2eddc11b;
823 Node* zero = m.Int32Constant(0);
824 Node* one = m.Int32Constant(1);
825 {
826 // if (((0 || 1) && 1) && 1) return constant; return 0;
827 IfBuilder cond(&m);
828 cond.OpenParen();
829 cond.OpenParen().If(zero).Or();
830 cond.If(one).CloseParen().And();
831 cond.If(one).CloseParen().And();
832 cond.If(one).Then();
833 m.Return(m.Int32Constant(constant));
834 }
835 m.Return(zero);
836
837 CHECK_EQ(constant, m.Call());
838 }
839
840
841 TEST(RunSimpleExpression3) {
842 StructuredMachineAssemblerTester<int32_t> m;
843
844 int32_t constant = 0x9ed5e9ef;
845 Node* zero = m.Int32Constant(0);
846 Node* one = m.Int32Constant(1);
847 {
848 // if (1 && ((0 || 1) && 1) && 1) return constant; return 0;
849 IfBuilder cond(&m);
850 cond.If(one).And();
851 cond.OpenParen();
852 cond.OpenParen().If(zero).Or();
853 cond.If(one).CloseParen().And();
854 cond.If(one).CloseParen().And();
855 cond.If(one).Then();
856 m.Return(m.Int32Constant(constant));
857 }
858 m.Return(zero);
859
860 CHECK_EQ(constant, m.Call());
861 }
862
863
864 TEST(RunSimpleExpressionVariable1) {
865 StructuredMachineAssemblerTester<int32_t> m;
866
867 int32_t constant = 0x4b40a986;
868 Node* one = m.Int32Constant(1);
869 Variable var = m.NewVariable(m.Int32Constant(constant));
870 {
871 // if (var.Get() && ((!var || var) && var) && var) {} return var;
872 // incrementing var in each environment.
873 IfBuilder cond(&m);
874 cond.If(var.Get()).And();
875 var.Set(m.Int32Add(var.Get(), one));
876 cond.OpenParen().OpenParen().If(m.Word32BinaryNot(var.Get())).Or();
877 var.Set(m.Int32Add(var.Get(), one));
878 cond.If(var.Get()).CloseParen().And();
879 var.Set(m.Int32Add(var.Get(), one));
880 cond.If(var.Get()).CloseParen().And();
881 var.Set(m.Int32Add(var.Get(), one));
882 cond.If(var.Get());
883 }
884 m.Return(var.Get());
885
886 CHECK_EQ(constant + 4, m.Call());
887 }
888
889
890 class QuicksortHelper : public StructuredMachineAssemblerTester<int32_t> {
891 public:
892 QuicksortHelper()
893 : StructuredMachineAssemblerTester(
894 MachineOperatorBuilder::pointer_rep(), kMachineWord32,
895 MachineOperatorBuilder::pointer_rep(), kMachineWord32),
896 input_(NULL),
897 stack_limit_(NULL),
898 one_(Int32Constant(1)),
899 stack_frame_size_(Int32Constant(kFrameVariables * 4)),
900 left_offset_(Int32Constant(0 * 4)),
901 right_offset_(Int32Constant(1 * 4)) {
902 Build();
903 }
904
905 int32_t DoCall(int32_t* input, int32_t input_length) {
906 int32_t stack_space[20];
907 // Do call.
908 int32_t return_val = Call(input, input_length, stack_space,
909 static_cast<int32_t>(ARRAY_SIZE(stack_space)));
910 // Ran out of stack space.
911 if (return_val != 0) return return_val;
912 // Check sorted.
913 int32_t last = input[0];
914 for (int32_t i = 0; i < input_length; i++) {
915 CHECK(last <= input[i]);
916 last = input[i];
917 }
918 return return_val;
919 }
920
921 private:
922 void Inc32(const Variable& var) { var.Set(Int32Add(var.Get(), one_)); }
923 Node* Index(Node* index) { return Word32Shl(index, Int32Constant(2)); }
924 Node* ArrayLoad(Node* index) {
925 return Load(kMachineWord32, input_, Index(index));
926 }
927 void Swap(Node* a_index, Node* b_index) {
928 Node* a = ArrayLoad(a_index);
929 Node* b = ArrayLoad(b_index);
930 Store(kMachineWord32, input_, Index(a_index), b);
931 Store(kMachineWord32, input_, Index(b_index), a);
932 }
933 void AddToCallStack(const Variable& fp, Node* left, Node* right) {
934 {
935 // Stack limit check.
936 IfBuilder cond(this);
937 cond.If(IntPtrLessThanOrEqual(fp.Get(), stack_limit_)).Then();
938 Return(Int32Constant(-1));
939 }
940 Store(kMachineWord32, fp.Get(), left_offset_, left);
941 Store(kMachineWord32, fp.Get(), right_offset_, right);
942 fp.Set(IntPtrAdd(fp.Get(), ConvertInt32ToIntPtr(stack_frame_size_)));
943 }
944 void Build() {
945 Variable left = NewVariable(Int32Constant(0));
946 Variable right =
947 NewVariable(Int32Sub(Parameter(kInputLengthParameter), one_));
948 input_ = Parameter(kInputParameter);
949 Node* top_of_stack = Parameter(kStackParameter);
950 stack_limit_ = IntPtrSub(
951 top_of_stack, ConvertInt32ToIntPtr(Parameter(kStackLengthParameter)));
952 Variable fp = NewVariable(top_of_stack);
953 {
954 Loop outermost(this);
955 // Edge case - 2 element array.
956 {
957 IfBuilder cond(this);
958 cond.If(Word32Equal(left.Get(), Int32Sub(right.Get(), one_))).And();
959 cond.If(Int32LessThanOrEqual(ArrayLoad(right.Get()),
960 ArrayLoad(left.Get()))).Then();
961 Swap(left.Get(), right.Get());
962 }
963 {
964 IfBuilder cond(this);
965 // Algorithm complete condition.
966 cond.If(WordEqual(top_of_stack, fp.Get())).And();
967 cond.If(Int32LessThanOrEqual(Int32Sub(right.Get(), one_), left.Get()))
968 .Then();
969 outermost.Break();
970 // 'Recursion' exit condition. Pop frame and continue.
971 cond.Else();
972 cond.If(Int32LessThanOrEqual(Int32Sub(right.Get(), one_), left.Get()))
973 .Then();
974 fp.Set(IntPtrSub(fp.Get(), ConvertInt32ToIntPtr(stack_frame_size_)));
975 left.Set(Load(kMachineWord32, fp.Get(), left_offset_));
976 right.Set(Load(kMachineWord32, fp.Get(), right_offset_));
977 outermost.Continue();
978 }
979 // Partition.
980 Variable store_index = NewVariable(left.Get());
981 {
982 Node* pivot_index =
983 Int32Div(Int32Add(left.Get(), right.Get()), Int32Constant(2));
984 Node* pivot = ArrayLoad(pivot_index);
985 Swap(pivot_index, right.Get());
986 Variable i = NewVariable(left.Get());
987 {
988 Loop partition(this);
989 {
990 IfBuilder cond(this);
991 // Parition complete.
992 cond.If(Word32Equal(i.Get(), right.Get())).Then();
993 partition.Break();
994 // Need swap.
995 cond.Else();
996 cond.If(Int32LessThanOrEqual(ArrayLoad(i.Get()), pivot)).Then();
997 Swap(i.Get(), store_index.Get());
998 Inc32(store_index);
999 }
1000 Inc32(i);
1001 } // End partition loop.
1002 Swap(store_index.Get(), right.Get());
1003 }
1004 // 'Recurse' left and right halves of partition.
1005 // Tail recurse second one.
1006 AddToCallStack(fp, left.Get(), Int32Sub(store_index.Get(), one_));
1007 left.Set(Int32Add(store_index.Get(), one_));
1008 } // End outermost loop.
1009 Return(Int32Constant(0));
1010 }
1011
1012 static const int kFrameVariables = 2; // left, right
1013 // Parameter offsets.
1014 static const int kInputParameter = 0;
1015 static const int kInputLengthParameter = 1;
1016 static const int kStackParameter = 2;
1017 static const int kStackLengthParameter = 3;
1018 // Function inputs.
1019 Node* input_;
1020 Node* stack_limit_;
1021 // Constants.
1022 Node* const one_;
1023 // Frame constants.
1024 Node* const stack_frame_size_;
1025 Node* const left_offset_;
1026 Node* const right_offset_;
1027 };
1028
1029
1030 TEST(RunSimpleQuicksort) {
1031 QuicksortHelper m;
1032 int32_t inputs[] = {9, 7, 1, 8, 11};
1033 CHECK_EQ(0, m.DoCall(inputs, ARRAY_SIZE(inputs)));
1034 }
1035
1036
1037 TEST(RunRandomQuicksort) {
1038 QuicksortHelper m;
1039
1040 v8::base::RandomNumberGenerator rng;
1041 static const int kMaxLength = 40;
1042 int32_t inputs[kMaxLength];
1043
1044 for (int length = 1; length < kMaxLength; length++) {
1045 for (int i = 0; i < 70; i++) {
1046 // Randomize inputs.
1047 for (int j = 0; j < length; j++) {
1048 inputs[j] = rng.NextInt(10) - 5;
1049 }
1050 CHECK_EQ(0, m.DoCall(inputs, length));
1051 }
1052 }
1053 }
1054
1055
1056 TEST(MultipleScopes) {
1057 StructuredMachineAssemblerTester<int32_t> m;
1058 for (int i = 0; i < 10; i++) {
1059 IfBuilder b(&m);
1060 b.If(m.Int32Constant(0)).Then();
1061 m.NewVariable(m.Int32Constant(0));
1062 }
1063 m.Return(m.Int32Constant(0));
1064 CHECK_EQ(0, m.Call());
1065 }
1066
1067 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698