| 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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 Type* upper = NodeProperties::GetType(node); | 361 Type* upper = NodeProperties::GetType(node); |
| 362 MachineType output_type = | 362 MachineType output_type = |
| 363 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); | 363 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); |
| 364 SetOutput(node, output_type); | 364 SetOutput(node, output_type); |
| 365 | 365 |
| 366 if (lower()) { | 366 if (lower()) { |
| 367 // Update the select operator. | 367 // Update the select operator. |
| 368 SelectParameters p = SelectParametersOf(node->op()); | 368 SelectParameters p = SelectParametersOf(node->op()); |
| 369 MachineType type = static_cast<MachineType>(output_type); | 369 MachineType type = static_cast<MachineType>(output_type); |
| 370 if (type != p.type()) { | 370 if (type != p.type()) { |
| 371 node->set_op(lowering->common()->Select(type, p.hint())); | 371 NodeProperties::ChangeOp(node, |
| 372 lowering->common()->Select(type, p.hint())); |
| 372 } | 373 } |
| 373 | 374 |
| 374 // Convert inputs to the output representation of this select. | 375 // Convert inputs to the output representation of this select. |
| 375 ProcessInput(node, 1, output_type); | 376 ProcessInput(node, 1, output_type); |
| 376 ProcessInput(node, 2, output_type); | 377 ProcessInput(node, 2, output_type); |
| 377 } else { | 378 } else { |
| 378 // Propagate {use} of the select to value inputs. | 379 // Propagate {use} of the select to value inputs. |
| 379 MachineType use_type = | 380 MachineType use_type = |
| 380 static_cast<MachineType>((use & kTypeMask) | output); | 381 static_cast<MachineType>((use & kTypeMask) | output); |
| 381 ProcessInput(node, 1, use_type); | 382 ProcessInput(node, 1, use_type); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 392 MachineType output_type = | 393 MachineType output_type = |
| 393 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); | 394 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); |
| 394 SetOutput(node, output_type); | 395 SetOutput(node, output_type); |
| 395 | 396 |
| 396 int values = node->op()->ValueInputCount(); | 397 int values = node->op()->ValueInputCount(); |
| 397 | 398 |
| 398 if (lower()) { | 399 if (lower()) { |
| 399 // Update the phi operator. | 400 // Update the phi operator. |
| 400 MachineType type = static_cast<MachineType>(output_type); | 401 MachineType type = static_cast<MachineType>(output_type); |
| 401 if (type != OpParameter<MachineType>(node)) { | 402 if (type != OpParameter<MachineType>(node)) { |
| 402 node->set_op(lowering->common()->Phi(type, values)); | 403 NodeProperties::ChangeOp(node, lowering->common()->Phi(type, values)); |
| 403 } | 404 } |
| 404 | 405 |
| 405 // Convert inputs to the output representation of this phi. | 406 // Convert inputs to the output representation of this phi. |
| 406 for (int i = 0; i < node->InputCount(); i++) { | 407 for (int i = 0; i < node->InputCount(); i++) { |
| 407 ProcessInput(node, i, i < values ? output_type : 0); | 408 ProcessInput(node, i, i < values ? output_type : 0); |
| 408 } | 409 } |
| 409 } else { | 410 } else { |
| 410 // Propagate {use} of the phi to value inputs, and 0 to control. | 411 // Propagate {use} of the phi to value inputs, and 0 to control. |
| 411 MachineType use_type = | 412 MachineType use_type = |
| 412 static_cast<MachineType>((use & kTypeMask) | output); | 413 static_cast<MachineType>((use & kTypeMask) | output); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 } | 447 } |
| 447 } else { | 448 } else { |
| 448 Zone* zone = jsgraph_->zone(); | 449 Zone* zone = jsgraph_->zone(); |
| 449 ZoneVector<MachineType>* types = | 450 ZoneVector<MachineType>* types = |
| 450 new (zone->New(sizeof(ZoneVector<MachineType>))) | 451 new (zone->New(sizeof(ZoneVector<MachineType>))) |
| 451 ZoneVector<MachineType>(node->InputCount(), zone); | 452 ZoneVector<MachineType>(node->InputCount(), zone); |
| 452 for (int i = 0; i < node->InputCount(); i++) { | 453 for (int i = 0; i < node->InputCount(); i++) { |
| 453 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output; | 454 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output; |
| 454 (*types)[i] = static_cast<MachineType>(input_type); | 455 (*types)[i] = static_cast<MachineType>(input_type); |
| 455 } | 456 } |
| 456 node->set_op(jsgraph_->common()->TypedStateValues(types)); | 457 NodeProperties::ChangeOp(node, |
| 458 jsgraph_->common()->TypedStateValues(types)); |
| 457 } | 459 } |
| 458 SetOutput(node, kMachAnyTagged); | 460 SetOutput(node, kMachAnyTagged); |
| 459 } | 461 } |
| 460 | 462 |
| 461 const Operator* Int32Op(Node* node) { | 463 const Operator* Int32Op(Node* node) { |
| 462 return changer_->Int32OperatorFor(node->opcode()); | 464 return changer_->Int32OperatorFor(node->opcode()); |
| 463 } | 465 } |
| 464 | 466 |
| 465 const Operator* Uint32Op(Node* node) { | 467 const Operator* Uint32Op(Node* node) { |
| 466 return changer_->Uint32OperatorFor(node->opcode()); | 468 return changer_->Uint32OperatorFor(node->opcode()); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 return SetOutput(node, kRepTagged); | 578 return SetOutput(node, kRepTagged); |
| 577 | 579 |
| 578 //------------------------------------------------------------------ | 580 //------------------------------------------------------------------ |
| 579 // Simplified operators. | 581 // Simplified operators. |
| 580 //------------------------------------------------------------------ | 582 //------------------------------------------------------------------ |
| 581 case IrOpcode::kBooleanNot: { | 583 case IrOpcode::kBooleanNot: { |
| 582 if (lower()) { | 584 if (lower()) { |
| 583 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; | 585 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; |
| 584 if (input & kRepBit) { | 586 if (input & kRepBit) { |
| 585 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) | 587 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) |
| 586 node->set_op(lowering->machine()->Word32Equal()); | |
| 587 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); | 588 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); |
| 589 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); |
| 588 } else { | 590 } else { |
| 589 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) | 591 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) |
| 590 node->set_op(lowering->machine()->WordEqual()); | |
| 591 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); | 592 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); |
| 593 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
| 592 } | 594 } |
| 593 } else { | 595 } else { |
| 594 // No input representation requirement; adapt during lowering. | 596 // No input representation requirement; adapt during lowering. |
| 595 ProcessInput(node, 0, kTypeBool); | 597 ProcessInput(node, 0, kTypeBool); |
| 596 SetOutput(node, kRepBit); | 598 SetOutput(node, kRepBit); |
| 597 } | 599 } |
| 598 break; | 600 break; |
| 599 } | 601 } |
| 600 case IrOpcode::kBooleanToNumber: { | 602 case IrOpcode::kBooleanToNumber: { |
| 601 if (lower()) { | 603 if (lower()) { |
| 602 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; | 604 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; |
| 603 if (input & kRepBit) { | 605 if (input & kRepBit) { |
| 604 // BooleanToNumber(x: kRepBit) => x | 606 // BooleanToNumber(x: kRepBit) => x |
| 605 DeferReplacement(node, node->InputAt(0)); | 607 DeferReplacement(node, node->InputAt(0)); |
| 606 } else { | 608 } else { |
| 607 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) | 609 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) |
| 608 node->set_op(lowering->machine()->WordEqual()); | |
| 609 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); | 610 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); |
| 611 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
| 610 } | 612 } |
| 611 } else { | 613 } else { |
| 612 // No input representation requirement; adapt during lowering. | 614 // No input representation requirement; adapt during lowering. |
| 613 ProcessInput(node, 0, kTypeBool); | 615 ProcessInput(node, 0, kTypeBool); |
| 614 SetOutput(node, kMachInt32); | 616 SetOutput(node, kMachInt32); |
| 615 } | 617 } |
| 616 break; | 618 break; |
| 617 } | 619 } |
| 618 case IrOpcode::kNumberEqual: | 620 case IrOpcode::kNumberEqual: |
| 619 case IrOpcode::kNumberLessThan: | 621 case IrOpcode::kNumberLessThan: |
| 620 case IrOpcode::kNumberLessThanOrEqual: { | 622 case IrOpcode::kNumberLessThanOrEqual: { |
| 621 // Number comparisons reduce to integer comparisons for integer inputs. | 623 // Number comparisons reduce to integer comparisons for integer inputs. |
| 622 if (BothInputsAre(node, Type::Signed32())) { | 624 if (BothInputsAre(node, Type::Signed32())) { |
| 623 // => signed Int32Cmp | 625 // => signed Int32Cmp |
| 624 VisitInt32Cmp(node); | 626 VisitInt32Cmp(node); |
| 625 if (lower()) node->set_op(Int32Op(node)); | 627 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
| 626 } else if (BothInputsAre(node, Type::Unsigned32())) { | 628 } else if (BothInputsAre(node, Type::Unsigned32())) { |
| 627 // => unsigned Int32Cmp | 629 // => unsigned Int32Cmp |
| 628 VisitUint32Cmp(node); | 630 VisitUint32Cmp(node); |
| 629 if (lower()) node->set_op(Uint32Op(node)); | 631 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
| 630 } else { | 632 } else { |
| 631 // => Float64Cmp | 633 // => Float64Cmp |
| 632 VisitFloat64Cmp(node); | 634 VisitFloat64Cmp(node); |
| 633 if (lower()) node->set_op(Float64Op(node)); | 635 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
| 634 } | 636 } |
| 635 break; | 637 break; |
| 636 } | 638 } |
| 637 case IrOpcode::kNumberAdd: | 639 case IrOpcode::kNumberAdd: |
| 638 case IrOpcode::kNumberSubtract: { | 640 case IrOpcode::kNumberSubtract: { |
| 639 // Add and subtract reduce to Int32Add/Sub if the inputs | 641 // Add and subtract reduce to Int32Add/Sub if the inputs |
| 640 // are already integers and all uses are truncating. | 642 // are already integers and all uses are truncating. |
| 641 if (CanLowerToInt32Binop(node, use)) { | 643 if (CanLowerToInt32Binop(node, use)) { |
| 642 // => signed Int32Add/Sub | 644 // => signed Int32Add/Sub |
| 643 VisitInt32Binop(node); | 645 VisitInt32Binop(node); |
| 644 if (lower()) node->set_op(Int32Op(node)); | 646 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
| 645 } else if (CanLowerToInt32AdditiveBinop(node, use)) { | 647 } else if (CanLowerToInt32AdditiveBinop(node, use)) { |
| 646 // => signed Int32Add/Sub, truncating inputs | 648 // => signed Int32Add/Sub, truncating inputs |
| 647 ProcessTruncateWord32Input(node, 0, kTypeInt32); | 649 ProcessTruncateWord32Input(node, 0, kTypeInt32); |
| 648 ProcessTruncateWord32Input(node, 1, kTypeInt32); | 650 ProcessTruncateWord32Input(node, 1, kTypeInt32); |
| 649 SetOutput(node, kMachInt32); | 651 SetOutput(node, kMachInt32); |
| 650 if (lower()) node->set_op(Int32Op(node)); | 652 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
| 651 } else if (CanLowerToUint32Binop(node, use)) { | 653 } else if (CanLowerToUint32Binop(node, use)) { |
| 652 // => unsigned Int32Add/Sub | 654 // => unsigned Int32Add/Sub |
| 653 VisitUint32Binop(node); | 655 VisitUint32Binop(node); |
| 654 if (lower()) node->set_op(Uint32Op(node)); | 656 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
| 655 } else if (CanLowerToUint32AdditiveBinop(node, use)) { | 657 } else if (CanLowerToUint32AdditiveBinop(node, use)) { |
| 656 // => signed Int32Add/Sub, truncating inputs | 658 // => signed Int32Add/Sub, truncating inputs |
| 657 ProcessTruncateWord32Input(node, 0, kTypeUint32); | 659 ProcessTruncateWord32Input(node, 0, kTypeUint32); |
| 658 ProcessTruncateWord32Input(node, 1, kTypeUint32); | 660 ProcessTruncateWord32Input(node, 1, kTypeUint32); |
| 659 SetOutput(node, kMachUint32); | 661 SetOutput(node, kMachUint32); |
| 660 if (lower()) node->set_op(Uint32Op(node)); | 662 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
| 661 } else { | 663 } else { |
| 662 // => Float64Add/Sub | 664 // => Float64Add/Sub |
| 663 VisitFloat64Binop(node); | 665 VisitFloat64Binop(node); |
| 664 if (lower()) node->set_op(Float64Op(node)); | 666 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
| 665 } | 667 } |
| 666 break; | 668 break; |
| 667 } | 669 } |
| 668 case IrOpcode::kNumberMultiply: { | 670 case IrOpcode::kNumberMultiply: { |
| 669 NumberMatcher right(node->InputAt(1)); | 671 NumberMatcher right(node->InputAt(1)); |
| 670 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa. | 672 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa. |
| 671 if (CanLowerToInt32Binop(node, use)) { | 673 if (CanLowerToInt32Binop(node, use)) { |
| 672 // => signed Int32Mul | 674 // => signed Int32Mul |
| 673 VisitInt32Binop(node); | 675 VisitInt32Binop(node); |
| 674 if (lower()) node->set_op(Int32Op(node)); | 676 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
| 675 break; | 677 break; |
| 676 } | 678 } |
| 677 } | 679 } |
| 678 // => Float64Mul | 680 // => Float64Mul |
| 679 VisitFloat64Binop(node); | 681 VisitFloat64Binop(node); |
| 680 if (lower()) node->set_op(Float64Op(node)); | 682 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
| 681 break; | 683 break; |
| 682 } | 684 } |
| 683 case IrOpcode::kNumberDivide: { | 685 case IrOpcode::kNumberDivide: { |
| 684 if (CanLowerToInt32Binop(node, use)) { | 686 if (CanLowerToInt32Binop(node, use)) { |
| 685 // => signed Int32Div | 687 // => signed Int32Div |
| 686 VisitInt32Binop(node); | 688 VisitInt32Binop(node); |
| 687 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); | 689 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
| 688 break; | 690 break; |
| 689 } | 691 } |
| 690 if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) { | 692 if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) { |
| 691 // => unsigned Uint32Div | 693 // => unsigned Uint32Div |
| 692 VisitUint32Binop(node); | 694 VisitUint32Binop(node); |
| 693 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); | 695 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); |
| 694 break; | 696 break; |
| 695 } | 697 } |
| 696 // => Float64Div | 698 // => Float64Div |
| 697 VisitFloat64Binop(node); | 699 VisitFloat64Binop(node); |
| 698 if (lower()) node->set_op(Float64Op(node)); | 700 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
| 699 break; | 701 break; |
| 700 } | 702 } |
| 701 case IrOpcode::kNumberModulus: { | 703 case IrOpcode::kNumberModulus: { |
| 702 if (CanLowerToInt32Binop(node, use)) { | 704 if (CanLowerToInt32Binop(node, use)) { |
| 703 // => signed Int32Mod | 705 // => signed Int32Mod |
| 704 VisitInt32Binop(node); | 706 VisitInt32Binop(node); |
| 705 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 707 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
| 706 break; | 708 break; |
| 707 } | 709 } |
| 708 if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) { | 710 if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) { |
| 709 // => unsigned Uint32Mod | 711 // => unsigned Uint32Mod |
| 710 VisitUint32Binop(node); | 712 VisitUint32Binop(node); |
| 711 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 713 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); |
| 712 break; | 714 break; |
| 713 } | 715 } |
| 714 // => Float64Mod | 716 // => Float64Mod |
| 715 VisitFloat64Binop(node); | 717 VisitFloat64Binop(node); |
| 716 if (lower()) node->set_op(Float64Op(node)); | 718 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
| 717 break; | 719 break; |
| 718 } | 720 } |
| 719 case IrOpcode::kNumberShiftLeft: { | 721 case IrOpcode::kNumberShiftLeft: { |
| 720 VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); | 722 VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); |
| 721 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); | 723 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); |
| 722 break; | 724 break; |
| 723 } | 725 } |
| 724 case IrOpcode::kNumberShiftRight: { | 726 case IrOpcode::kNumberShiftRight: { |
| 725 VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); | 727 VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); |
| 726 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); | 728 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 748 } else if ((in & kTypeMask) == kTypeInt32 || | 750 } else if ((in & kTypeMask) == kTypeInt32 || |
| 749 (in & kRepMask) == kRepWord32) { | 751 (in & kRepMask) == kRepWord32) { |
| 750 // Just change representation if necessary. | 752 // Just change representation if necessary. |
| 751 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32); | 753 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32); |
| 752 if (lower()) DeferReplacement(node, node->InputAt(0)); | 754 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 753 } else { | 755 } else { |
| 754 // Require the input in float64 format and perform truncation. | 756 // Require the input in float64 format and perform truncation. |
| 755 // TODO(turbofan): avoid a truncation with a smi check. | 757 // TODO(turbofan): avoid a truncation with a smi check. |
| 756 VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32); | 758 VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32); |
| 757 if (lower()) { | 759 if (lower()) { |
| 758 node->set_op(lowering->machine()->TruncateFloat64ToInt32( | 760 NodeProperties::ChangeOp( |
| 759 TruncationMode::kJavaScript)); | 761 node, lowering->machine()->TruncateFloat64ToInt32( |
| 762 TruncationMode::kJavaScript)); |
| 760 } | 763 } |
| 761 } | 764 } |
| 762 break; | 765 break; |
| 763 } | 766 } |
| 764 case IrOpcode::kNumberToUint32: { | 767 case IrOpcode::kNumberToUint32: { |
| 765 MachineTypeUnion use_rep = use & kRepMask; | 768 MachineTypeUnion use_rep = use & kRepMask; |
| 766 Node* input = node->InputAt(0); | 769 Node* input = node->InputAt(0); |
| 767 Type* in_upper = NodeProperties::GetType(input); | 770 Type* in_upper = NodeProperties::GetType(input); |
| 768 MachineTypeUnion in = GetInfo(input)->output; | 771 MachineTypeUnion in = GetInfo(input)->output; |
| 769 if (in_upper->Is(Type::Unsigned32())) { | 772 if (in_upper->Is(Type::Unsigned32())) { |
| 770 // If the input has type uint32, pass through representation. | 773 // If the input has type uint32, pass through representation. |
| 771 VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep); | 774 VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep); |
| 772 if (lower()) DeferReplacement(node, node->InputAt(0)); | 775 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 773 } else if ((in & kTypeMask) == kTypeInt32 || | 776 } else if ((in & kTypeMask) == kTypeInt32 || |
| 774 in_upper->Is(Type::Signed32())) { | 777 in_upper->Is(Type::Signed32())) { |
| 775 // Just change representation if necessary. | 778 // Just change representation if necessary. |
| 776 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeUint32 | kRepWord32); | 779 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeUint32 | kRepWord32); |
| 777 if (lower()) DeferReplacement(node, node->InputAt(0)); | 780 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 778 } else if ((in & kTypeMask) == kTypeUint32 || | 781 } else if ((in & kTypeMask) == kTypeUint32 || |
| 779 (in & kRepMask) == kRepWord32) { | 782 (in & kRepMask) == kRepWord32) { |
| 780 // Just change representation if necessary. | 783 // Just change representation if necessary. |
| 781 VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32); | 784 VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32); |
| 782 if (lower()) DeferReplacement(node, node->InputAt(0)); | 785 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 783 } else { | 786 } else { |
| 784 // Require the input in float64 format and perform truncation. | 787 // Require the input in float64 format and perform truncation. |
| 785 // TODO(turbofan): avoid a truncation with a smi check. | 788 // TODO(turbofan): avoid a truncation with a smi check. |
| 786 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32); | 789 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32); |
| 787 if (lower()) { | 790 if (lower()) { |
| 788 node->set_op(lowering->machine()->TruncateFloat64ToInt32( | 791 NodeProperties::ChangeOp( |
| 789 TruncationMode::kJavaScript)); | 792 node, lowering->machine()->TruncateFloat64ToInt32( |
| 793 TruncationMode::kJavaScript)); |
| 790 } | 794 } |
| 791 } | 795 } |
| 792 break; | 796 break; |
| 793 } | 797 } |
| 794 case IrOpcode::kPlainPrimitiveToNumber: { | 798 case IrOpcode::kPlainPrimitiveToNumber: { |
| 795 VisitUnop(node, kMachAnyTagged, kTypeNumber | kRepTagged); | 799 VisitUnop(node, kMachAnyTagged, kTypeNumber | kRepTagged); |
| 796 if (lower()) { | 800 if (lower()) { |
| 797 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) | 801 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) |
| 798 Operator::Properties properties = node->op()->properties(); | 802 Operator::Properties properties = node->op()->properties(); |
| 799 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); | 803 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); |
| 800 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 804 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
| 801 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 805 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 802 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, | 806 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, |
| 803 flags, properties); | 807 flags, properties); |
| 804 node->set_op(jsgraph_->common()->Call(desc)); | |
| 805 node->InsertInput(jsgraph_->zone(), 0, | 808 node->InsertInput(jsgraph_->zone(), 0, |
| 806 jsgraph_->HeapConstant(callable.code())); | 809 jsgraph_->HeapConstant(callable.code())); |
| 807 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); | 810 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); |
| 811 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); |
| 808 } | 812 } |
| 809 break; | 813 break; |
| 810 } | 814 } |
| 811 case IrOpcode::kReferenceEqual: { | 815 case IrOpcode::kReferenceEqual: { |
| 812 VisitBinop(node, kMachAnyTagged, kRepBit); | 816 VisitBinop(node, kMachAnyTagged, kRepBit); |
| 813 if (lower()) node->set_op(lowering->machine()->WordEqual()); | 817 if (lower()) { |
| 818 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
| 819 } |
| 814 break; | 820 break; |
| 815 } | 821 } |
| 816 case IrOpcode::kStringEqual: { | 822 case IrOpcode::kStringEqual: { |
| 817 VisitBinop(node, kMachAnyTagged, kRepBit); | 823 VisitBinop(node, kMachAnyTagged, kRepBit); |
| 818 if (lower()) lowering->DoStringEqual(node); | 824 if (lower()) lowering->DoStringEqual(node); |
| 819 break; | 825 break; |
| 820 } | 826 } |
| 821 case IrOpcode::kStringLessThan: { | 827 case IrOpcode::kStringLessThan: { |
| 822 VisitBinop(node, kMachAnyTagged, kRepBit); | 828 VisitBinop(node, kMachAnyTagged, kRepBit); |
| 823 if (lower()) lowering->DoStringLessThan(node); | 829 if (lower()) lowering->DoStringLessThan(node); |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 | 1209 |
| 1204 } // namespace | 1210 } // namespace |
| 1205 | 1211 |
| 1206 | 1212 |
| 1207 void SimplifiedLowering::DoAllocate(Node* node) { | 1213 void SimplifiedLowering::DoAllocate(Node* node) { |
| 1208 PretenureFlag pretenure = OpParameter<PretenureFlag>(node->op()); | 1214 PretenureFlag pretenure = OpParameter<PretenureFlag>(node->op()); |
| 1209 AllocationSpace space = pretenure == TENURED ? OLD_SPACE : NEW_SPACE; | 1215 AllocationSpace space = pretenure == TENURED ? OLD_SPACE : NEW_SPACE; |
| 1210 Runtime::FunctionId f = Runtime::kAllocateInTargetSpace; | 1216 Runtime::FunctionId f = Runtime::kAllocateInTargetSpace; |
| 1211 Operator::Properties props = node->op()->properties(); | 1217 Operator::Properties props = node->op()->properties(); |
| 1212 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(zone(), f, 2, props); | 1218 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(zone(), f, 2, props); |
| 1213 node->set_op(common()->Call(desc)); | |
| 1214 ExternalReference ref(f, jsgraph()->isolate()); | 1219 ExternalReference ref(f, jsgraph()->isolate()); |
| 1215 int32_t flags = AllocateTargetSpace::encode(space); | 1220 int32_t flags = AllocateTargetSpace::encode(space); |
| 1216 node->InsertInput(graph()->zone(), 0, jsgraph()->CEntryStubConstant(1)); | 1221 node->InsertInput(graph()->zone(), 0, jsgraph()->CEntryStubConstant(1)); |
| 1217 node->InsertInput(graph()->zone(), 2, jsgraph()->SmiConstant(flags)); | 1222 node->InsertInput(graph()->zone(), 2, jsgraph()->SmiConstant(flags)); |
| 1218 node->InsertInput(graph()->zone(), 3, jsgraph()->ExternalConstant(ref)); | 1223 node->InsertInput(graph()->zone(), 3, jsgraph()->ExternalConstant(ref)); |
| 1219 node->InsertInput(graph()->zone(), 4, jsgraph()->Int32Constant(2)); | 1224 node->InsertInput(graph()->zone(), 4, jsgraph()->Int32Constant(2)); |
| 1220 node->InsertInput(graph()->zone(), 5, jsgraph()->NoContextConstant()); | 1225 node->InsertInput(graph()->zone(), 5, jsgraph()->NoContextConstant()); |
| 1226 NodeProperties::ChangeOp(node, common()->Call(desc)); |
| 1221 } | 1227 } |
| 1222 | 1228 |
| 1223 | 1229 |
| 1224 void SimplifiedLowering::DoLoadField(Node* node) { | 1230 void SimplifiedLowering::DoLoadField(Node* node) { |
| 1225 const FieldAccess& access = FieldAccessOf(node->op()); | 1231 const FieldAccess& access = FieldAccessOf(node->op()); |
| 1226 node->set_op(machine()->Load(access.machine_type)); | |
| 1227 Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); | 1232 Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); |
| 1228 node->InsertInput(graph()->zone(), 1, offset); | 1233 node->InsertInput(graph()->zone(), 1, offset); |
| 1234 NodeProperties::ChangeOp(node, machine()->Load(access.machine_type)); |
| 1229 } | 1235 } |
| 1230 | 1236 |
| 1231 | 1237 |
| 1232 void SimplifiedLowering::DoStoreField(Node* node) { | 1238 void SimplifiedLowering::DoStoreField(Node* node) { |
| 1233 const FieldAccess& access = FieldAccessOf(node->op()); | 1239 const FieldAccess& access = FieldAccessOf(node->op()); |
| 1234 Type* type = NodeProperties::GetType(node->InputAt(1)); | 1240 Type* type = NodeProperties::GetType(node->InputAt(1)); |
| 1235 WriteBarrierKind kind = | 1241 WriteBarrierKind kind = |
| 1236 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, type); | 1242 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, type); |
| 1237 node->set_op( | |
| 1238 machine()->Store(StoreRepresentation(access.machine_type, kind))); | |
| 1239 Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); | 1243 Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); |
| 1240 node->InsertInput(graph()->zone(), 1, offset); | 1244 node->InsertInput(graph()->zone(), 1, offset); |
| 1245 NodeProperties::ChangeOp( |
| 1246 node, machine()->Store(StoreRepresentation(access.machine_type, kind))); |
| 1241 } | 1247 } |
| 1242 | 1248 |
| 1243 | 1249 |
| 1244 Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access, | 1250 Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access, |
| 1245 Node* const key) { | 1251 Node* const key) { |
| 1246 Node* index = key; | 1252 Node* index = key; |
| 1247 const int element_size_shift = ElementSizeLog2Of(access.machine_type); | 1253 const int element_size_shift = ElementSizeLog2Of(access.machine_type); |
| 1248 if (element_size_shift) { | 1254 if (element_size_shift) { |
| 1249 index = graph()->NewNode(machine()->Word32Shl(), index, | 1255 index = graph()->NewNode(machine()->Word32Shl(), index, |
| 1250 jsgraph()->Int32Constant(element_size_shift)); | 1256 jsgraph()->Int32Constant(element_size_shift)); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1304 vfalse = jsgraph()->Int32Constant(0); | 1310 vfalse = jsgraph()->Int32Constant(0); |
| 1305 } | 1311 } |
| 1306 | 1312 |
| 1307 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | 1313 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 1308 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); | 1314 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); |
| 1309 | 1315 |
| 1310 // Replace effect uses of {node} with the {ephi}. | 1316 // Replace effect uses of {node} with the {ephi}. |
| 1311 NodeProperties::ReplaceUses(node, node, ephi); | 1317 NodeProperties::ReplaceUses(node, node, ephi); |
| 1312 | 1318 |
| 1313 // Turn the {node} into a Phi. | 1319 // Turn the {node} into a Phi. |
| 1314 node->set_op(common()->Phi(output_type, 2)); | |
| 1315 node->ReplaceInput(0, vtrue); | 1320 node->ReplaceInput(0, vtrue); |
| 1316 node->ReplaceInput(1, vfalse); | 1321 node->ReplaceInput(1, vfalse); |
| 1317 node->ReplaceInput(2, merge); | 1322 node->ReplaceInput(2, merge); |
| 1318 node->TrimInputCount(3); | 1323 node->TrimInputCount(3); |
| 1324 NodeProperties::ChangeOp(node, common()->Phi(output_type, 2)); |
| 1319 } else { | 1325 } else { |
| 1320 node->set_op(machine()->CheckedLoad(type)); | 1326 NodeProperties::ChangeOp(node, machine()->CheckedLoad(type)); |
| 1321 } | 1327 } |
| 1322 } | 1328 } |
| 1323 | 1329 |
| 1324 | 1330 |
| 1325 void SimplifiedLowering::DoStoreBuffer(Node* node) { | 1331 void SimplifiedLowering::DoStoreBuffer(Node* node) { |
| 1326 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); | 1332 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); |
| 1327 MachineType const type = BufferAccessOf(node->op()).machine_type(); | 1333 MachineType const type = BufferAccessOf(node->op()).machine_type(); |
| 1328 node->set_op(machine()->CheckedStore(type)); | 1334 NodeProperties::ChangeOp(node, machine()->CheckedStore(type)); |
| 1329 } | 1335 } |
| 1330 | 1336 |
| 1331 | 1337 |
| 1332 void SimplifiedLowering::DoLoadElement(Node* node) { | 1338 void SimplifiedLowering::DoLoadElement(Node* node) { |
| 1333 const ElementAccess& access = ElementAccessOf(node->op()); | 1339 const ElementAccess& access = ElementAccessOf(node->op()); |
| 1334 node->set_op(machine()->Load(access.machine_type)); | |
| 1335 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); | 1340 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); |
| 1341 NodeProperties::ChangeOp(node, machine()->Load(access.machine_type)); |
| 1336 } | 1342 } |
| 1337 | 1343 |
| 1338 | 1344 |
| 1339 void SimplifiedLowering::DoStoreElement(Node* node) { | 1345 void SimplifiedLowering::DoStoreElement(Node* node) { |
| 1340 const ElementAccess& access = ElementAccessOf(node->op()); | 1346 const ElementAccess& access = ElementAccessOf(node->op()); |
| 1341 Type* type = NodeProperties::GetType(node->InputAt(2)); | 1347 Type* type = NodeProperties::GetType(node->InputAt(2)); |
| 1342 node->set_op(machine()->Store( | |
| 1343 StoreRepresentation(access.machine_type, | |
| 1344 ComputeWriteBarrierKind(access.base_is_tagged, | |
| 1345 access.machine_type, type)))); | |
| 1346 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); | 1348 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); |
| 1349 NodeProperties::ChangeOp( |
| 1350 node, machine()->Store(StoreRepresentation( |
| 1351 access.machine_type, |
| 1352 ComputeWriteBarrierKind(access.base_is_tagged, |
| 1353 access.machine_type, type)))); |
| 1347 } | 1354 } |
| 1348 | 1355 |
| 1349 | 1356 |
| 1350 Node* SimplifiedLowering::StringComparison(Node* node) { | 1357 Node* SimplifiedLowering::StringComparison(Node* node) { |
| 1351 Operator::Properties properties = node->op()->properties(); | 1358 Operator::Properties properties = node->op()->properties(); |
| 1352 Callable callable = CodeFactory::StringCompare(isolate()); | 1359 Callable callable = CodeFactory::StringCompare(isolate()); |
| 1353 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 1360 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
| 1354 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1361 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 1355 isolate(), zone(), callable.descriptor(), 0, flags, properties); | 1362 isolate(), zone(), callable.descriptor(), 0, flags, properties); |
| 1356 return graph()->NewNode( | 1363 return graph()->NewNode( |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1603 | 1610 |
| 1604 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | 1611 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| 1605 Node* false0 = zero; | 1612 Node* false0 = zero; |
| 1606 | 1613 |
| 1607 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0); | 1614 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0); |
| 1608 return graph()->NewNode(phi_op, true0, false0, merge0); | 1615 return graph()->NewNode(phi_op, true0, false0, merge0); |
| 1609 } | 1616 } |
| 1610 | 1617 |
| 1611 | 1618 |
| 1612 void SimplifiedLowering::DoShift(Node* node, Operator const* op) { | 1619 void SimplifiedLowering::DoShift(Node* node, Operator const* op) { |
| 1613 node->set_op(op); | |
| 1614 Node* const rhs = NodeProperties::GetValueInput(node, 1); | 1620 Node* const rhs = NodeProperties::GetValueInput(node, 1); |
| 1615 Type* const rhs_type = NodeProperties::GetType(rhs); | 1621 Type* const rhs_type = NodeProperties::GetType(rhs); |
| 1616 if (!rhs_type->Is(zero_thirtyone_range_)) { | 1622 if (!rhs_type->Is(zero_thirtyone_range_)) { |
| 1617 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, | 1623 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, |
| 1618 jsgraph()->Int32Constant(0x1f))); | 1624 jsgraph()->Int32Constant(0x1f))); |
| 1619 } | 1625 } |
| 1626 NodeProperties::ChangeOp(node, op); |
| 1620 } | 1627 } |
| 1621 | 1628 |
| 1622 | 1629 |
| 1623 void SimplifiedLowering::DoStringEqual(Node* node) { | 1630 void SimplifiedLowering::DoStringEqual(Node* node) { |
| 1624 node->set_op(machine()->WordEqual()); | |
| 1625 node->ReplaceInput(0, StringComparison(node)); | 1631 node->ReplaceInput(0, StringComparison(node)); |
| 1626 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1632 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1633 NodeProperties::ChangeOp(node, machine()->WordEqual()); |
| 1627 } | 1634 } |
| 1628 | 1635 |
| 1629 | 1636 |
| 1630 void SimplifiedLowering::DoStringLessThan(Node* node) { | 1637 void SimplifiedLowering::DoStringLessThan(Node* node) { |
| 1631 node->set_op(machine()->IntLessThan()); | |
| 1632 node->ReplaceInput(0, StringComparison(node)); | 1638 node->ReplaceInput(0, StringComparison(node)); |
| 1633 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1639 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1640 NodeProperties::ChangeOp(node, machine()->IntLessThan()); |
| 1634 } | 1641 } |
| 1635 | 1642 |
| 1636 | 1643 |
| 1637 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1644 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
| 1638 node->set_op(machine()->IntLessThanOrEqual()); | |
| 1639 node->ReplaceInput(0, StringComparison(node)); | 1645 node->ReplaceInput(0, StringComparison(node)); |
| 1640 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1646 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1647 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); |
| 1641 } | 1648 } |
| 1642 | 1649 |
| 1643 } // namespace compiler | 1650 } // namespace compiler |
| 1644 } // namespace internal | 1651 } // namespace internal |
| 1645 } // namespace v8 | 1652 } // namespace v8 |
| OLD | NEW |