OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 switch (node->opcode()) { | 348 switch (node->opcode()) { |
349 case IrOpcode::kChangeInt32ToTagged: | 349 case IrOpcode::kChangeInt32ToTagged: |
350 state = LowerChangeInt32ToTagged(node, *effect, *control); | 350 state = LowerChangeInt32ToTagged(node, *effect, *control); |
351 break; | 351 break; |
352 case IrOpcode::kChangeUint32ToTagged: | 352 case IrOpcode::kChangeUint32ToTagged: |
353 state = LowerChangeUint32ToTagged(node, *effect, *control); | 353 state = LowerChangeUint32ToTagged(node, *effect, *control); |
354 break; | 354 break; |
355 case IrOpcode::kChangeFloat64ToTagged: | 355 case IrOpcode::kChangeFloat64ToTagged: |
356 state = LowerChangeFloat64ToTagged(node, *effect, *control); | 356 state = LowerChangeFloat64ToTagged(node, *effect, *control); |
357 break; | 357 break; |
| 358 case IrOpcode::kObjectIsCallable: |
| 359 state = LowerObjectIsCallable(node, *effect, *control); |
| 360 break; |
| 361 case IrOpcode::kObjectIsNumber: |
| 362 state = LowerObjectIsNumber(node, *effect, *control); |
| 363 break; |
| 364 case IrOpcode::kObjectIsReceiver: |
| 365 state = LowerObjectIsReceiver(node, *effect, *control); |
| 366 break; |
| 367 case IrOpcode::kObjectIsString: |
| 368 state = LowerObjectIsString(node, *effect, *control); |
| 369 break; |
| 370 case IrOpcode::kObjectIsUndetectable: |
| 371 state = LowerObjectIsUndetectable(node, *effect, *control); |
| 372 break; |
358 default: | 373 default: |
359 return false; | 374 return false; |
360 } | 375 } |
361 NodeProperties::ReplaceUses(node, state.value); | 376 NodeProperties::ReplaceUses(node, state.value); |
362 *effect = state.effect; | 377 *effect = state.effect; |
363 *control = state.control; | 378 *control = state.control; |
364 return true; | 379 return true; |
365 } | 380 } |
366 | 381 |
367 EffectControlLinearizer::ValueEffectControl | 382 EffectControlLinearizer::ValueEffectControl |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 Node* merge = graph()->NewNode(common()->Merge(2), if_true, alloc.control); | 499 Node* merge = graph()->NewNode(common()->Merge(2), if_true, alloc.control); |
485 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | 500 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
486 vtrue, alloc.value, merge); | 501 vtrue, alloc.value, merge); |
487 Node* ephi = | 502 Node* ephi = |
488 graph()->NewNode(common()->EffectPhi(2), effect, alloc.effect, merge); | 503 graph()->NewNode(common()->EffectPhi(2), effect, alloc.effect, merge); |
489 | 504 |
490 return ValueEffectControl(phi, ephi, merge); | 505 return ValueEffectControl(phi, ephi, merge); |
491 } | 506 } |
492 | 507 |
493 EffectControlLinearizer::ValueEffectControl | 508 EffectControlLinearizer::ValueEffectControl |
| 509 EffectControlLinearizer::LowerObjectIsCallable(Node* node, Node* effect, |
| 510 Node* control) { |
| 511 Node* value = node->InputAt(0); |
| 512 |
| 513 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); |
| 514 Node* branch = |
| 515 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
| 516 |
| 517 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 518 Node* etrue = effect; |
| 519 Node* vtrue = jsgraph()->Int32Constant(0); |
| 520 |
| 521 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 522 Node* efalse = effect; |
| 523 Node* vfalse; |
| 524 { |
| 525 Node* value_map = efalse = |
| 526 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| 527 value, efalse, if_false); |
| 528 Node* value_bit_field = efalse = graph()->NewNode( |
| 529 simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map, |
| 530 efalse, if_false); |
| 531 vfalse = graph()->NewNode( |
| 532 machine()->Word32Equal(), |
| 533 jsgraph()->Int32Constant(1 << Map::kIsCallable), |
| 534 graph()->NewNode( |
| 535 machine()->Word32And(), value_bit_field, |
| 536 jsgraph()->Int32Constant((1 << Map::kIsCallable) | |
| 537 (1 << Map::kIsUndetectable)))); |
| 538 } |
| 539 |
| 540 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 541 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 542 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
| 543 vfalse, control); |
| 544 |
| 545 return ValueEffectControl(value, effect, control); |
| 546 } |
| 547 |
| 548 EffectControlLinearizer::ValueEffectControl |
| 549 EffectControlLinearizer::LowerObjectIsNumber(Node* node, Node* effect, |
| 550 Node* control) { |
| 551 Node* value = node->InputAt(0); |
| 552 |
| 553 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); |
| 554 Node* branch = graph()->NewNode(common()->Branch(), check, control); |
| 555 |
| 556 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 557 Node* etrue = effect; |
| 558 Node* vtrue = jsgraph()->Int32Constant(1); |
| 559 |
| 560 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 561 Node* efalse = effect; |
| 562 Node* vfalse; |
| 563 { |
| 564 Node* value_map = efalse = |
| 565 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| 566 value, efalse, if_false); |
| 567 vfalse = graph()->NewNode(machine()->WordEqual(), value_map, |
| 568 jsgraph()->HeapNumberMapConstant()); |
| 569 } |
| 570 |
| 571 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 572 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 573 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
| 574 vfalse, control); |
| 575 |
| 576 return ValueEffectControl(value, effect, control); |
| 577 } |
| 578 |
| 579 EffectControlLinearizer::ValueEffectControl |
| 580 EffectControlLinearizer::LowerObjectIsReceiver(Node* node, Node* effect, |
| 581 Node* control) { |
| 582 Node* value = node->InputAt(0); |
| 583 |
| 584 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); |
| 585 Node* branch = |
| 586 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
| 587 |
| 588 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 589 Node* etrue = effect; |
| 590 Node* vtrue = jsgraph()->Int32Constant(0); |
| 591 |
| 592 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 593 Node* efalse = effect; |
| 594 Node* vfalse; |
| 595 { |
| 596 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
| 597 Node* value_map = efalse = |
| 598 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| 599 value, efalse, if_false); |
| 600 Node* value_instance_type = efalse = graph()->NewNode( |
| 601 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, |
| 602 efalse, if_false); |
| 603 vfalse = graph()->NewNode(machine()->Uint32LessThanOrEqual(), |
| 604 jsgraph()->Uint32Constant(FIRST_JS_RECEIVER_TYPE), |
| 605 value_instance_type); |
| 606 } |
| 607 |
| 608 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 609 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 610 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
| 611 vfalse, control); |
| 612 |
| 613 return ValueEffectControl(value, effect, control); |
| 614 } |
| 615 |
| 616 EffectControlLinearizer::ValueEffectControl |
| 617 EffectControlLinearizer::LowerObjectIsString(Node* node, Node* effect, |
| 618 Node* control) { |
| 619 Node* value = node->InputAt(0); |
| 620 |
| 621 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); |
| 622 Node* branch = |
| 623 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
| 624 |
| 625 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 626 Node* etrue = effect; |
| 627 Node* vtrue = jsgraph()->Int32Constant(0); |
| 628 |
| 629 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 630 Node* efalse = effect; |
| 631 Node* vfalse; |
| 632 { |
| 633 Node* value_map = efalse = |
| 634 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| 635 value, efalse, if_false); |
| 636 Node* value_instance_type = efalse = graph()->NewNode( |
| 637 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, |
| 638 efalse, if_false); |
| 639 vfalse = graph()->NewNode(machine()->Uint32LessThan(), value_instance_type, |
| 640 jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE)); |
| 641 } |
| 642 |
| 643 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 644 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 645 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
| 646 vfalse, control); |
| 647 |
| 648 return ValueEffectControl(value, effect, control); |
| 649 } |
| 650 |
| 651 EffectControlLinearizer::ValueEffectControl |
| 652 EffectControlLinearizer::LowerObjectIsUndetectable(Node* node, Node* effect, |
| 653 Node* control) { |
| 654 Node* value = node->InputAt(0); |
| 655 |
| 656 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); |
| 657 Node* branch = |
| 658 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
| 659 |
| 660 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 661 Node* etrue = effect; |
| 662 Node* vtrue = jsgraph()->Int32Constant(0); |
| 663 |
| 664 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 665 Node* efalse = effect; |
| 666 Node* vfalse; |
| 667 { |
| 668 Node* value_map = efalse = |
| 669 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
| 670 value, efalse, if_false); |
| 671 Node* value_bit_field = efalse = graph()->NewNode( |
| 672 simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map, |
| 673 efalse, if_false); |
| 674 vfalse = graph()->NewNode( |
| 675 machine()->Word32Equal(), |
| 676 graph()->NewNode( |
| 677 machine()->Word32Equal(), jsgraph()->Int32Constant(0), |
| 678 graph()->NewNode( |
| 679 machine()->Word32And(), value_bit_field, |
| 680 jsgraph()->Int32Constant(1 << Map::kIsUndetectable))), |
| 681 jsgraph()->Int32Constant(0)); |
| 682 } |
| 683 |
| 684 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 685 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 686 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
| 687 vfalse, control); |
| 688 |
| 689 return ValueEffectControl(value, effect, control); |
| 690 } |
| 691 |
| 692 EffectControlLinearizer::ValueEffectControl |
494 EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect, | 693 EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect, |
495 Node* control) { | 694 Node* control) { |
496 effect = graph()->NewNode(common()->BeginRegion(), effect); | 695 effect = graph()->NewNode(common()->BeginRegion(), effect); |
497 Node* result = effect = | 696 Node* result = effect = |
498 graph()->NewNode(simplified()->Allocate(NOT_TENURED), | 697 graph()->NewNode(simplified()->Allocate(NOT_TENURED), |
499 jsgraph()->Constant(HeapNumber::kSize), effect, control); | 698 jsgraph()->Constant(HeapNumber::kSize), effect, control); |
500 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), | 699 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), |
501 result, jsgraph()->HeapNumberMapConstant(), effect, | 700 result, jsgraph()->HeapNumberMapConstant(), effect, |
502 control); | 701 control); |
503 effect = graph()->NewNode( | 702 effect = graph()->NewNode( |
(...skipping 29 matching lines...) Expand all Loading... |
533 return jsgraph()->Int32Constant(Smi::kMaxValue); | 732 return jsgraph()->Int32Constant(Smi::kMaxValue); |
534 } | 733 } |
535 | 734 |
536 Node* EffectControlLinearizer::SmiShiftBitsConstant() { | 735 Node* EffectControlLinearizer::SmiShiftBitsConstant() { |
537 return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); | 736 return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); |
538 } | 737 } |
539 | 738 |
540 } // namespace compiler | 739 } // namespace compiler |
541 } // namespace internal | 740 } // namespace internal |
542 } // namespace v8 | 741 } // namespace v8 |
OLD | NEW |