X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineOperand.h;h=ddffdcaf1e4db4ca0e7767dc54781df66625d14f;hb=530a574a9dc6de13fe2bab31a461ba6bdb2a4c54;hp=d46101884c7f38a6c53702acb48e22890e5658b0;hpb=9bac67657bb158d8649e85494f5999993591b87c;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index d46101884c7..ddffdcaf1e4 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -14,7 +14,6 @@ #ifndef LLVM_CODEGEN_MACHINEOPERAND_H #define LLVM_CODEGEN_MACHINEOPERAND_H -#include "llvm/ADT/Hashing.h" #include "llvm/Support/DataTypes.h" #include @@ -30,42 +29,54 @@ class MachineRegisterInfo; class MDNode; class TargetMachine; class TargetRegisterInfo; +class hash_code; class raw_ostream; class MCSymbol; /// MachineOperand class - Representation of each machine instruction operand. /// +/// This class isn't a POD type because it has a private constructor, but its +/// destructor must be trivial. Functions like MachineInstr::addOperand(), +/// MachineRegisterInfo::moveOperands(), and MF::DeleteMachineInstr() depend on +/// not having to call the MachineOperand destructor. +/// class MachineOperand { public: - enum MachineOperandType { - MO_Register, ///< Register operand. - MO_Immediate, ///< Immediate operand - MO_CImmediate, ///< Immediate >64bit operand - MO_FPImmediate, ///< Floating-point immediate operand - MO_MachineBasicBlock, ///< MachineBasicBlock reference - MO_FrameIndex, ///< Abstract Stack Frame Index - MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool - MO_TargetIndex, ///< Target-dependent index+offset operand. - MO_JumpTableIndex, ///< Address of indexed Jump Table for switch - MO_ExternalSymbol, ///< Name of external global symbol - MO_GlobalAddress, ///< Address of a global value - MO_BlockAddress, ///< Address of a basic block - MO_RegisterMask, ///< Mask of preserved registers. - MO_Metadata, ///< Metadata reference (for debug info) - MO_MCSymbol ///< MCSymbol reference (for debug/eh info) + enum MachineOperandType : unsigned char { + MO_Register, ///< Register operand. + MO_Immediate, ///< Immediate operand + MO_CImmediate, ///< Immediate >64bit operand + MO_FPImmediate, ///< Floating-point immediate operand + MO_MachineBasicBlock, ///< MachineBasicBlock reference + MO_FrameIndex, ///< Abstract Stack Frame Index + MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool + MO_TargetIndex, ///< Target-dependent index+offset operand. + MO_JumpTableIndex, ///< Address of indexed Jump Table for switch + MO_ExternalSymbol, ///< Name of external global symbol + MO_GlobalAddress, ///< Address of a global value + MO_BlockAddress, ///< Address of a basic block + MO_RegisterMask, ///< Mask of preserved registers. + MO_RegisterLiveOut, ///< Mask of live-out registers. + MO_Metadata, ///< Metadata reference (for debug info) + MO_MCSymbol, ///< MCSymbol reference (for debug/eh info) + MO_CFIIndex ///< MCCFIInstruction index. }; private: /// OpKind - Specify what kind of operand this is. This discriminates the /// union. - unsigned char OpKind; // MachineOperandType + MachineOperandType OpKind : 8; - /// SubReg - Subregister number, only valid for MO_Register. A value of 0 - /// indicates the MO_Register has no subReg. - unsigned char SubReg; + /// Subregister number for MO_Register. A value of 0 indicates the + /// MO_Register has no subReg. + /// + /// For all other kinds of operands, this field holds target-specific flags. + unsigned SubReg_TargetFlags : 12; - /// TargetFlags - This is a set of target-specific operand flags. - unsigned char TargetFlags; + /// 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; /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register /// operands. @@ -140,17 +151,18 @@ private: /// Contents union - This contains the payload for the various operand types. union { - MachineBasicBlock *MBB; // For MO_MachineBasicBlock. - const ConstantFP *CFP; // For MO_FPImmediate. - const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit. - int64_t ImmVal; // For MO_Immediate. - const uint32_t *RegMask; // For MO_RegisterMask. - const MDNode *MD; // For MO_Metadata. - MCSymbol *Sym; // For MO_MCSymbol + MachineBasicBlock *MBB; // For MO_MachineBasicBlock. + const ConstantFP *CFP; // For MO_FPImmediate. + const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit. + int64_t ImmVal; // For MO_Immediate. + const uint32_t *RegMask; // For MO_RegisterMask and MO_RegisterLiveOut. + const MDNode *MD; // For MO_Metadata. + MCSymbol *Sym; // For MO_MCSymbol. + unsigned CFIIndex; // For MO_CFI. struct { // For MO_Register. // Register number is in SmallContents.RegNo. - MachineOperand **Prev; // Access list for register. + MachineOperand *Prev; // Access list for register. See MRI. MachineOperand *Next; } Reg; @@ -168,17 +180,26 @@ private: } OffsetedInfo; } Contents; - explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) { - TargetFlags = 0; - } + explicit MachineOperand(MachineOperandType K) + : OpKind(K), SubReg_TargetFlags(0), ParentMI(nullptr) {} public: /// getType - Returns the MachineOperandType for this operand. /// MachineOperandType getType() const { return (MachineOperandType)OpKind; } - unsigned char getTargetFlags() const { return TargetFlags; } - void setTargetFlags(unsigned char F) { TargetFlags = F; } - void addTargetFlag(unsigned char F) { TargetFlags |= F; } + unsigned getTargetFlags() const { + return isReg() ? 0 : SubReg_TargetFlags; + } + void setTargetFlags(unsigned F) { + assert(!isReg() && "Register operands can't have target flags"); + SubReg_TargetFlags = F; + assert(SubReg_TargetFlags == F && "Target flags out of range"); + } + void addTargetFlag(unsigned F) { + assert(!isReg() && "Register operands can't have target flags"); + SubReg_TargetFlags |= F; + assert((SubReg_TargetFlags & F) && "Target flags out of range"); + } /// getParent - Return the instruction that this operand belongs to. @@ -194,9 +215,9 @@ public: /// /// Never call clearParent() on an operand in a MachineInstr. /// - void clearParent() { ParentMI = 0; } + void clearParent() { ParentMI = nullptr; } - void print(raw_ostream &os, const TargetMachine *TM = 0) const; + void print(raw_ostream &os, const TargetRegisterInfo *TRI = nullptr) const; //===--------------------------------------------------------------------===// // Accessors that tell you what kind of MachineOperand you're looking at. @@ -206,7 +227,7 @@ public: bool isReg() const { return OpKind == MO_Register; } /// isImm - Tests if this is a MO_Immediate operand. bool isImm() const { return OpKind == MO_Immediate; } - /// isCImm - Test if t his is a MO_CImmediate operand. + /// isCImm - Test if this is a MO_CImmediate operand. bool isCImm() const { return OpKind == MO_CImmediate; } /// isFPImm - Tests if this is a MO_FPImmediate operand. bool isFPImm() const { return OpKind == MO_FPImmediate; } @@ -228,10 +249,12 @@ public: bool isBlockAddress() const { return OpKind == MO_BlockAddress; } /// isRegMask - Tests if this is a MO_RegisterMask operand. bool isRegMask() const { return OpKind == MO_RegisterMask; } + /// isRegLiveOut - Tests if this is a MO_RegisterLiveOut operand. + bool isRegLiveOut() const { return OpKind == MO_RegisterLiveOut; } /// isMetadata - Tests if this is a MO_Metadata operand. bool isMetadata() const { return OpKind == MO_Metadata; } bool isMCSymbol() const { return OpKind == MO_MCSymbol; } - + bool isCFIIndex() const { return OpKind == MO_CFIIndex; } //===--------------------------------------------------------------------===// // Accessors for Register Operands @@ -245,7 +268,7 @@ public: unsigned getSubReg() const { assert(isReg() && "Wrong MachineOperand accessor"); - return (unsigned)SubReg; + return SubReg_TargetFlags; } bool isUse() const { @@ -288,6 +311,11 @@ public: return IsEarlyClobber; } + bool isTied() const { + assert(isReg() && "Wrong MachineOperand accessor"); + return TiedTo; + } + bool isDebug() const { assert(isReg() && "Wrong MachineOperand accessor"); return IsDebug; @@ -315,7 +343,8 @@ public: void setSubReg(unsigned subReg) { assert(isReg() && "Wrong MachineOperand accessor"); - SubReg = (unsigned char)subReg; + SubReg_TargetFlags = subReg; + assert(SubReg_TargetFlags == subReg && "SubReg out of range"); } /// substVirtReg - Substitute the current register with the virtual @@ -331,17 +360,9 @@ public: /// void substPhysReg(unsigned Reg, const TargetRegisterInfo&); - void setIsUse(bool Val = true) { - assert(isReg() && "Wrong MachineOperand accessor"); - assert((Val || !isDebug()) && "Marking a debug operation as def"); - IsDef = !Val; - } + void setIsUse(bool Val = true) { setIsDef(!Val); } - void setIsDef(bool Val = true) { - assert(isReg() && "Wrong MachineOperand accessor"); - assert((!Val || !isDebug()) && "Marking a debug operation as def"); - IsDef = Val; - } + void setIsDef(bool Val = true); void setImplicit(bool Val = true) { assert(isReg() && "Wrong MachineOperand accessor"); @@ -375,7 +396,7 @@ public: } void setIsDebug(bool Val = true) { - assert(isReg() && IsDef && "Wrong MachineOperand accessor"); + assert(isReg() && !IsDef && "Wrong MachineOperand accessor"); IsDebug = Val; } @@ -424,12 +445,17 @@ public: return Contents.Sym; } + unsigned getCFIIndex() const { + assert(isCFIIndex() && "Wrong MachineOperand accessor"); + return Contents.CFIIndex; + } + /// getOffset - Return the offset from the symbol in this operand. This always /// returns 0 for ExternalSymbol operands. int64_t getOffset() const { assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() || isBlockAddress()) && "Wrong MachineOperand accessor"); - return (int64_t(Contents.OffsetedInfo.OffsetHi) << 32) | + return int64_t(uint64_t(Contents.OffsetedInfo.OffsetHi) << 32) | SmallContents.OffsetLo; } @@ -460,6 +486,12 @@ public: return Contents.RegMask; } + /// getRegLiveOut - Returns a bit mask of live-out registers. + const uint32_t *getRegLiveOut() const { + assert(isRegLiveOut() && "Wrong MachineOperand accessor"); + return Contents.RegMask; + } + const MDNode *getMetadata() const { assert(isMetadata() && "Wrong MachineOperand accessor"); return Contents.MD; @@ -474,6 +506,11 @@ public: Contents.ImmVal = immVal; } + void setFPImm(const ConstantFP *CFP) { + assert(isFPImm() && "Wrong MachineOperand mutator"); + Contents.CFP = CFP; + } + void setOffset(int64_t Offset) { assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() || isBlockAddress()) && "Wrong MachineOperand accessor"); @@ -512,6 +549,17 @@ public: /// the setImm method should be used. void ChangeToImmediate(int64_t ImmVal); + /// ChangeToFPImmediate - Replace this operand with a new FP immediate operand + /// of the specified value. If an operand is known to be an FP immediate + /// already, the setFPImm method should be used. + void ChangeToFPImmediate(const ConstantFP *FPImm); + + /// ChangeToES - Replace this operand with a new external symbol operand. + void ChangeToES(const char *SymName, unsigned char TargetFlags = 0); + + /// ChangeToMCSymbol - Replace this operand with a new MC symbol operand. + void ChangeToMCSymbol(MCSymbol *Sym); + /// 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. @@ -548,6 +596,8 @@ public: unsigned SubReg = 0, bool isDebug = false, bool isInternalRead = 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; @@ -556,11 +606,12 @@ public: Op.IsUndef = isUndef; Op.IsInternalRead = isInternalRead; Op.IsEarlyClobber = isEarlyClobber; + Op.TiedTo = 0; Op.IsDebug = isDebug; Op.SmallContents.RegNo = Reg; - Op.Contents.Reg.Prev = 0; - Op.Contents.Reg.Next = 0; - Op.SubReg = SubReg; + Op.Contents.Reg.Prev = nullptr; + Op.Contents.Reg.Next = nullptr; + Op.setSubReg(SubReg); return Op; } static MachineOperand CreateMBB(MachineBasicBlock *MBB, @@ -614,11 +665,11 @@ public: Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateBA(const BlockAddress *BA, + static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset, unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_BlockAddress); Op.Contents.OffsetedInfo.Val.BA = BA; - Op.setOffset(0); // Offset is always 0. + Op.setOffset(Offset); Op.setTargetFlags(TargetFlags); return Op; } @@ -640,6 +691,12 @@ public: Op.Contents.RegMask = Mask; return Op; } + static MachineOperand CreateRegLiveOut(const uint32_t *Mask) { + assert(Mask && "Missing live-out register mask"); + MachineOperand Op(MachineOperand::MO_RegisterLiveOut); + Op.Contents.RegMask = Mask; + return Op; + } static MachineOperand CreateMetadata(const MDNode *Meta) { MachineOperand Op(MachineOperand::MO_Metadata); Op.Contents.MD = Meta; @@ -652,9 +709,17 @@ public: return Op; } + static MachineOperand CreateCFIIndex(unsigned CFIIndex) { + MachineOperand Op(MachineOperand::MO_CFIIndex); + Op.Contents.CFIIndex = CFIIndex; + return Op; + } + friend class MachineInstr; friend class MachineRegisterInfo; private: + void removeRegFromUses(); + //===--------------------------------------------------------------------===// // Methods for handling register use/def lists. //===--------------------------------------------------------------------===// @@ -664,24 +729,18 @@ private: /// part of a machine instruction. bool isOnRegUseList() const { assert(isReg() && "Can only add reg operand to use lists"); - return Contents.Reg.Prev != 0; + return Contents.Reg.Prev != nullptr; } - - /// AddRegOperandToRegInfo - Add this register operand to the specified - /// MachineRegisterInfo. If it is null, then the next/prev fields should be - /// explicitly nulled out. - void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo); - - /// RemoveRegOperandFromRegInfo - Remove this register operand from the - /// MachineRegisterInfo it is linked with. - void RemoveRegOperandFromRegInfo(); }; inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) { - MO.print(OS, 0); + MO.print(OS, nullptr); 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 #endif