diff options
Diffstat (limited to 'include/llvm/CodeGen/MachineOperand.h')
-rw-r--r-- | include/llvm/CodeGen/MachineOperand.h | 98 |
1 files changed, 75 insertions, 23 deletions
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 4be7942c2c64..53e8889d118a 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -74,7 +74,7 @@ public: private: /// OpKind - Specify what kind of operand this is. This discriminates the /// union. - MachineOperandType OpKind : 8; + unsigned OpKind : 8; /// Subregister number for MO_Register. A value of 0 indicates the /// MO_Register has no subReg. @@ -85,17 +85,17 @@ private: /// TiedTo - Non-zero when this register operand is tied to another register /// operand. The encoding of this field is described in the block comment /// before MachineInstr::tieOperands(). - unsigned char TiedTo : 4; + unsigned TiedTo : 4; /// 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; + unsigned 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; + unsigned IsImp : 1; /// IsDeadOrKill /// For uses: IsKill - True if this instruction is the last use of the @@ -103,14 +103,10 @@ private: /// For defs: IsDead - True if this register is never used by a subsequent /// instruction. /// This is only valid on register operands. - bool IsDeadOrKill : 1; + unsigned 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; + /// See isRenamable(). + unsigned 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 @@ -129,7 +125,7 @@ private: /// 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; + unsigned IsUndef : 1; /// IsInternalRead - True if this operand reads a value that was defined /// inside the same instruction or bundle. This flag can be set on both use @@ -140,16 +136,16 @@ private: /// When this flag is set, the instruction bundle must contain at least one /// other def of the register. If multiple instructions in the bundle define /// the register, the meaning is target-defined. - bool IsInternalRead : 1; + unsigned IsInternalRead : 1; /// IsEarlyClobber - True if this MO_Register 'def' operand is written to /// by the MachineInstr before all input registers are read. This is used to /// model the GCC inline asm '&' constraint modifier. - bool IsEarlyClobber : 1; + unsigned IsEarlyClobber : 1; /// IsDebug - True if this MO_Register 'use' operand is in a debug pseudo, /// not a real instruction. Such uses should be ignored during codegen. - bool IsDebug : 1; + unsigned IsDebug : 1; /// SmallContents - This really should be part of the Contents union, but /// lives out here so we can get a better packed struct. @@ -198,7 +194,19 @@ private: } Contents; explicit MachineOperand(MachineOperandType K) - : OpKind(K), SubReg_TargetFlags(0), ParentMI(nullptr) {} + : OpKind(K), SubReg_TargetFlags(0), ParentMI(nullptr) { + // Assert that the layout is what we expect. It's easy to grow this object. + static_assert(alignof(MachineOperand) <= alignof(int64_t), + "MachineOperand shouldn't be more than 8 byte aligned"); + static_assert(sizeof(Contents) <= 2 * sizeof(void *), + "Contents should be at most two pointers"); + static_assert(sizeof(MachineOperand) <= + alignTo<alignof(int64_t)>(2 * sizeof(unsigned) + + 3 * sizeof(void *)), + "MachineOperand too big. Should be Kind, SmallContents, " + "ParentMI, and Contents"); + } + public: /// getType - Returns the MachineOperandType for this operand. /// @@ -238,7 +246,7 @@ public: /// 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, + static void printSubRegIdx(raw_ostream &OS, uint64_t Index, const TargetRegisterInfo *TRI); /// Print operand target flags. @@ -270,6 +278,9 @@ public: /// \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 IsStandalone - whether we want a verbose output of the MO. This + /// prints extra information that can be easily inferred when printing the + /// whole function, but not when printing only a fragment of it. /// \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). @@ -280,10 +291,16 @@ public: /// information from it's parent. /// \param IntrinsicInfo - same as \p TRI. void print(raw_ostream &os, ModuleSlotTracker &MST, LLT TypeToPrint, - bool PrintDef, bool ShouldPrintRegisterTies, + bool PrintDef, bool IsStandalone, bool ShouldPrintRegisterTies, unsigned TiedOperandIdx, const TargetRegisterInfo *TRI, const TargetIntrinsicInfo *IntrinsicInfo) const; + /// Same as print(os, TRI, IntrinsicInfo), but allows to specify the low-level + /// type to be printed the same way the full version of print(...) does it. + void print(raw_ostream &os, LLT TypeToPrint, + const TargetRegisterInfo *TRI = nullptr, + const TargetIntrinsicInfo *IntrinsicInfo = nullptr) const; + void dump() const; //===--------------------------------------------------------------------===// @@ -369,6 +386,35 @@ public: return IsUndef; } + /// isRenamable - Returns 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. + /// + /// Operands that are renamable can freely be changed to any other register + /// that is a member of the register class returned by + /// MI->getRegClassConstraint(). + /// + /// isRenamable can return false for several different reasons: + /// + /// - ABI constraints (since liveness is not always precisely modeled). We + /// conservatively handle these cases by setting all physical register + /// operands that didn’t start out as virtual regs to not be renamable. + /// Also any physical register operands created after register allocation or + /// whose register is changed after register allocation will not be + /// renamable. This state is tracked in the MachineOperand::IsRenamable + /// bit. + /// + /// - Opcode/target constraints: for opcodes that have complex register class + /// requirements (e.g. that depend on other operands/instructions), we set + /// hasExtraSrcRegAllocReq/hasExtraDstRegAllocReq in the machine opcode + /// description. Operands belonging to instructions with opcodes that are + /// marked hasExtraSrcRegAllocReq/hasExtraDstRegAllocReq return false from + /// isRenamable(). Additionally, the AllowRegisterRenaming target property + /// prevents any operands from being marked renamable for targets that don't + /// have detailed opcode hasExtraSrcRegAllocReq/hasExtraDstRegAllocReq + /// values. bool isRenamable() const; bool isInternalRead() const { @@ -458,10 +504,6 @@ public: 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; @@ -574,6 +616,11 @@ public: return Contents.RegMask; } + /// Returns number of elements needed for a regmask array. + static unsigned getRegMaskSize(unsigned NumRegs) { + return (NumRegs + 31) / 32; + } + /// getRegLiveOut - Returns a bit mask of live-out registers. const uint32_t *getRegLiveOut() const { assert(isRegLiveOut() && "Wrong MachineOperand accessor"); @@ -594,6 +641,11 @@ public: Contents.ImmVal = immVal; } + void setCImm(const ConstantInt *CI) { + assert(isCImm() && "Wrong MachineOperand mutator"); + Contents.CI = CI; + } + void setFPImm(const ConstantFP *CFP) { assert(isFPImm() && "Wrong MachineOperand mutator"); Contents.CFP = CFP; @@ -641,7 +693,7 @@ public: /// should stay in sync with the hash_value overload below. bool isIdenticalTo(const MachineOperand &Other) const; - /// \brief MachineOperand hash_value overload. + /// 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 |