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 "src/compiler/change-lowering.h" | 5 #include "src/compiler/change-lowering.h" |
6 #include "src/compiler/js-graph.h" | 6 #include "src/compiler/js-graph.h" |
7 #include "src/compiler/node-properties-inl.h" | 7 #include "src/compiler/node-properties-inl.h" |
8 #include "src/compiler/simplified-operator.h" | 8 #include "src/compiler/simplified-operator.h" |
9 #include "src/compiler/typer.h" | 9 #include "src/compiler/typer.h" |
10 #include "test/compiler-unittests/graph-unittest.h" | 10 #include "test/compiler-unittests/graph-unittest.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 case kRepWord32: | 46 case kRepWord32: |
47 return 4; | 47 return 4; |
48 case kRepWord64: | 48 case kRepWord64: |
49 return 8; | 49 return 8; |
50 default: | 50 default: |
51 break; | 51 break; |
52 } | 52 } |
53 UNREACHABLE(); | 53 UNREACHABLE(); |
54 return 0; | 54 return 0; |
55 } | 55 } |
| 56 int SmiMaxValue() const { return -(SmiMinValue() + 1); } |
| 57 int SmiMinValue() const { |
| 58 return static_cast<int>(0xffffffffu << (SmiValueSize() - 1)); |
| 59 } |
56 int SmiShiftAmount() const { return kSmiTagSize + SmiShiftSize(); } | 60 int SmiShiftAmount() const { return kSmiTagSize + SmiShiftSize(); } |
57 int SmiShiftSize() const { | 61 int SmiShiftSize() const { |
58 // TODO(turbofan): Work-around for weird GCC 4.6 linker issue: | 62 // TODO(turbofan): Work-around for weird GCC 4.6 linker issue: |
59 // src/compiler/change-lowering.cc:46: undefined reference to | 63 // src/compiler/change-lowering.cc:46: undefined reference to |
60 // `v8::internal::SmiTagging<4u>::kSmiShiftSize' | 64 // `v8::internal::SmiTagging<4u>::kSmiShiftSize' |
61 // src/compiler/change-lowering.cc:46: undefined reference to | 65 // src/compiler/change-lowering.cc:46: undefined reference to |
62 // `v8::internal::SmiTagging<8u>::kSmiShiftSize' | 66 // `v8::internal::SmiTagging<8u>::kSmiShiftSize' |
63 STATIC_ASSERT(SmiTagging<4>::kSmiShiftSize == 0); | 67 STATIC_ASSERT(SmiTagging<4>::kSmiShiftSize == 0); |
64 STATIC_ASSERT(SmiTagging<8>::kSmiShiftSize == 31); | 68 STATIC_ASSERT(SmiTagging<8>::kSmiShiftSize == 31); |
65 return Is32() ? 0 : 31; | 69 return Is32() ? 0 : 31; |
66 } | 70 } |
| 71 int SmiValueSize() const { |
| 72 // TODO(turbofan): Work-around for weird GCC 4.6 linker issue: |
| 73 // src/compiler/change-lowering.cc:46: undefined reference to |
| 74 // `v8::internal::SmiTagging<4u>::kSmiValueSize' |
| 75 // src/compiler/change-lowering.cc:46: undefined reference to |
| 76 // `v8::internal::SmiTagging<8u>::kSmiValueSize' |
| 77 STATIC_ASSERT(SmiTagging<4>::kSmiValueSize == 31); |
| 78 STATIC_ASSERT(SmiTagging<8>::kSmiValueSize == 32); |
| 79 return Is32() ? 31 : 32; |
| 80 } |
67 | 81 |
68 Node* Parameter(int32_t index = 0) { | 82 Node* Parameter(int32_t index = 0) { |
69 return graph()->NewNode(common()->Parameter(index), graph()->start()); | 83 return graph()->NewNode(common()->Parameter(index), graph()->start()); |
70 } | 84 } |
71 | 85 |
72 Reduction Reduce(Node* node) { | 86 Reduction Reduce(Node* node) { |
73 Typer typer(zone()); | 87 Typer typer(zone()); |
74 JSGraph jsgraph(graph(), common(), &typer); | 88 JSGraph jsgraph(graph(), common(), &typer); |
75 CompilationInfo info(isolate(), zone()); | 89 CompilationInfo info(isolate(), zone()); |
76 Linkage linkage(&info); | 90 Linkage linkage(&info); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 IsControlEffect(CaptureEq(&if_true)))), | 282 IsControlEffect(CaptureEq(&if_true)))), |
269 IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())), | 283 IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())), |
270 IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), | 284 IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), |
271 IsIfFalse(AllOf( | 285 IsIfFalse(AllOf( |
272 CaptureEq(&branch), | 286 CaptureEq(&branch), |
273 IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)), | 287 IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)), |
274 graph()->start())))))); | 288 graph()->start())))))); |
275 } | 289 } |
276 | 290 |
277 | 291 |
| 292 TARGET_TEST_F(ChangeLowering32Test, ChangeUint32ToTagged) { |
| 293 STATIC_ASSERT(kSmiTag == 0); |
| 294 STATIC_ASSERT(kSmiTagSize == 1); |
| 295 |
| 296 Node* val = Parameter(0); |
| 297 Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val); |
| 298 Reduction reduction = Reduce(node); |
| 299 ASSERT_TRUE(reduction.Changed()); |
| 300 |
| 301 Node* phi = reduction.replacement(); |
| 302 Capture<Node*> branch, heap_number, if_false; |
| 303 EXPECT_THAT( |
| 304 phi, |
| 305 IsPhi( |
| 306 IsWord32Shl(val, IsInt32Constant(SmiShiftAmount())), |
| 307 IsFinish( |
| 308 AllOf(CaptureEq(&heap_number), |
| 309 IsAllocateHeapNumber(_, CaptureEq(&if_false))), |
| 310 IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number), |
| 311 IsInt32Constant(HeapNumberValueOffset()), |
| 312 IsChangeUint32ToFloat64(val), CaptureEq(&heap_number), |
| 313 CaptureEq(&if_false))), |
| 314 IsMerge( |
| 315 IsIfTrue(AllOf(CaptureEq(&branch), |
| 316 IsBranch(IsUint32LessThanOrEqual( |
| 317 val, IsInt32Constant(SmiMaxValue())), |
| 318 graph()->start()))), |
| 319 AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch)))))); |
| 320 } |
| 321 |
| 322 |
278 // ----------------------------------------------------------------------------- | 323 // ----------------------------------------------------------------------------- |
279 // 64-bit | 324 // 64-bit |
280 | 325 |
281 | 326 |
282 class ChangeLowering64Test : public ChangeLoweringTest { | 327 class ChangeLowering64Test : public ChangeLoweringTest { |
283 public: | 328 public: |
284 virtual ~ChangeLowering64Test() {} | 329 virtual ~ChangeLowering64Test() {} |
285 virtual MachineType WordRepresentation() const V8_FINAL V8_OVERRIDE { | 330 virtual MachineType WordRepresentation() const V8_FINAL V8_OVERRIDE { |
286 return kRepWord64; | 331 return kRepWord64; |
287 } | 332 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 IsControlEffect(CaptureEq(&if_true)))), | 391 IsControlEffect(CaptureEq(&if_true)))), |
347 IsTruncateInt64ToInt32( | 392 IsTruncateInt64ToInt32( |
348 IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))), | 393 IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))), |
349 IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), | 394 IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), |
350 IsIfFalse(AllOf( | 395 IsIfFalse(AllOf( |
351 CaptureEq(&branch), | 396 CaptureEq(&branch), |
352 IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)), | 397 IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)), |
353 graph()->start())))))); | 398 graph()->start())))))); |
354 } | 399 } |
355 | 400 |
| 401 |
| 402 TARGET_TEST_F(ChangeLowering64Test, ChangeUint32ToTagged) { |
| 403 STATIC_ASSERT(kSmiTag == 0); |
| 404 STATIC_ASSERT(kSmiTagSize == 1); |
| 405 |
| 406 Node* val = Parameter(0); |
| 407 Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val); |
| 408 Reduction reduction = Reduce(node); |
| 409 ASSERT_TRUE(reduction.Changed()); |
| 410 |
| 411 Node* phi = reduction.replacement(); |
| 412 Capture<Node*> branch, heap_number, if_false; |
| 413 EXPECT_THAT( |
| 414 phi, |
| 415 IsPhi( |
| 416 IsWord64Shl(IsChangeUint32ToUint64(val), |
| 417 IsInt32Constant(SmiShiftAmount())), |
| 418 IsFinish( |
| 419 AllOf(CaptureEq(&heap_number), |
| 420 IsAllocateHeapNumber(_, CaptureEq(&if_false))), |
| 421 IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number), |
| 422 IsInt32Constant(HeapNumberValueOffset()), |
| 423 IsChangeUint32ToFloat64(val), CaptureEq(&heap_number), |
| 424 CaptureEq(&if_false))), |
| 425 IsMerge( |
| 426 IsIfTrue(AllOf(CaptureEq(&branch), |
| 427 IsBranch(IsUint32LessThanOrEqual( |
| 428 val, IsInt32Constant(SmiMaxValue())), |
| 429 graph()->start()))), |
| 430 AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch)))))); |
| 431 } |
| 432 |
356 } // namespace compiler | 433 } // namespace compiler |
357 } // namespace internal | 434 } // namespace internal |
358 } // namespace v8 | 435 } // namespace v8 |
OLD | NEW |