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 #ifndef V8_COMPILER_INSTRUCTION_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_H_ |
6 #define V8_COMPILER_INSTRUCTION_H_ | 6 #define V8_COMPILER_INSTRUCTION_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 #include <map> | 10 #include <map> |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 } | 110 } |
111 | 111 |
112 bool EqualsCanonicalized(const InstructionOperand& that) const { | 112 bool EqualsCanonicalized(const InstructionOperand& that) const { |
113 return this->GetCanonicalizedValue() == that.GetCanonicalizedValue(); | 113 return this->GetCanonicalizedValue() == that.GetCanonicalizedValue(); |
114 } | 114 } |
115 | 115 |
116 bool CompareCanonicalized(const InstructionOperand& that) const { | 116 bool CompareCanonicalized(const InstructionOperand& that) const { |
117 return this->GetCanonicalizedValue() < that.GetCanonicalizedValue(); | 117 return this->GetCanonicalizedValue() < that.GetCanonicalizedValue(); |
118 } | 118 } |
119 | 119 |
120 bool InterferesWith(const InstructionOperand& that) const; | 120 bool InterferesWith(const InstructionOperand& other) const; |
121 | 121 |
122 // APIs to aid debugging. For general-stream APIs, use operator<< | 122 // APIs to aid debugging. For general-stream APIs, use operator<< |
123 void Print(const RegisterConfiguration* config) const; | 123 void Print(const RegisterConfiguration* config) const; |
124 void Print() const; | 124 void Print() const; |
125 | 125 |
126 protected: | 126 protected: |
127 explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {} | 127 explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {} |
128 | 128 |
129 inline uint64_t GetCanonicalizedValue() const; | 129 inline uint64_t GetCanonicalizedValue() const; |
130 | 130 |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 LocationOperand::cast(this)->location_kind() == | 632 LocationOperand::cast(this)->location_kind() == |
633 LocationOperand::STACK_SLOT && | 633 LocationOperand::STACK_SLOT && |
634 LocationOperand::cast(this)->representation() == | 634 LocationOperand::cast(this)->representation() == |
635 MachineRepresentation::kSimd128; | 635 MachineRepresentation::kSimd128; |
636 } | 636 } |
637 | 637 |
638 uint64_t InstructionOperand::GetCanonicalizedValue() const { | 638 uint64_t InstructionOperand::GetCanonicalizedValue() const { |
639 if (IsAnyLocationOperand()) { | 639 if (IsAnyLocationOperand()) { |
640 MachineRepresentation canonical = MachineRepresentation::kNone; | 640 MachineRepresentation canonical = MachineRepresentation::kNone; |
641 if (IsFPRegister()) { | 641 if (IsFPRegister()) { |
642 // We treat all FP register operands the same for simple aliasing. | 642 if (kSimpleFPAliasing) { |
643 canonical = MachineRepresentation::kFloat64; | 643 // We treat all FP register operands the same for simple aliasing. |
| 644 canonical = MachineRepresentation::kFloat64; |
| 645 } else { |
| 646 // We need to distinguish FP register operands of different reps when |
| 647 // aliasing is not simple (e.g. ARM). |
| 648 canonical = LocationOperand::cast(this)->representation(); |
| 649 } |
644 } | 650 } |
645 return InstructionOperand::KindField::update( | 651 return InstructionOperand::KindField::update( |
646 LocationOperand::RepresentationField::update(this->value_, canonical), | 652 LocationOperand::RepresentationField::update(this->value_, canonical), |
647 LocationOperand::EXPLICIT); | 653 LocationOperand::EXPLICIT); |
648 } | 654 } |
649 return this->value_; | 655 return this->value_; |
650 } | 656 } |
651 | 657 |
652 // Required for maps that don't care about machine type. | 658 // Required for maps that don't care about machine type. |
653 struct CompareOperandModuloType { | 659 struct CompareOperandModuloType { |
(...skipping 22 matching lines...) Expand all Loading... |
676 destination_ = operand; | 682 destination_ = operand; |
677 } | 683 } |
678 | 684 |
679 // The gap resolver marks moves as "in-progress" by clearing the | 685 // The gap resolver marks moves as "in-progress" by clearing the |
680 // destination (but not the source). | 686 // destination (but not the source). |
681 bool IsPending() const { | 687 bool IsPending() const { |
682 return destination_.IsInvalid() && !source_.IsInvalid(); | 688 return destination_.IsInvalid() && !source_.IsInvalid(); |
683 } | 689 } |
684 void SetPending() { destination_ = InstructionOperand(); } | 690 void SetPending() { destination_ = InstructionOperand(); } |
685 | 691 |
686 // True if this move is a move into the given destination operand. | |
687 bool Blocks(const InstructionOperand& destination) const { | |
688 return !IsEliminated() && source().InterferesWith(destination); | |
689 } | |
690 | |
691 // A move is redundant if it's been eliminated or if its source and | 692 // A move is redundant if it's been eliminated or if its source and |
692 // destination are the same. | 693 // destination are the same. |
693 bool IsRedundant() const { | 694 bool IsRedundant() const { |
694 DCHECK_IMPLIES(!destination_.IsInvalid(), !destination_.IsConstant()); | 695 DCHECK_IMPLIES(!destination_.IsInvalid(), !destination_.IsConstant()); |
695 return IsEliminated() || source_.EqualsCanonicalized(destination_); | 696 return IsEliminated() || source_.EqualsCanonicalized(destination_); |
696 } | 697 } |
697 | 698 |
698 // We clear both operands to indicate move that's been eliminated. | 699 // We clear both operands to indicate move that's been eliminated. |
699 void Eliminate() { source_ = destination_ = InstructionOperand(); } | 700 void Eliminate() { source_ = destination_ = InstructionOperand(); } |
700 bool IsEliminated() const { | 701 bool IsEliminated() const { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 const InstructionOperand& to, | 740 const InstructionOperand& to, |
740 Zone* operand_allocation_zone) { | 741 Zone* operand_allocation_zone) { |
741 MoveOperands* move = new (operand_allocation_zone) MoveOperands(from, to); | 742 MoveOperands* move = new (operand_allocation_zone) MoveOperands(from, to); |
742 push_back(move); | 743 push_back(move); |
743 return move; | 744 return move; |
744 } | 745 } |
745 | 746 |
746 bool IsRedundant() const; | 747 bool IsRedundant() const; |
747 | 748 |
748 // Prepare this ParallelMove to insert move as if it happened in a subsequent | 749 // Prepare this ParallelMove to insert move as if it happened in a subsequent |
749 // ParallelMove. move->source() may be changed. The MoveOperand returned | 750 // ParallelMove. move->source() may be changed. Any MoveOperands added to |
750 // must be Eliminated. | 751 // to_eliminate must be Eliminated. |
751 MoveOperands* PrepareInsertAfter(MoveOperands* move) const; | 752 void PrepareInsertAfter(MoveOperands* move, |
| 753 ZoneVector<MoveOperands*>* to_eliminate) const; |
752 | 754 |
753 private: | 755 private: |
754 DISALLOW_COPY_AND_ASSIGN(ParallelMove); | 756 DISALLOW_COPY_AND_ASSIGN(ParallelMove); |
755 }; | 757 }; |
756 | 758 |
757 | 759 |
758 struct PrintableParallelMove { | 760 struct PrintableParallelMove { |
759 const RegisterConfiguration* register_configuration_; | 761 const RegisterConfiguration* register_configuration_; |
760 const ParallelMove* parallel_move_; | 762 const ParallelMove* parallel_move_; |
761 }; | 763 }; |
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1532 | 1534 |
1533 | 1535 |
1534 std::ostream& operator<<(std::ostream& os, | 1536 std::ostream& operator<<(std::ostream& os, |
1535 const PrintableInstructionSequence& code); | 1537 const PrintableInstructionSequence& code); |
1536 | 1538 |
1537 } // namespace compiler | 1539 } // namespace compiler |
1538 } // namespace internal | 1540 } // namespace internal |
1539 } // namespace v8 | 1541 } // namespace v8 |
1540 | 1542 |
1541 #endif // V8_COMPILER_INSTRUCTION_H_ | 1543 #endif // V8_COMPILER_INSTRUCTION_H_ |
OLD | NEW |