diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
commit | 044eb2f6afba375a914ac9d8024f8f5142bb912e (patch) | |
tree | 1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /include/llvm/CodeGen/MachineOperand.h | |
parent | eb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff) |
Notes
Diffstat (limited to 'include/llvm/CodeGen/MachineOperand.h')
-rw-r--r-- | include/llvm/CodeGen/MachineOperand.h | 186 |
1 files changed, 143 insertions, 43 deletions
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 2560399bcf54..ccf0917ed085 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -14,8 +14,10 @@ #ifndef LLVM_CODEGEN_MACHINEOPERAND_H #define LLVM_CODEGEN_MACHINEOPERAND_H +#include "llvm/ADT/DenseMap.h" #include "llvm/IR/Intrinsics.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/LowLevelTypeImpl.h" #include <cassert> namespace llvm { @@ -65,6 +67,7 @@ public: MO_CFIIndex, ///< MCCFIInstruction index. MO_IntrinsicID, ///< Intrinsic ID for ISel MO_Predicate, ///< Generic predicate for ISel + MO_Last = MO_Predicate, }; private: @@ -83,24 +86,30 @@ private: /// before MachineInstr::tieOperands(). unsigned char TiedTo : 4; - /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register - /// operands. - /// IsDef - True if this is a def, false if this is a use of the register. + /// This is only valid on register operands. /// bool IsDef : 1; /// IsImp - True if this is an implicit def or use, false if it is explicit. + /// This is only valid on register opderands. /// bool IsImp : 1; - /// IsKill - True if this instruction is the last use of the register on this - /// path through the function. This is only valid on uses of registers. - bool IsKill : 1; - - /// IsDead - True if this register is never used by a subsequent instruction. - /// This is only valid on definitions of registers. - bool IsDead : 1; + /// IsDeadOrKill + /// For uses: IsKill - True if this instruction is the last use of the + /// register on this path through the function. + /// For defs: IsDead - True if this register is never used by a subsequent + /// instruction. + /// This is only valid on register operands. + bool IsDeadOrKill : 1; + + /// IsRenamable - True if this register may be renamed, i.e. it does not + /// generate a value that is somehow read in a way that is not represented by + /// the Machine IR (e.g. to meet an ABI or ISA requirement). This is only + /// valid on physical register operands. Virtual registers are assumed to + /// always be renamable regardless of the value of this field. + bool IsRenamable : 1; /// IsUndef - True if this register operand reads an "undef" value, i.e. the /// read value doesn't matter. This flag can be set on both use and def @@ -114,9 +123,9 @@ private: /// the same register. In that case, the instruction may depend on those /// operands reading the same dont-care value. For example: /// - /// %vreg1<def> = XOR %vreg2<undef>, %vreg2<undef> + /// %1 = XOR undef %2, undef %2 /// - /// Any register can be used for %vreg2, and its value doesn't matter, but + /// Any register can be used for %2, and its value doesn't matter, but /// the two operands must be the same register. /// bool IsUndef : 1; @@ -224,11 +233,50 @@ public: /// void clearParent() { ParentMI = nullptr; } + /// Print a subreg index operand. + /// MO_Immediate operands can also be subreg idices. If it's the case, the + /// subreg index name will be printed. MachineInstr::isOperandSubregIdx can be + /// called to check this. + static void printSubregIdx(raw_ostream &OS, uint64_t Index, + const TargetRegisterInfo *TRI); + + /// Print operand target flags. + static void printTargetFlags(raw_ostream& OS, const MachineOperand &Op); + + /// Print a MCSymbol as an operand. + static void printSymbol(raw_ostream &OS, MCSymbol &Sym); + + /// Print a stack object reference. + static void printStackObjectReference(raw_ostream &OS, unsigned FrameIndex, + bool IsFixed, StringRef Name); + + /// Print the MachineOperand to \p os. + /// Providing a valid \p TRI and \p IntrinsicInfo results in a more + /// target-specific printing. If \p TRI and \p IntrinsicInfo are null, the + /// function will try to pick it up from the parent. void print(raw_ostream &os, const TargetRegisterInfo *TRI = nullptr, const TargetIntrinsicInfo *IntrinsicInfo = nullptr) const; - void print(raw_ostream &os, ModuleSlotTracker &MST, - const TargetRegisterInfo *TRI = nullptr, - const TargetIntrinsicInfo *IntrinsicInfo = nullptr) const; + + /// More complex way of printing a MachineOperand. + /// \param TypeToPrint specifies the generic type to be printed on uses and + /// defs. It can be determined using MachineInstr::getTypeToPrint. + /// \param PrintDef - whether we want to print `def` on an operand which + /// isDef. Sometimes, if the operand is printed before '=', we don't print + /// `def`. + /// \param ShouldPrintRegisterTies - whether we want to print register ties. + /// Sometimes they are easily determined by the instruction's descriptor + /// (MachineInstr::hasComplexRegiterTies can determine if it's needed). + /// \param TiedOperandIdx - if we need to print register ties this needs to + /// provide the index of the tied register. If not, it will be ignored. + /// \param TRI - provide more target-specific information to the printer. + /// Unlike the previous function, this one will not try and get the + /// information from it's parent. + /// \param IntrinsicInfo - same as \p TRI. + void print(raw_ostream &os, ModuleSlotTracker &MST, LLT TypeToPrint, + bool PrintDef, bool ShouldPrintRegisterTies, + unsigned TiedOperandIdx, const TargetRegisterInfo *TRI, + const TargetIntrinsicInfo *IntrinsicInfo) const; + void dump() const; //===--------------------------------------------------------------------===// @@ -301,12 +349,12 @@ public: bool isDead() const { assert(isReg() && "Wrong MachineOperand accessor"); - return IsDead; + return IsDeadOrKill & IsDef; } bool isKill() const { assert(isReg() && "Wrong MachineOperand accessor"); - return IsKill; + return IsDeadOrKill & !IsDef; } bool isUndef() const { @@ -314,6 +362,8 @@ public: return IsUndef; } + bool isRenamable() const; + bool isInternalRead() const { assert(isReg() && "Wrong MachineOperand accessor"); return IsInternalRead; @@ -369,12 +419,13 @@ public: /// substPhysReg - Substitute the current register with the physical register /// Reg, taking any existing SubReg into account. For instance, - /// substPhysReg(%EAX) will change %reg1024:sub_8bit to %AL. + /// substPhysReg(%eax) will change %reg1024:sub_8bit to %al. /// void substPhysReg(unsigned Reg, const TargetRegisterInfo&); void setIsUse(bool Val = true) { setIsDef(!Val); } + /// Change a def to a use, or a use to a def. void setIsDef(bool Val = true); void setImplicit(bool Val = true) { @@ -385,12 +436,12 @@ public: void setIsKill(bool Val = true) { assert(isReg() && !IsDef && "Wrong MachineOperand mutator"); assert((!Val || !isDebug()) && "Marking a debug operation as kill"); - IsKill = Val; + IsDeadOrKill = Val; } void setIsDead(bool Val = true) { assert(isReg() && IsDef && "Wrong MachineOperand mutator"); - IsDead = Val; + IsDeadOrKill = Val; } void setIsUndef(bool Val = true) { @@ -398,6 +449,12 @@ public: IsUndef = Val; } + void setIsRenamable(bool Val = true); + + /// Set IsRenamable to true if there are no extra register allocation + /// requirements placed on this operand by the parent instruction's opcode. + void setIsRenamableIfNoExtraRegAllocReq(); + void setIsInternalRead(bool Val = true) { assert(isReg() && "Wrong MachineOperand mutator"); IsInternalRead = Val; @@ -549,6 +606,11 @@ public: Contents.OffsetedInfo.Val.Index = Idx; } + void setMetadata(const MDNode *MD) { + assert(isMetadata() && "Wrong MachineOperand mutator"); + Contents.MD = MD; + } + void setMBB(MachineBasicBlock *MBB) { assert(isMBB() && "Wrong MachineOperand mutator"); Contents.MBB = MBB; @@ -568,14 +630,16 @@ public: //===--------------------------------------------------------------------===// /// Returns true if this operand is identical to the specified operand except - /// for liveness related flags (isKill, isUndef and isDead). + /// for liveness related flags (isKill, isUndef and isDead). Note that this + /// should stay in sync with the hash_value overload below. bool isIdenticalTo(const MachineOperand &Other) const; /// \brief MachineOperand hash_value overload. /// /// Note that this includes the same information in the hash that /// isIdenticalTo uses for comparison. It is thus suited for use in hash - /// tables which use that function for equality comparisons only. + /// tables which use that function for equality comparisons only. This must + /// stay exactly in sync with isIdenticalTo above. friend hash_code hash_value(const MachineOperand &MO); /// ChangeToImmediate - Replace this operand with a new immediate operand of @@ -597,6 +661,10 @@ public: /// Replace this operand with a frame index. void ChangeToFrameIndex(int Idx); + /// Replace this operand with a target index. + void ChangeToTargetIndex(unsigned Idx, int64_t Offset, + unsigned char TargetFlags = 0); + /// ChangeToRegister - Replace this operand with a new register operand of /// the specified value. If an operand is known to be an register already, /// the setReg method should be used. @@ -630,16 +698,16 @@ public: bool isKill = false, bool isDead = false, bool isUndef = false, bool isEarlyClobber = false, - unsigned SubReg = 0, - bool isDebug = false, - bool isInternalRead = false) { + unsigned SubReg = 0, bool isDebug = false, + bool isInternalRead = false, + bool isRenamable = false) { assert(!(isDead && !isDef) && "Dead flag on non-def"); assert(!(isKill && isDef) && "Kill flag on def"); MachineOperand Op(MachineOperand::MO_Register); Op.IsDef = isDef; Op.IsImp = isImp; - Op.IsKill = isKill; - Op.IsDead = isDead; + Op.IsDeadOrKill = isKill | isDead; + Op.IsRenamable = isRenamable; Op.IsUndef = isUndef; Op.IsInternalRead = isInternalRead; Op.IsEarlyClobber = isEarlyClobber; @@ -679,8 +747,7 @@ public: Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateJTI(unsigned Idx, - unsigned char TargetFlags = 0) { + static MachineOperand CreateJTI(unsigned Idx, unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_JumpTableIndex); Op.setIndex(Idx); Op.setTargetFlags(TargetFlags); @@ -711,12 +778,12 @@ public: return Op; } /// CreateRegMask - Creates a register mask operand referencing Mask. The - /// operand does not take ownership of the memory referenced by Mask, it must - /// remain valid for the lifetime of the operand. + /// operand does not take ownership of the memory referenced by Mask, it + /// must remain valid for the lifetime of the operand. /// - /// A RegMask operand represents a set of non-clobbered physical registers on - /// an instruction that clobbers many registers, typically a call. The bit - /// mask has a bit set for each physreg that is preserved by this + /// A RegMask operand represents a set of non-clobbered physical registers + /// on an instruction that clobbers many registers, typically a call. The + /// bit mask has a bit set for each physreg that is preserved by this /// instruction, as described in the documentation for /// TargetRegisterInfo::getCallPreservedMask(). /// @@ -769,30 +836,63 @@ public: friend class MachineInstr; friend class MachineRegisterInfo; + private: + // If this operand is currently a register operand, and if this is in a + // function, deregister the operand from the register's use/def list. void removeRegFromUses(); + /// Artificial kinds for DenseMap usage. + enum : unsigned char { + MO_Empty = MO_Last + 1, + MO_Tombstone, + }; + + friend struct DenseMapInfo<MachineOperand>; + //===--------------------------------------------------------------------===// // Methods for handling register use/def lists. //===--------------------------------------------------------------------===// - /// isOnRegUseList - Return true if this operand is on a register use/def list - /// or false if not. This can only be called for register operands that are - /// part of a machine instruction. + /// isOnRegUseList - Return true if this operand is on a register use/def + /// list or false if not. This can only be called for register operands + /// that are part of a machine instruction. bool isOnRegUseList() const { assert(isReg() && "Can only add reg operand to use lists"); return Contents.Reg.Prev != nullptr; } }; -inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) { - MO.print(OS, nullptr); +template <> struct DenseMapInfo<MachineOperand> { + static MachineOperand getEmptyKey() { + return MachineOperand(static_cast<MachineOperand::MachineOperandType>( + MachineOperand::MO_Empty)); + } + static MachineOperand getTombstoneKey() { + return MachineOperand(static_cast<MachineOperand::MachineOperandType>( + MachineOperand::MO_Tombstone)); + } + static unsigned getHashValue(const MachineOperand &MO) { + return hash_value(MO); + } + static bool isEqual(const MachineOperand &LHS, const MachineOperand &RHS) { + if (LHS.getType() == static_cast<MachineOperand::MachineOperandType>( + MachineOperand::MO_Empty) || + LHS.getType() == static_cast<MachineOperand::MachineOperandType>( + MachineOperand::MO_Tombstone)) + return LHS.getType() == RHS.getType(); + return LHS.isIdenticalTo(RHS); + } +}; + +inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand &MO) { + MO.print(OS); return OS; } - // See friend declaration above. This additional declaration is required in - // order to compile LLVM with IBM xlC compiler. - hash_code hash_value(const MachineOperand &MO); -} // End llvm namespace +// See friend declaration above. This additional declaration is required in +// order to compile LLVM with IBM xlC compiler. +hash_code hash_value(const MachineOperand &MO); +} // namespace llvm #endif |