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 |