OLD | NEW |
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 <limits> | 5 #include <limits> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 #include "test/cctest/cctest.h" | 8 #include "test/cctest/cctest.h" |
9 #include "test/cctest/compiler/graph-builder-tester.h" | 9 #include "test/cctest/compiler/graph-builder-tester.h" |
10 #include "test/cctest/compiler/value-helper.h" | 10 #include "test/cctest/compiler/value-helper.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 CHECK_EQ(expected, *m.Value().handle()); | 72 CHECK_EQ(expected, *m.Value().handle()); |
73 } | 73 } |
74 | 74 |
75 void CheckNumberConstant(Node* n, double expected) { | 75 void CheckNumberConstant(Node* n, double expected) { |
76 NumberMatcher m(n); | 76 NumberMatcher m(n); |
77 CHECK_EQ(IrOpcode::kNumberConstant, n->opcode()); | 77 CHECK_EQ(IrOpcode::kNumberConstant, n->opcode()); |
78 CHECK(m.HasValue()); | 78 CHECK(m.HasValue()); |
79 CHECK_EQ(expected, m.Value()); | 79 CHECK_EQ(expected, m.Value()); |
80 } | 80 } |
81 | 81 |
82 Node* Parameter(int index = 0) { | 82 Node* Parameter(Type* type, int index = 0) { |
83 return graph()->NewNode(common()->Parameter(index), graph()->start()); | 83 Node* node = graph()->NewNode(common()->Parameter(index), graph()->start()); |
| 84 NodeProperties::SetBounds(node, Bounds(type)); |
| 85 return node; |
84 } | 86 } |
85 | 87 |
| 88 Node* Parameter(int index = 0) { return Parameter(Type::Any(), index); } |
| 89 |
86 void CheckTypeError(MachineTypeUnion from, MachineTypeUnion to) { | 90 void CheckTypeError(MachineTypeUnion from, MachineTypeUnion to) { |
87 changer()->testing_type_errors_ = true; | 91 changer()->testing_type_errors_ = true; |
88 changer()->type_error_ = false; | 92 changer()->type_error_ = false; |
89 Node* n = Parameter(0); | 93 Node* n = Parameter(0); |
90 Node* c = changer()->GetRepresentationFor(n, from, to); | 94 Node* c = changer()->GetRepresentationFor(n, from, to); |
91 CHECK(changer()->type_error_); | 95 CHECK(changer()->type_error_); |
92 CHECK_EQ(n, c); | 96 CHECK_EQ(n, c); |
93 } | 97 } |
94 | 98 |
95 void CheckNop(MachineTypeUnion from, MachineTypeUnion to) { | 99 void CheckNop(MachineTypeUnion from, MachineTypeUnion to) { |
96 Node* n = Parameter(0); | 100 Node* n = Parameter(0); |
97 Node* c = changer()->GetRepresentationFor(n, from, to); | 101 Node* c = changer()->GetRepresentationFor(n, from, to); |
98 CHECK_EQ(n, c); | 102 CHECK_EQ(n, c); |
99 } | 103 } |
100 }; | 104 }; |
101 } | 105 |
102 } | 106 } // namespace compiler |
103 } // namespace v8::internal::compiler | 107 } // namespace internal |
| 108 } // namespace v8 |
104 | 109 |
105 | 110 |
106 static const MachineType all_reps[] = {kRepBit, kRepWord32, kRepWord64, | 111 static const MachineType all_reps[] = {kRepBit, kRepWord32, kRepWord64, |
107 kRepFloat32, kRepFloat64, kRepTagged}; | 112 kRepFloat32, kRepFloat64, kRepTagged}; |
108 | 113 |
109 | 114 |
110 TEST(BoolToBit_constant) { | 115 TEST(ToBit_constant) { |
111 RepresentationChangerTester r; | 116 RepresentationChangerTester r; |
112 | 117 |
113 Node* true_node = r.jsgraph()->TrueConstant(); | 118 Node* true_node = r.jsgraph()->TrueConstant(); |
114 Node* true_bit = | 119 Node* true_bit = |
115 r.changer()->GetRepresentationFor(true_node, kRepTagged, kRepBit); | 120 r.changer()->GetRepresentationFor(true_node, kRepTagged, kRepBit); |
116 r.CheckInt32Constant(true_bit, 1); | 121 r.CheckInt32Constant(true_bit, 1); |
117 | 122 |
118 Node* false_node = r.jsgraph()->FalseConstant(); | 123 Node* false_node = r.jsgraph()->FalseConstant(); |
119 Node* false_bit = | 124 Node* false_bit = |
120 r.changer()->GetRepresentationFor(false_node, kRepTagged, kRepBit); | 125 r.changer()->GetRepresentationFor(false_node, kRepTagged, kRepBit); |
121 r.CheckInt32Constant(false_bit, 0); | 126 r.CheckInt32Constant(false_bit, 0); |
| 127 |
| 128 { |
| 129 FOR_FLOAT64_INPUTS(i) { |
| 130 Node* node = r.jsgraph()->Constant(*i); |
| 131 Node* bit = r.changer()->GetRepresentationFor(node, kRepTagged, kRepBit); |
| 132 r.CheckInt32Constant(bit, DoubleToBoolean(*i) ? 1 : 0); |
| 133 } |
| 134 } |
| 135 |
| 136 { |
| 137 FOR_INT32_INPUTS(i) { |
| 138 Node* node = r.jsgraph()->Int32Constant(*i); |
| 139 Node* bit = r.changer()->GetRepresentationFor(node, kRepWord32, kRepBit); |
| 140 r.CheckInt32Constant(bit, *i == 0 ? 0 : 1); |
| 141 } |
| 142 } |
122 } | 143 } |
123 | 144 |
124 | 145 |
125 TEST(BitToBool_constant) { | 146 TEST(BitToBool_constant) { |
126 RepresentationChangerTester r; | 147 RepresentationChangerTester r; |
127 | 148 |
128 for (int i = -5; i < 5; i++) { | 149 for (int i = -5; i < 5; i++) { |
129 Node* node = r.jsgraph()->Int32Constant(i); | 150 Node* node = r.jsgraph()->Int32Constant(i); |
130 Node* val = r.changer()->GetRepresentationFor(node, kRepBit, kRepTagged); | 151 Node* val = r.changer()->GetRepresentationFor(node, kRepBit, kRepTagged); |
131 r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value() | 152 r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value() |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 Node* n = r.jsgraph()->Constant(static_cast<double>(*i)); | 384 Node* n = r.jsgraph()->Constant(static_cast<double>(*i)); |
364 Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeUint32, | 385 Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeUint32, |
365 kRepWord32); | 386 kRepWord32); |
366 r.CheckUint32Constant(c, *i); | 387 r.CheckUint32Constant(c, *i); |
367 } | 388 } |
368 } | 389 } |
369 } | 390 } |
370 | 391 |
371 | 392 |
372 static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from, | 393 static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from, |
373 MachineTypeUnion to) { | 394 MachineTypeUnion to, Type* from_type = Type::Any()) { |
374 RepresentationChangerTester r; | 395 RepresentationChangerTester r; |
375 | 396 |
376 Node* n = r.Parameter(); | 397 Node* n = r.Parameter(from_type); |
377 Node* c = r.changer()->GetRepresentationFor(n, from, to); | 398 Node* c = r.changer()->GetRepresentationFor(n, from, to); |
378 | 399 |
379 CHECK_NE(c, n); | 400 CHECK_NE(c, n); |
380 CHECK_EQ(expected, c->opcode()); | 401 CHECK_EQ(expected, c->opcode()); |
381 CHECK_EQ(n, c->InputAt(0)); | 402 CHECK_EQ(n, c->InputAt(0)); |
382 } | 403 } |
383 | 404 |
384 | 405 |
385 static void CheckTwoChanges(IrOpcode::Value expected2, | 406 static void CheckTwoChanges(IrOpcode::Value expected2, |
386 IrOpcode::Value expected1, MachineTypeUnion from, | 407 IrOpcode::Value expected1, MachineTypeUnion from, |
387 MachineTypeUnion to) { | 408 MachineTypeUnion to, |
| 409 Type* from_type = Type::Any()) { |
388 RepresentationChangerTester r; | 410 RepresentationChangerTester r; |
389 | 411 |
390 Node* n = r.Parameter(); | 412 Node* n = r.Parameter(from_type); |
391 Node* c1 = r.changer()->GetRepresentationFor(n, from, to); | 413 Node* c1 = r.changer()->GetRepresentationFor(n, from, to); |
392 | 414 |
393 CHECK_NE(c1, n); | 415 CHECK_NE(c1, n); |
394 CHECK_EQ(expected1, c1->opcode()); | 416 CHECK_EQ(expected1, c1->opcode()); |
395 Node* c2 = c1->InputAt(0); | 417 Node* c2 = c1->InputAt(0); |
396 CHECK_NE(c2, n); | 418 CHECK_NE(c2, n); |
397 CHECK_EQ(expected2, c2->opcode()); | 419 CHECK_EQ(expected2, c2->opcode()); |
398 CHECK_EQ(n, c2->InputAt(0)); | 420 CHECK_EQ(n, c2->InputAt(0)); |
399 } | 421 } |
400 | 422 |
401 | 423 |
402 TEST(SingleChanges) { | 424 TEST(SingleChanges) { |
403 CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit); | 425 CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit, Type::Boolean()); |
| 426 CheckTwoChanges(IrOpcode::kChangeTaggedToInt32, IrOpcode::kChangeWord32ToBit, |
| 427 kRepTagged, kRepBit, Type::Signed32()); |
| 428 CheckTwoChanges(IrOpcode::kChangeTaggedToUint32, IrOpcode::kChangeWord32ToBit, |
| 429 kRepTagged, kRepBit, Type::Unsigned32()); |
| 430 CheckChange(IrOpcode::kChangeWord32ToBit, kRepWord8, kRepBit); |
| 431 CheckChange(IrOpcode::kChangeWord32ToBit, kRepWord16, kRepBit); |
| 432 CheckChange(IrOpcode::kChangeWord32ToBit, kRepWord32, kRepBit); |
| 433 CheckChange(IrOpcode::kChangeWord64ToBit, kRepWord64, kRepBit); |
404 CheckChange(IrOpcode::kChangeBitToBool, kRepBit, kRepTagged); | 434 CheckChange(IrOpcode::kChangeBitToBool, kRepBit, kRepTagged); |
405 | 435 |
406 CheckChange(IrOpcode::kChangeInt32ToTagged, kRepWord32 | kTypeInt32, | 436 CheckChange(IrOpcode::kChangeInt32ToTagged, kRepWord32 | kTypeInt32, |
407 kRepTagged); | 437 kRepTagged); |
408 CheckChange(IrOpcode::kChangeUint32ToTagged, kRepWord32 | kTypeUint32, | 438 CheckChange(IrOpcode::kChangeUint32ToTagged, kRepWord32 | kTypeUint32, |
409 kRepTagged); | 439 kRepTagged); |
410 CheckChange(IrOpcode::kChangeFloat64ToTagged, kRepFloat64, kRepTagged); | 440 CheckChange(IrOpcode::kChangeFloat64ToTagged, kRepFloat64, kRepTagged); |
411 | 441 |
412 CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged | kTypeInt32, | 442 CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged | kTypeInt32, |
413 kRepWord32); | 443 kRepWord32); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 // X -> X is always a nop for any single representation X. | 503 // X -> X is always a nop for any single representation X. |
474 for (size_t i = 0; i < arraysize(all_reps); i++) { | 504 for (size_t i = 0; i < arraysize(all_reps); i++) { |
475 r.CheckNop(all_reps[i], all_reps[i]); | 505 r.CheckNop(all_reps[i], all_reps[i]); |
476 } | 506 } |
477 | 507 |
478 // 32-bit floats. | 508 // 32-bit floats. |
479 r.CheckNop(kRepFloat32, kRepFloat32); | 509 r.CheckNop(kRepFloat32, kRepFloat32); |
480 r.CheckNop(kRepFloat32 | kTypeNumber, kRepFloat32); | 510 r.CheckNop(kRepFloat32 | kTypeNumber, kRepFloat32); |
481 r.CheckNop(kRepFloat32, kRepFloat32 | kTypeNumber); | 511 r.CheckNop(kRepFloat32, kRepFloat32 | kTypeNumber); |
482 | 512 |
483 // 32-bit or 64-bit words can be used as branch conditions (kRepBit). | |
484 r.CheckNop(kRepWord32, kRepBit); | |
485 r.CheckNop(kRepWord32, kRepBit | kTypeBool); | |
486 r.CheckNop(kRepWord64, kRepBit); | |
487 r.CheckNop(kRepWord64, kRepBit | kTypeBool); | |
488 | |
489 // 32-bit words can be used as smaller word sizes and vice versa, because | 513 // 32-bit words can be used as smaller word sizes and vice versa, because |
490 // loads from memory implicitly sign or zero extend the value to the | 514 // loads from memory implicitly sign or zero extend the value to the |
491 // full machine word size, and stores implicitly truncate. | 515 // full machine word size, and stores implicitly truncate. |
492 r.CheckNop(kRepWord32, kRepWord8); | 516 r.CheckNop(kRepWord32, kRepWord8); |
493 r.CheckNop(kRepWord32, kRepWord16); | 517 r.CheckNop(kRepWord32, kRepWord16); |
494 r.CheckNop(kRepWord32, kRepWord32); | 518 r.CheckNop(kRepWord32, kRepWord32); |
495 r.CheckNop(kRepWord8, kRepWord32); | 519 r.CheckNop(kRepWord8, kRepWord32); |
496 r.CheckNop(kRepWord16, kRepWord32); | 520 r.CheckNop(kRepWord16, kRepWord32); |
497 | 521 |
498 // kRepBit (result of comparison) is implicitly a wordish thing. | 522 // kRepBit (result of comparison) is implicitly a wordish thing. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 r.CheckTypeError(kRepWord32 | kTypeUint32, kRepWord64); | 562 r.CheckTypeError(kRepWord32 | kTypeUint32, kRepWord64); |
539 | 563 |
540 for (size_t i = 0; i < arraysize(all_reps); i++) { | 564 for (size_t i = 0; i < arraysize(all_reps); i++) { |
541 for (size_t j = 0; j < arraysize(all_reps); j++) { | 565 for (size_t j = 0; j < arraysize(all_reps); j++) { |
542 if (i == j) continue; | 566 if (i == j) continue; |
543 // Only a single from representation is allowed. | 567 // Only a single from representation is allowed. |
544 r.CheckTypeError(all_reps[i] | all_reps[j], kRepTagged); | 568 r.CheckTypeError(all_reps[i] | all_reps[j], kRepTagged); |
545 } | 569 } |
546 } | 570 } |
547 } | 571 } |
OLD | NEW |