OLD | NEW |
1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===// | 1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 /// linear-scan code enables this by calling trim() on the ranges of interest | 649 /// linear-scan code enables this by calling trim() on the ranges of interest |
650 /// as Cur advances. Note that linear-scan also has to initialize TrimmedBegin | 650 /// as Cur advances. Note that linear-scan also has to initialize TrimmedBegin |
651 /// at the beginning by calling untrim(). | 651 /// at the beginning by calling untrim(). |
652 RangeType::const_iterator TrimmedBegin; | 652 RangeType::const_iterator TrimmedBegin; |
653 }; | 653 }; |
654 | 654 |
655 Ostream &operator<<(Ostream &Str, const LiveRange &L); | 655 Ostream &operator<<(Ostream &Str, const LiveRange &L); |
656 | 656 |
657 /// Variable represents an operand that is register-allocated or | 657 /// Variable represents an operand that is register-allocated or |
658 /// stack-allocated. If it is register-allocated, it will ultimately have a | 658 /// stack-allocated. If it is register-allocated, it will ultimately have a |
659 /// non-negative RegNum field. | 659 /// valid RegNum field. |
660 class Variable : public Operand { | 660 class Variable : public Operand { |
661 Variable() = delete; | 661 Variable() = delete; |
662 Variable(const Variable &) = delete; | 662 Variable(const Variable &) = delete; |
663 Variable &operator=(const Variable &) = delete; | 663 Variable &operator=(const Variable &) = delete; |
664 | 664 |
665 enum RegRequirement : uint8_t { | 665 enum RegRequirement : uint8_t { |
666 RR_MayHaveRegister, | 666 RR_MayHaveRegister, |
667 RR_MustHaveRegister, | 667 RR_MustHaveRegister, |
668 RR_MustNotHaveRegister, | 668 RR_MustNotHaveRegister, |
669 }; | 669 }; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 /// instead of copying the existing assignment. | 766 /// instead of copying the existing assignment. |
767 const Variable *asType(const Cfg *Func, Type Ty, RegNumT NewRegNum) const; | 767 const Variable *asType(const Cfg *Func, Type Ty, RegNumT NewRegNum) const; |
768 | 768 |
769 void emit(const Cfg *Func) const override; | 769 void emit(const Cfg *Func) const override; |
770 using Operand::dump; | 770 using Operand::dump; |
771 void dump(const Cfg *Func, Ostream &Str) const override; | 771 void dump(const Cfg *Func, Ostream &Str) const override; |
772 | 772 |
773 /// Return reg num of base register, if different from stack/frame register. | 773 /// Return reg num of base register, if different from stack/frame register. |
774 virtual RegNumT getBaseRegNum() const { return RegNumT(); } | 774 virtual RegNumT getBaseRegNum() const { return RegNumT(); } |
775 | 775 |
| 776 void setLinkedTo(const Variable *Var) { |
| 777 // If B is linked to A, and we now want to link C to B, we instead link C to |
| 778 // A so that we have one root (A) and all leaves (B, C) link directly to the |
| 779 // root. |
| 780 if (Var->getLinkedTo() != nullptr) { |
| 781 Var = Var->LinkedTo; |
| 782 assert(Var->LinkedTo == nullptr); |
| 783 } |
| 784 LinkedTo = Var; |
| 785 } |
| 786 const Variable *getLinkedTo() const { |
| 787 // Make sure a leaf links directly to the root. |
| 788 if (LinkedTo != nullptr) |
| 789 assert(LinkedTo->LinkedTo == nullptr); |
| 790 return LinkedTo; |
| 791 } |
| 792 |
776 static bool classof(const Operand *Operand) { | 793 static bool classof(const Operand *Operand) { |
777 OperandKind Kind = Operand->getKind(); | 794 OperandKind Kind = Operand->getKind(); |
778 return Kind >= kVariable && Kind <= kVariable_Max; | 795 return Kind >= kVariable && Kind <= kVariable_Max; |
779 } | 796 } |
780 | 797 |
781 SizeT hashValue() const override { return std::hash<SizeT>()(getIndex()); } | 798 SizeT hashValue() const override { return std::hash<SizeT>()(getIndex()); } |
782 | 799 |
783 protected: | 800 protected: |
784 Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index) | 801 Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index) |
785 : Operand(K, Ty), Number(Index), | 802 : Operand(K, Ty), Number(Index), |
(...skipping 21 matching lines...) Expand all Loading... |
807 /// RegNum is the allocated register, (as long as RegNum.hasValue() is true). | 824 /// RegNum is the allocated register, (as long as RegNum.hasValue() is true). |
808 RegNumT RegNum; | 825 RegNumT RegNum; |
809 /// RegNumTmp is the tentative assignment during register allocation. | 826 /// RegNumTmp is the tentative assignment during register allocation. |
810 RegNumT RegNumTmp; | 827 RegNumT RegNumTmp; |
811 /// StackOffset is the canonical location on stack (only if | 828 /// StackOffset is the canonical location on stack (only if |
812 /// RegNum.hasNoValue() || IsArgument). | 829 /// RegNum.hasNoValue() || IsArgument). |
813 int32_t StackOffset = 0; | 830 int32_t StackOffset = 0; |
814 LiveRange Live; | 831 LiveRange Live; |
815 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this. | 832 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this. |
816 Variable *VarsReal[1]; | 833 Variable *VarsReal[1]; |
| 834 /// This Variable may be "linked" to another Variable, such that if neither |
| 835 /// Variable gets a register, they are guaranteed to share a stack location. |
| 836 const Variable *LinkedTo = nullptr; |
817 }; | 837 }; |
818 | 838 |
819 // Variable64On32 represents a 64-bit variable on a 32-bit architecture. In | 839 // Variable64On32 represents a 64-bit variable on a 32-bit architecture. In |
820 // this situation the variable must be split into a low and a high word. | 840 // this situation the variable must be split into a low and a high word. |
821 class Variable64On32 : public Variable { | 841 class Variable64On32 : public Variable { |
822 Variable64On32() = delete; | 842 Variable64On32() = delete; |
823 Variable64On32(const Variable64On32 &) = delete; | 843 Variable64On32(const Variable64On32 &) = delete; |
824 Variable64On32 &operator=(const Variable64On32 &) = delete; | 844 Variable64On32 &operator=(const Variable64On32 &) = delete; |
825 | 845 |
826 public: | 846 public: |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1023 return Operand->getKind() == kVariableBoolean; | 1043 return Operand->getKind() == kVariableBoolean; |
1024 } | 1044 } |
1025 | 1045 |
1026 private: | 1046 private: |
1027 Variable *BoolSource = nullptr; | 1047 Variable *BoolSource = nullptr; |
1028 }; | 1048 }; |
1029 | 1049 |
1030 } // end of namespace Ice | 1050 } // end of namespace Ice |
1031 | 1051 |
1032 #endif // SUBZERO_SRC_ICEOPERAND_H | 1052 #endif // SUBZERO_SRC_ICEOPERAND_H |
OLD | NEW |