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

Side by Side Diff: test/cctest/compiler/compiler/test-simplified-lowering.cc

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback, rebase and "git cl format" 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 <limits>
6
7 #include "src/compiler/control-builders.h"
8 #include "src/compiler/node-properties-inl.h"
9 #include "src/compiler/pipeline.h"
10 #include "src/compiler/simplified-lowering.h"
11 #include "src/compiler/simplified-node-factory.h"
12 #include "src/compiler/typer.h"
13 #include "src/compiler/verifier.h"
14 #include "src/execution.h"
15 #include "src/parser.h"
16 #include "src/rewriter.h"
17 #include "src/scopes.h"
18 #include "test/cctest/cctest.h"
19 #include "test/cctest/compiler/codegen-tester.h"
20 #include "test/cctest/compiler/graph-builder-tester.h"
21 #include "test/cctest/compiler/value-helper.h"
22
23 using namespace v8::internal;
24 using namespace v8::internal::compiler;
25
26 template <typename ReturnType>
27 class SimplifiedGraphBuilderTester : public GraphBuilderTester<ReturnType> {
28 public:
29 SimplifiedGraphBuilderTester(MachineRepresentation p0 = kMachineLast,
30 MachineRepresentation p1 = kMachineLast,
31 MachineRepresentation p2 = kMachineLast,
32 MachineRepresentation p3 = kMachineLast,
33 MachineRepresentation p4 = kMachineLast)
34 : GraphBuilderTester<ReturnType>(p0, p1, p2, p3, p4) {}
35
36 // Close graph and lower one node.
37 void Lower(Node* node) {
38 this->End();
39 Typer typer(this->zone());
40 CommonOperatorBuilder common(this->zone());
41 SourcePositionTable source_positions(this->graph());
42 JSGraph jsgraph(this->graph(), &common, &typer);
43 SimplifiedLowering lowering(&jsgraph, &source_positions);
44 if (node == NULL) {
45 lowering.LowerAllNodes();
46 } else {
47 lowering.Lower(node);
48 }
49 }
50
51 // Close graph and lower all nodes.
52 void LowerAllNodes() { Lower(NULL); }
53
54 void StoreFloat64(Node* node, double* ptr) {
55 Node* ptr_node = this->PointerConstant(ptr);
56 this->Store(kMachineFloat64, ptr_node, node);
57 }
58
59 Node* LoadInt32(int32_t* ptr) {
60 Node* ptr_node = this->PointerConstant(ptr);
61 return this->Load(kMachineWord32, ptr_node);
62 }
63
64 Node* LoadUint32(uint32_t* ptr) {
65 Node* ptr_node = this->PointerConstant(ptr);
66 return this->Load(kMachineWord32, ptr_node);
67 }
68
69 Node* LoadFloat64(double* ptr) {
70 Node* ptr_node = this->PointerConstant(ptr);
71 return this->Load(kMachineFloat64, ptr_node);
72 }
73
74 Factory* factory() { return this->isolate()->factory(); }
75 Heap* heap() { return this->isolate()->heap(); }
76 };
77
78
79 class SimplifiedGraphBuilderJSTester
80 : public SimplifiedGraphBuilderTester<Object*> {
81 public:
82 SimplifiedGraphBuilderJSTester()
83 : SimplifiedGraphBuilderTester<Object*>(),
84 f_(v8::Utils::OpenHandle(*v8::Handle<v8::Function>::Cast(CompileRun(
85 "(function() { 'use strict'; return 2.7123; })")))),
86 swapped_(false) {
87 set_current_context(HeapConstant(handle(f_->context())));
88 }
89
90 template <typename T>
91 T* CallJS() {
92 if (!swapped_) {
93 Compile();
94 }
95 Handle<Object>* args = NULL;
96 MaybeHandle<Object> result = Execution::Call(
97 isolate(), f_, factory()->undefined_value(), 0, args, false);
98 return T::cast(*result.ToHandleChecked());
99 }
100
101 private:
102 void Compile() {
103 CompilationInfoWithZone info(f_);
104 CHECK(Parser::Parse(&info));
105 StrictMode strict_mode = info.function()->strict_mode();
106 info.SetStrictMode(strict_mode);
107 info.SetOptimizing(BailoutId::None(), Handle<Code>(f_->code()));
108 CHECK(Rewriter::Rewrite(&info));
109 CHECK(Scope::Analyze(&info));
110 CHECK_NE(NULL, info.scope());
111 Pipeline pipeline(&info);
112 Linkage linkage(&info);
113 Handle<Code> code = pipeline.GenerateCodeForMachineGraph(&linkage, graph());
114 CHECK(!code.is_null());
115 f_->ReplaceCode(*code);
116 swapped_ = true;
117 }
118
119 Handle<JSFunction> f_;
120 bool swapped_;
121 };
122
123
124 TEST(RunChangeTaggedToInt32) {
125 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged);
126 Node* x = t.ChangeTaggedToInt32(t.Parameter(0));
127 t.Return(x);
128
129 t.Lower(x);
130
131 // TODO(titzer): remove me.
132 return;
133
134 FOR_INT32_INPUTS(i) {
135 int32_t input = *i;
136
137 if (Smi::IsValid(input)) {
138 int32_t result = t.Call(Smi::FromInt(input));
139 CHECK_EQ(input, result);
140 }
141
142 {
143 Handle<Object> number = t.factory()->NewNumber(input);
144 int32_t result = t.Call(*number);
145 CHECK_EQ(input, result);
146 }
147
148 {
149 Handle<HeapNumber> number = t.factory()->NewHeapNumber(input);
150 int32_t result = t.Call(*number);
151 CHECK_EQ(input, result);
152 }
153 }
154 }
155
156
157 TEST(RunChangeTaggedToUint32) {
158 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged);
159 Node* x = t.ChangeTaggedToUint32(t.Parameter(0));
160 t.Return(x);
161
162 t.Lower(x);
163
164 // TODO(titzer): remove me.
165 return;
166
167 FOR_UINT32_INPUTS(i) {
168 uint32_t input = *i;
169
170 if (Smi::IsValid(input)) {
171 int32_t result = t.Call(Smi::FromInt(input));
172 CHECK_EQ(static_cast<int32_t>(input), result);
173 }
174
175 {
176 Handle<Object> number = t.factory()->NewNumber(input);
177 int32_t result = t.Call(*number);
178 CHECK_EQ(static_cast<int32_t>(input), result);
179 }
180
181 {
182 Handle<HeapNumber> number = t.factory()->NewHeapNumber(input);
183 int32_t result = t.Call(*number);
184 CHECK_EQ(static_cast<int32_t>(input), result);
185 }
186 }
187 }
188
189
190 TEST(RunChangeTaggedToFloat64) {
191 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged);
192 double result;
193 Node* x = t.ChangeTaggedToFloat64(t.Parameter(0));
194 t.StoreFloat64(x, &result);
195 t.Return(t.Int32Constant(0));
196
197 t.Lower(x);
198
199 // TODO(titzer): remove me.
200 return;
201
202 {
203 FOR_INT32_INPUTS(i) {
204 int32_t input = *i;
205
206 if (Smi::IsValid(input)) {
207 t.Call(Smi::FromInt(input));
208 CHECK_EQ(input, static_cast<int32_t>(result));
209 }
210
211 {
212 Handle<Object> number = t.factory()->NewNumber(input);
213 t.Call(*number);
214 CHECK_EQ(input, static_cast<int32_t>(result));
215 }
216
217 {
218 Handle<HeapNumber> number = t.factory()->NewHeapNumber(input);
219 t.Call(*number);
220 CHECK_EQ(input, static_cast<int32_t>(result));
221 }
222 }
223 }
224
225 {
226 FOR_FLOAT64_INPUTS(i) {
227 double input = *i;
228 {
229 Handle<Object> number = t.factory()->NewNumber(input);
230 t.Call(*number);
231 CHECK_EQ(input, result);
232 }
233
234 {
235 Handle<HeapNumber> number = t.factory()->NewHeapNumber(input);
236 t.Call(*number);
237 CHECK_EQ(input, result);
238 }
239 }
240 }
241 }
242
243
244 TEST(RunChangeBoolToBit) {
245 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged);
246 Node* x = t.ChangeBoolToBit(t.Parameter(0));
247 t.Return(x);
248
249 t.Lower(x);
250
251 if (!Pipeline::SupportedTarget()) return;
252
253 {
254 Object* true_obj = t.heap()->true_value();
255 int32_t result = t.Call(true_obj);
256 CHECK_EQ(1, result);
257 }
258
259 {
260 Object* false_obj = t.heap()->false_value();
261 int32_t result = t.Call(false_obj);
262 CHECK_EQ(0, result);
263 }
264 }
265
266
267 TEST(RunChangeBitToBool) {
268 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged);
269 Node* x = t.ChangeBitToBool(t.Parameter(0));
270 t.Return(x);
271
272 t.Lower(x);
273
274 // TODO(titzer): remove me.
275 return;
276
277 {
278 Object* result = t.Call(1);
279 Object* true_obj = t.heap()->true_value();
280 CHECK_EQ(true_obj, result);
281 }
282
283 {
284 Object* result = t.Call(0);
285 Object* false_obj = t.heap()->false_value();
286 CHECK_EQ(false_obj, result);
287 }
288 }
289
290
291 TEST(RunChangeInt32ToTagged) {
292 SimplifiedGraphBuilderJSTester t;
293 int32_t input;
294 Node* load = t.LoadInt32(&input);
295 Node* x = t.ChangeInt32ToTagged(load);
296 t.Return(x);
297
298 t.Lower(x);
299
300 // TODO(titzer): remove me.
301 return;
302
303
304 {
305 FOR_INT32_INPUTS(i) {
306 input = *i;
307 HeapNumber* result = t.CallJS<HeapNumber>();
308 CHECK_EQ(static_cast<double>(input), result->value());
309 }
310 }
311
312 {
313 FOR_INT32_INPUTS(i) {
314 input = *i;
315 SimulateFullSpace(CcTest::heap()->new_space());
316 HeapNumber* result = t.CallJS<HeapNumber>();
317 CHECK_EQ(static_cast<double>(input), result->value());
318 }
319 }
320 }
321
322
323 TEST(RunChangeUint32ToTagged) {
324 SimplifiedGraphBuilderJSTester t;
325 uint32_t input;
326 Node* load = t.LoadUint32(&input);
327 Node* x = t.ChangeUint32ToTagged(load);
328 t.Return(x);
329
330 t.Lower(x);
331
332 // TODO(titzer): remove me.
333 return;
334
335 {
336 FOR_UINT32_INPUTS(i) {
337 input = *i;
338 HeapNumber* result = t.CallJS<HeapNumber>();
339 double expected = static_cast<double>(input);
340 CHECK_EQ(expected, result->value());
341 }
342 }
343
344 {
345 FOR_UINT32_INPUTS(i) {
346 input = *i;
347 SimulateFullSpace(CcTest::heap()->new_space());
348 HeapNumber* result = t.CallJS<HeapNumber>();
349 double expected = static_cast<double>(static_cast<uint32_t>(input));
350 CHECK_EQ(expected, result->value());
351 }
352 }
353 }
354
355
356 TEST(RunChangeFloat64ToTagged) {
357 SimplifiedGraphBuilderJSTester t;
358 double input;
359 Node* load = t.LoadFloat64(&input);
360 Node* x = t.ChangeFloat64ToTagged(load);
361 t.Return(x);
362
363 t.Lower(x);
364
365 // TODO(titzer): remove me.
366 return;
367
368 {
369 FOR_FLOAT64_INPUTS(i) {
370 input = *i;
371 HeapNumber* result = t.CallJS<HeapNumber>();
372 CHECK_EQ(input, result->value());
373 }
374 }
375 {
376 FOR_FLOAT64_INPUTS(i) {
377 input = *i;
378 SimulateFullSpace(CcTest::heap()->new_space());
379 HeapNumber* result = t.CallJS<HeapNumber>();
380 CHECK_EQ(input, result->value());
381 }
382 }
383 }
384
385
386 // TODO(dcarney): find a home for these functions.
387 namespace {
388
389 FieldAccess ForJSObjectMap() {
390 FieldAccess access = {JSObject::kMapOffset, Handle<Name>(), Type::Any(),
391 kMachineTagged};
392 return access;
393 }
394
395
396 FieldAccess ForJSObjectProperties() {
397 FieldAccess access = {JSObject::kPropertiesOffset, Handle<Name>(),
398 Type::Any(), kMachineTagged};
399 return access;
400 }
401
402
403 FieldAccess ForArrayBufferBackingStore() {
404 FieldAccess access = {
405 JSArrayBuffer::kBackingStoreOffset, Handle<Name>(), Type::UntaggedPtr(),
406 MachineOperatorBuilder::pointer_rep(),
407 };
408 return access;
409 }
410
411
412 ElementAccess ForFixedArrayElement() {
413 ElementAccess access = {FixedArray::kHeaderSize, Type::Any(), kMachineTagged};
414 return access;
415 }
416
417
418 ElementAccess ForBackingStoreElement(MachineRepresentation rep) {
419 ElementAccess access = {kNonHeapObjectHeaderSize, Type::Any(), rep};
420 return access;
421 }
422 }
423
424
425 // Create a simple JSObject with a unique map.
426 static Handle<JSObject> TestObject() {
427 static int index = 0;
428 char buffer[50];
429 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++);
430 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer)));
431 }
432
433
434 TEST(RunLoadMap) {
435 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged);
436 FieldAccess access = ForJSObjectMap();
437 Node* load = t.LoadField(access, t.Parameter(0));
438 t.Return(load);
439
440 t.LowerAllNodes();
441
442 if (!Pipeline::SupportedTarget()) return;
443
444 Handle<JSObject> src = TestObject();
445 Handle<Map> src_map(src->map());
446 Object* result = t.Call(*src);
447 CHECK_EQ(*src_map, result);
448 }
449
450
451 TEST(RunStoreMap) {
452 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged, kMachineTagged);
453 FieldAccess access = ForJSObjectMap();
454 t.StoreField(access, t.Parameter(1), t.Parameter(0));
455 t.Return(t.Int32Constant(0));
456
457 t.LowerAllNodes();
458
459 if (!Pipeline::SupportedTarget()) return;
460
461 Handle<JSObject> src = TestObject();
462 Handle<Map> src_map(src->map());
463 Handle<JSObject> dst = TestObject();
464 CHECK(src->map() != dst->map());
465 t.Call(*src_map, *dst);
466 CHECK(*src_map == dst->map());
467 }
468
469
470 TEST(RunLoadProperties) {
471 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged);
472 FieldAccess access = ForJSObjectProperties();
473 Node* load = t.LoadField(access, t.Parameter(0));
474 t.Return(load);
475
476 t.LowerAllNodes();
477
478 if (!Pipeline::SupportedTarget()) return;
479
480 Handle<JSObject> src = TestObject();
481 Handle<FixedArray> src_props(src->properties());
482 Object* result = t.Call(*src);
483 CHECK_EQ(*src_props, result);
484 }
485
486
487 TEST(RunLoadStoreMap) {
488 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged, kMachineTagged);
489 FieldAccess access = ForJSObjectMap();
490 Node* load = t.LoadField(access, t.Parameter(0));
491 t.StoreField(access, t.Parameter(1), load);
492 t.Return(load);
493
494 t.LowerAllNodes();
495
496 if (!Pipeline::SupportedTarget()) return;
497
498 Handle<JSObject> src = TestObject();
499 Handle<Map> src_map(src->map());
500 Handle<JSObject> dst = TestObject();
501 CHECK(src->map() != dst->map());
502 Object* result = t.Call(*src, *dst);
503 CHECK(result->IsMap());
504 CHECK_EQ(*src_map, result);
505 CHECK(*src_map == dst->map());
506 }
507
508
509 TEST(RunLoadStoreFixedArrayIndex) {
510 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged);
511 ElementAccess access = ForFixedArrayElement();
512 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0));
513 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load);
514 t.Return(load);
515
516 t.LowerAllNodes();
517
518 if (!Pipeline::SupportedTarget()) return;
519
520 Handle<FixedArray> array = t.factory()->NewFixedArray(2);
521 Handle<JSObject> src = TestObject();
522 Handle<JSObject> dst = TestObject();
523 array->set(0, *src);
524 array->set(1, *dst);
525 Object* result = t.Call(*array);
526 CHECK_EQ(*src, result);
527 CHECK_EQ(*src, array->get(0));
528 CHECK_EQ(*src, array->get(1));
529 }
530
531
532 TEST(RunLoadStoreArrayBuffer) {
533 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged);
534 const int index = 12;
535 FieldAccess access = ForArrayBufferBackingStore();
536 Node* backing_store = t.LoadField(access, t.Parameter(0));
537 ElementAccess buffer_access = ForBackingStoreElement(kMachineWord8);
538 Node* load =
539 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index));
540 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1),
541 load);
542 t.Return(load);
543
544 t.LowerAllNodes();
545
546 if (!Pipeline::SupportedTarget()) return;
547
548 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer();
549 const int array_length = 2 * index;
550 Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length);
551 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store());
552 for (int i = 0; i < array_length; i++) {
553 data[i] = i;
554 }
555 int32_t result = t.Call(*array);
556 CHECK_EQ(index, result);
557 for (int i = 0; i < array_length; i++) {
558 uint8_t expected = i;
559 if (i == (index + 1)) expected = result;
560 CHECK_EQ(data[i], expected);
561 }
562 }
563
564
565 TEST(RunCopyFixedArray) {
566 SimplifiedGraphBuilderTester<int32_t> t(kMachineTagged, kMachineTagged);
567
568 const int kArraySize = 15;
569 Node* one = t.Int32Constant(1);
570 Node* index = t.Int32Constant(0);
571 Node* limit = t.Int32Constant(kArraySize);
572 t.environment()->Push(index);
573 {
574 LoopBuilder loop(&t);
575 loop.BeginLoop();
576 // Loop exit condition.
577 index = t.environment()->Top();
578 Node* condition = t.Int32LessThan(index, limit);
579 loop.BreakUnless(condition);
580 // src[index] = dst[index].
581 index = t.environment()->Pop();
582 ElementAccess access = ForFixedArrayElement();
583 Node* src = t.Parameter(0);
584 Node* load = t.LoadElement(access, src, index);
585 Node* dst = t.Parameter(1);
586 t.StoreElement(access, dst, index, load);
587 // index++
588 index = t.Int32Add(index, one);
589 t.environment()->Push(index);
590 // continue.
591 loop.EndBody();
592 loop.EndLoop();
593 }
594 index = t.environment()->Pop();
595 t.Return(index);
596
597 t.LowerAllNodes();
598
599 if (!Pipeline::SupportedTarget()) return;
600
601 Handle<FixedArray> src = t.factory()->NewFixedArray(kArraySize);
602 Handle<FixedArray> src_copy = t.factory()->NewFixedArray(kArraySize);
603 Handle<FixedArray> dst = t.factory()->NewFixedArray(kArraySize);
604 for (int i = 0; i < kArraySize; i++) {
605 src->set(i, *TestObject());
606 src_copy->set(i, src->get(i));
607 dst->set(i, *TestObject());
608 CHECK_NE(src_copy->get(i), dst->get(i));
609 }
610 CHECK_EQ(kArraySize, t.Call(*src, *dst));
611 for (int i = 0; i < kArraySize; i++) {
612 CHECK_EQ(src_copy->get(i), dst->get(i));
613 }
614 }
OLDNEW
« no previous file with comments | « test/cctest/compiler/compiler/test-scheduler.cc ('k') | test/cctest/compiler/compiler/test-structured-ifbuilder-fuzzer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698