| 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 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 bool getIsArg() const { return IsArgument; } | 689 bool getIsArg() const { return IsArgument; } |
| 690 virtual void setIsArg(bool Val = true) { IsArgument = Val; } | 690 virtual void setIsArg(bool Val = true) { IsArgument = Val; } |
| 691 bool getIsImplicitArg() const { return IsImplicitArgument; } | 691 bool getIsImplicitArg() const { return IsImplicitArgument; } |
| 692 void setIsImplicitArg(bool Val = true) { IsImplicitArgument = Val; } | 692 void setIsImplicitArg(bool Val = true) { IsImplicitArgument = Val; } |
| 693 | 693 |
| 694 void setIgnoreLiveness() { IgnoreLiveness = true; } | 694 void setIgnoreLiveness() { IgnoreLiveness = true; } |
| 695 bool getIgnoreLiveness() const { | 695 bool getIgnoreLiveness() const { |
| 696 return IgnoreLiveness || IsRematerializable; | 696 return IgnoreLiveness || IsRematerializable; |
| 697 } | 697 } |
| 698 | 698 |
| 699 /// Returns true if the variable either has a definite stack offset, or has |
| 700 /// the UndeterminedStackOffset such that it is guaranteed to have a definite |
| 701 /// stack offset at emission time. |
| 699 bool hasStackOffset() const { return StackOffset != InvalidStackOffset; } | 702 bool hasStackOffset() const { return StackOffset != InvalidStackOffset; } |
| 703 /// Returns true if the variable has a stack offset that is known at this |
| 704 /// time. |
| 705 bool hasKnownStackOffset() const { |
| 706 return StackOffset != InvalidStackOffset && |
| 707 StackOffset != UndeterminedStackOffset; |
| 708 } |
| 700 int32_t getStackOffset() const { | 709 int32_t getStackOffset() const { |
| 701 assert(hasStackOffset()); | 710 assert(hasKnownStackOffset()); |
| 702 return StackOffset; | 711 return StackOffset; |
| 703 } | 712 } |
| 704 void setStackOffset(int32_t Offset) { StackOffset = Offset; } | 713 void setStackOffset(int32_t Offset) { StackOffset = Offset; } |
| 714 /// Set a "placeholder" stack offset before its actual offset has been |
| 715 /// determined. |
| 716 void setHasStackOffset() { |
| 717 if (!hasStackOffset()) |
| 718 StackOffset = UndeterminedStackOffset; |
| 719 } |
| 705 /// Returns the variable's stack offset in symbolic form, to improve | 720 /// Returns the variable's stack offset in symbolic form, to improve |
| 706 /// readability in DecorateAsm mode. | 721 /// readability in DecorateAsm mode. |
| 707 std::string getSymbolicStackOffset() const { | 722 std::string getSymbolicStackOffset() const { |
| 708 if (!BuildDefs::dump()) | 723 if (!BuildDefs::dump()) |
| 709 return ""; | 724 return ""; |
| 710 return ".L$lv$" + getName(); | 725 return ".L$lv$" + getName(); |
| 711 } | 726 } |
| 712 | 727 |
| 713 bool hasReg() const { return getRegNum().hasValue(); } | 728 bool hasReg() const { return getRegNum().hasValue(); } |
| 714 RegNumT getRegNum() const { return RegNum; } | 729 RegNumT getRegNum() const { return RegNum; } |
| 715 void setRegNum(RegNumT NewRegNum) { | 730 void setRegNum(RegNumT NewRegNum) { |
| 716 // Regnum shouldn't be set more than once. | 731 // Regnum shouldn't be set more than once. |
| 717 assert(!hasReg() || RegNum == NewRegNum); | 732 assert(!hasReg() || RegNum == NewRegNum); |
| 718 RegNum = NewRegNum; | 733 RegNum = NewRegNum; |
| 719 } | 734 } |
| 720 bool hasRegTmp() const { return getRegNumTmp().hasValue(); } | 735 bool hasRegTmp() const { return getRegNumTmp().hasValue(); } |
| 721 RegNumT getRegNumTmp() const { return RegNumTmp; } | 736 RegNumT getRegNumTmp() const { return RegNumTmp; } |
| 722 void setRegNumTmp(RegNumT NewRegNum) { RegNumTmp = NewRegNum; } | 737 void setRegNumTmp(RegNumT NewRegNum) { RegNumTmp = NewRegNum; } |
| 723 | 738 |
| 724 RegWeight getWeight(const Cfg *Func) const; | 739 RegWeight getWeight(const Cfg *Func) const; |
| 725 | 740 |
| 726 void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; } | 741 void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; } |
| 727 bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; } | 742 bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; } |
| 728 void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; } | 743 void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; } |
| 729 bool mustNotHaveReg() const { | 744 bool mustNotHaveReg() const { |
| 730 return RegRequirement == RR_MustNotHaveRegister; | 745 return RegRequirement == RR_MustNotHaveRegister; |
| 731 } | 746 } |
| 747 bool mayHaveReg() const { return RegRequirement == RR_MayHaveRegister; } |
| 732 void setRematerializable(RegNumT NewRegNum, int32_t NewOffset) { | 748 void setRematerializable(RegNumT NewRegNum, int32_t NewOffset) { |
| 733 IsRematerializable = true; | 749 IsRematerializable = true; |
| 734 setRegNum(NewRegNum); | 750 setRegNum(NewRegNum); |
| 735 setStackOffset(NewOffset); | 751 setStackOffset(NewOffset); |
| 736 setMustHaveReg(); | 752 setMustHaveReg(); |
| 737 } | 753 } |
| 738 bool isRematerializable() const { return IsRematerializable; } | 754 bool isRematerializable() const { return IsRematerializable; } |
| 739 | 755 |
| 740 void setRegClass(uint8_t RC) { RegisterClass = static_cast<RegClass>(RC); } | 756 void setRegClass(uint8_t RC) { RegisterClass = static_cast<RegClass>(RC); } |
| 741 RegClass getRegClass() const { return RegisterClass; } | 757 RegClass getRegClass() const { return RegisterClass; } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 Variable *getLinkedTo() const { return LinkedTo; } | 798 Variable *getLinkedTo() const { return LinkedTo; } |
| 783 /// Follow the LinkedTo chain up to the furthest ancestor. | 799 /// Follow the LinkedTo chain up to the furthest ancestor. |
| 784 Variable *getLinkedToRoot() const { | 800 Variable *getLinkedToRoot() const { |
| 785 Variable *Root = LinkedTo; | 801 Variable *Root = LinkedTo; |
| 786 if (Root == nullptr) | 802 if (Root == nullptr) |
| 787 return nullptr; | 803 return nullptr; |
| 788 while (Root->LinkedTo != nullptr) | 804 while (Root->LinkedTo != nullptr) |
| 789 Root = Root->LinkedTo; | 805 Root = Root->LinkedTo; |
| 790 return Root; | 806 return Root; |
| 791 } | 807 } |
| 808 /// Follow the LinkedTo chain up to the furthest stack-allocated ancestor. |
| 809 /// This is only certain to be accurate after register allocation and stack |
| 810 /// slot assignment have completed. |
| 811 Variable *getLinkedToStackRoot() const { |
| 812 Variable *FurthestStackVar = nullptr; |
| 813 for (Variable *Root = LinkedTo; Root != nullptr; Root = Root->LinkedTo) { |
| 814 if (!Root->hasReg() && Root->hasStackOffset()) { |
| 815 FurthestStackVar = Root; |
| 816 } |
| 817 } |
| 818 return FurthestStackVar; |
| 819 } |
| 792 | 820 |
| 793 static bool classof(const Operand *Operand) { | 821 static bool classof(const Operand *Operand) { |
| 794 OperandKind Kind = Operand->getKind(); | 822 OperandKind Kind = Operand->getKind(); |
| 795 return Kind >= kVariable && Kind <= kVariable_Max; | 823 return Kind >= kVariable && Kind <= kVariable_Max; |
| 796 } | 824 } |
| 797 | 825 |
| 798 SizeT hashValue() const override { return std::hash<SizeT>()(getIndex()); } | 826 SizeT hashValue() const override { return std::hash<SizeT>()(getIndex()); } |
| 799 | 827 |
| 800 protected: | 828 protected: |
| 801 Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index) | 829 Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 818 bool IgnoreLiveness = false; | 846 bool IgnoreLiveness = false; |
| 819 // If IsRematerializable, RegNum keeps track of which register (stack or frame | 847 // If IsRematerializable, RegNum keeps track of which register (stack or frame |
| 820 // pointer), and StackOffset is the known offset from that register. | 848 // pointer), and StackOffset is the known offset from that register. |
| 821 bool IsRematerializable = false; | 849 bool IsRematerializable = false; |
| 822 RegRequirement RegRequirement = RR_MayHaveRegister; | 850 RegRequirement RegRequirement = RR_MayHaveRegister; |
| 823 RegClass RegisterClass; | 851 RegClass RegisterClass; |
| 824 /// RegNum is the allocated register, (as long as RegNum.hasValue() is true). | 852 /// RegNum is the allocated register, (as long as RegNum.hasValue() is true). |
| 825 RegNumT RegNum; | 853 RegNumT RegNum; |
| 826 /// RegNumTmp is the tentative assignment during register allocation. | 854 /// RegNumTmp is the tentative assignment during register allocation. |
| 827 RegNumT RegNumTmp; | 855 RegNumT RegNumTmp; |
| 828 static constexpr int32_t InvalidStackOffset = -1; | 856 static constexpr int32_t InvalidStackOffset = |
| 857 std::numeric_limits<int32_t>::min(); |
| 858 static constexpr int32_t UndeterminedStackOffset = |
| 859 1 + std::numeric_limits<int32_t>::min(); |
| 829 /// StackOffset is the canonical location on stack (only if | 860 /// StackOffset is the canonical location on stack (only if |
| 830 /// RegNum.hasNoValue() || IsArgument). | 861 /// RegNum.hasNoValue() || IsArgument). |
| 831 int32_t StackOffset = InvalidStackOffset; | 862 int32_t StackOffset = InvalidStackOffset; |
| 832 LiveRange Live; | 863 LiveRange Live; |
| 833 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this. | 864 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this. |
| 834 Variable *VarsReal[1]; | 865 Variable *VarsReal[1]; |
| 835 /// This Variable may be "linked" to another Variable, such that if neither | 866 /// This Variable may be "linked" to another Variable, such that if neither |
| 836 /// Variable gets a register, they are guaranteed to share a stack location. | 867 /// Variable gets a register, they are guaranteed to share a stack location. |
| 837 Variable *LinkedTo = nullptr; | 868 Variable *LinkedTo = nullptr; |
| 838 }; | 869 }; |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1044 return Operand->getKind() == kVariableBoolean; | 1075 return Operand->getKind() == kVariableBoolean; |
| 1045 } | 1076 } |
| 1046 | 1077 |
| 1047 private: | 1078 private: |
| 1048 Variable *BoolSource = nullptr; | 1079 Variable *BoolSource = nullptr; |
| 1049 }; | 1080 }; |
| 1050 | 1081 |
| 1051 } // end of namespace Ice | 1082 } // end of namespace Ice |
| 1052 | 1083 |
| 1053 #endif // SUBZERO_SRC_ICEOPERAND_H | 1084 #endif // SUBZERO_SRC_ICEOPERAND_H |
| OLD | NEW |