diff options
Diffstat (limited to 'include/llvm/CodeGen/MachineInstr.h')
-rw-r--r-- | include/llvm/CodeGen/MachineInstr.h | 162 |
1 files changed, 132 insertions, 30 deletions
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index cccab81efbb2..3c828116411e 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -22,13 +22,14 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/CodeGen/MachineOperand.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugLoc.h" #include "llvm/IR/InlineAsm.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/Support/ArrayRecycler.h" -#include "llvm/Support/DebugLoc.h" #include "llvm/Target/TargetOpcodes.h" -#include <vector> namespace llvm { @@ -243,6 +244,14 @@ public: /// DebugLoc getDebugLoc() const { return debugLoc; } + /// getDebugVariable() - Return the debug variable referenced by + /// this DBG_VALUE instruction. + DIVariable getDebugVariable() const { + assert(isDebugValue() && "not a DBG_VALUE"); + const MDNode *Var = getOperand(getNumOperands() - 1).getMetadata(); + return DIVariable(Var); + } + /// emitError - Emit an error referring to the source location of this /// instruction. This should only be used for inline assembly that is somehow /// impossible to compile. Other errors should have been handled much @@ -287,11 +296,57 @@ public: const_mop_iterator operands_begin() const { return Operands; } const_mop_iterator operands_end() const { return Operands + NumOperands; } + iterator_range<mop_iterator> operands() { + return iterator_range<mop_iterator>(operands_begin(), operands_end()); + } + iterator_range<const_mop_iterator> operands() const { + return iterator_range<const_mop_iterator>(operands_begin(), operands_end()); + } + iterator_range<mop_iterator> explicit_operands() { + return iterator_range<mop_iterator>( + operands_begin(), operands_begin() + getNumExplicitOperands()); + } + iterator_range<const_mop_iterator> explicit_operands() const { + return iterator_range<const_mop_iterator>( + operands_begin(), operands_begin() + getNumExplicitOperands()); + } + iterator_range<mop_iterator> implicit_operands() { + return iterator_range<mop_iterator>(explicit_operands().end(), + operands_end()); + } + iterator_range<const_mop_iterator> implicit_operands() const { + return iterator_range<const_mop_iterator>(explicit_operands().end(), + operands_end()); + } + iterator_range<mop_iterator> defs() { + return iterator_range<mop_iterator>( + operands_begin(), operands_begin() + getDesc().getNumDefs()); + } + iterator_range<const_mop_iterator> defs() const { + return iterator_range<const_mop_iterator>( + operands_begin(), operands_begin() + getDesc().getNumDefs()); + } + iterator_range<mop_iterator> uses() { + return iterator_range<mop_iterator>( + operands_begin() + getDesc().getNumDefs(), operands_end()); + } + iterator_range<const_mop_iterator> uses() const { + return iterator_range<const_mop_iterator>( + operands_begin() + getDesc().getNumDefs(), operands_end()); + } + /// Access to memory operands of the instruction mmo_iterator memoperands_begin() const { return MemRefs; } mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; } bool memoperands_empty() const { return NumMemRefs == 0; } + iterator_range<mmo_iterator> memoperands() { + return iterator_range<mmo_iterator>(memoperands_begin(), memoperands_end()); + } + iterator_range<mmo_iterator> memoperands() const { + return iterator_range<mmo_iterator>(memoperands_begin(), memoperands_end()); + } + /// hasOneMemOperand - Return true if this instruction has exactly one /// MachineMemOperand. bool hasOneMemOperand() const { @@ -623,19 +678,19 @@ public: /// bundle remain bundled. void eraseFromBundle(); + bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } + bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } + /// isLabel - Returns true if the MachineInstr represents a label. /// - bool isLabel() const { - return getOpcode() == TargetOpcode::PROLOG_LABEL || - getOpcode() == TargetOpcode::EH_LABEL || - getOpcode() == TargetOpcode::GC_LABEL; + bool isLabel() const { return isEHLabel() || isGCLabel(); } + bool isCFIInstruction() const { + return getOpcode() == TargetOpcode::CFI_INSTRUCTION; } - bool isPrologLabel() const { - return getOpcode() == TargetOpcode::PROLOG_LABEL; - } - bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } - bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } + // True if the instruction represents a position in the function. + bool isPosition() const { return isLabel() || isCFIInstruction(); } + bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; } /// A DBG_VALUE is indirect iff the first operand is a register and /// the second operand is an immediate. @@ -672,6 +727,9 @@ public: bool isFullCopy() const { return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg(); } + bool isExtractSubreg() const { + return getOpcode() == TargetOpcode::EXTRACT_SUBREG; + } /// isCopyLike - Return true if the instruction behaves like a copy. /// This does not include native copy instructions. @@ -701,7 +759,7 @@ public: // Pseudo-instructions that don't produce any real output. case TargetOpcode::IMPLICIT_DEF: case TargetOpcode::KILL: - case TargetOpcode::PROLOG_LABEL: + case TargetOpcode::CFI_INSTRUCTION: case TargetOpcode::EH_LABEL: case TargetOpcode::GC_LABEL: case TargetOpcode::DBG_VALUE: @@ -721,7 +779,8 @@ public: /// is a read of a super-register. /// This does not count partial redefines of virtual registers as reads: /// %reg1024:6 = OP. - bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI = NULL) const { + bool readsRegister(unsigned Reg, + const TargetRegisterInfo *TRI = nullptr) const { return findRegisterUseOperandIdx(Reg, false, TRI) != -1; } @@ -737,12 +796,13 @@ public: /// partial defines. /// If Ops is not null, all operand indices for Reg are added. std::pair<bool,bool> readsWritesVirtualRegister(unsigned Reg, - SmallVectorImpl<unsigned> *Ops = 0) const; + SmallVectorImpl<unsigned> *Ops = nullptr) const; /// killsRegister - Return true if the MachineInstr kills the specified /// register. If TargetRegisterInfo is passed, then it also checks if there is /// a kill of a super-register. - bool killsRegister(unsigned Reg, const TargetRegisterInfo *TRI = NULL) const { + bool killsRegister(unsigned Reg, + const TargetRegisterInfo *TRI = nullptr) const { return findRegisterUseOperandIdx(Reg, true, TRI) != -1; } @@ -750,7 +810,8 @@ public: /// specified register. If TargetRegisterInfo is passed, then it also checks /// if there is a def of a super-register. /// NOTE: It's ignoring subreg indices on virtual registers. - bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const { + bool definesRegister(unsigned Reg, + const TargetRegisterInfo *TRI = nullptr) const { return findRegisterDefOperandIdx(Reg, false, false, TRI) != -1; } @@ -765,7 +826,7 @@ public: /// instruction. If TargetRegisterInfo is passed, then it also checks /// if there is a dead def of a super-register. bool registerDefIsDead(unsigned Reg, - const TargetRegisterInfo *TRI = NULL) const { + const TargetRegisterInfo *TRI = nullptr) const { return findRegisterDefOperandIdx(Reg, true, false, TRI) != -1; } @@ -773,14 +834,14 @@ public: /// the specific register or -1 if it is not found. It further tightens /// the search criteria to a use that kills the register if isKill is true. int findRegisterUseOperandIdx(unsigned Reg, bool isKill = false, - const TargetRegisterInfo *TRI = NULL) const; + const TargetRegisterInfo *TRI = nullptr) const; /// findRegisterUseOperand - Wrapper for findRegisterUseOperandIdx, it returns /// a pointer to the MachineOperand rather than an index. MachineOperand *findRegisterUseOperand(unsigned Reg, bool isKill = false, - const TargetRegisterInfo *TRI = NULL) { + const TargetRegisterInfo *TRI = nullptr) { int Idx = findRegisterUseOperandIdx(Reg, isKill, TRI); - return (Idx == -1) ? NULL : &getOperand(Idx); + return (Idx == -1) ? nullptr : &getOperand(Idx); } /// findRegisterDefOperandIdx() - Returns the operand index that is a def of @@ -791,14 +852,14 @@ public: /// This may also return a register mask operand when Overlap is true. int findRegisterDefOperandIdx(unsigned Reg, bool isDead = false, bool Overlap = false, - const TargetRegisterInfo *TRI = NULL) const; + const TargetRegisterInfo *TRI = nullptr) const; /// findRegisterDefOperand - Wrapper for findRegisterDefOperandIdx, it returns /// a pointer to the MachineOperand rather than an index. MachineOperand *findRegisterDefOperand(unsigned Reg, bool isDead = false, - const TargetRegisterInfo *TRI = NULL) { + const TargetRegisterInfo *TRI = nullptr) { int Idx = findRegisterDefOperandIdx(Reg, isDead, false, TRI); - return (Idx == -1) ? NULL : &getOperand(Idx); + return (Idx == -1) ? nullptr : &getOperand(Idx); } /// findFirstPredOperandIdx() - Find the index of the first operand in the @@ -816,7 +877,7 @@ public: /// The flag operand is an immediate that can be decoded with methods like /// InlineAsm::hasRegClassConstraint(). /// - int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = 0) const; + int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = nullptr) const; /// getRegClassConstraint - Compute the static register class constraint for /// operand OpIdx. For normal instructions, this is derived from the @@ -830,6 +891,37 @@ public: const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const; + /// \brief Applies the constraints (def/use) implied by this MI on \p Reg to + /// the given \p CurRC. + /// If \p ExploreBundle is set and MI is part of a bundle, all the + /// instructions inside the bundle will be taken into account. In other words, + /// this method accumulates all the constrains of the operand of this MI and + /// the related bundle if MI is a bundle or inside a bundle. + /// + /// Returns the register class that statisfies both \p CurRC and the + /// constraints set by MI. Returns NULL if such a register class does not + /// exist. + /// + /// \pre CurRC must not be NULL. + const TargetRegisterClass *getRegClassConstraintEffectForVReg( + unsigned Reg, const TargetRegisterClass *CurRC, + const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, + bool ExploreBundle = false) const; + + /// \brief Applies the constraints (def/use) implied by the \p OpIdx operand + /// to the given \p CurRC. + /// + /// Returns the register class that statisfies both \p CurRC and the + /// constraints set by \p OpIdx MI. Returns NULL if such a register class + /// does not exist. + /// + /// \pre CurRC must not be NULL. + /// \pre The operand at \p OpIdx must be a register. + const TargetRegisterClass * + getRegClassConstraintEffect(unsigned OpIdx, const TargetRegisterClass *CurRC, + const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI) const; + /// tieOperands - Add a tie between the register operands at DefIdx and /// UseIdx. The tie will cause the register allocator to ensure that the two /// operands are assigned the same physical register. @@ -847,7 +939,8 @@ public: /// check if the register def is tied to a source operand, due to either /// two-address elimination or inline assembly constraints. Returns the /// first tied use operand index by reference if UseOpIdx is not null. - bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx = 0) const { + bool isRegTiedToUseOperand(unsigned DefOpIdx, + unsigned *UseOpIdx = nullptr) const { const MachineOperand &MO = getOperand(DefOpIdx); if (!MO.isReg() || !MO.isDef() || !MO.isTied()) return false; @@ -857,9 +950,10 @@ public: } /// isRegTiedToDefOperand - Return true if the use operand of the specified - /// index is tied to an def operand. It also returns the def operand index by + /// index is tied to a def operand. It also returns the def operand index by /// reference if DefOpIdx is not null. - bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0) const { + bool isRegTiedToDefOperand(unsigned UseOpIdx, + unsigned *DefOpIdx = nullptr) const { const MachineOperand &MO = getOperand(UseOpIdx); if (!MO.isReg() || !MO.isUse() || !MO.isTied()) return false; @@ -898,7 +992,8 @@ public: /// addRegisterDefined - We have determined MI defines a register. Make sure /// there is an operand defining Reg. - void addRegisterDefined(unsigned Reg, const TargetRegisterInfo *RegInfo = 0); + void addRegisterDefined(unsigned Reg, + const TargetRegisterInfo *RegInfo = nullptr); /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as /// dead except those in the UsedRegs list. @@ -952,7 +1047,7 @@ public: // // Debugging support // - void print(raw_ostream &OS, const TargetMachine *TM = 0, + void print(raw_ostream &OS, const TargetMachine *TM = nullptr, bool SkipOpers = false) const; void dump() const; @@ -1038,6 +1133,13 @@ private: /// hasPropertyInBundle - Slow path for hasProperty when we're dealing with a /// bundle. bool hasPropertyInBundle(unsigned Mask, QueryType Type) const; + + /// \brief Implements the logic of getRegClassConstraintEffectForVReg for the + /// this MI and the given operand index \p OpIdx. + /// If the related operand does not constrained Reg, this returns CurRC. + const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl( + unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC, + const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const; }; /// MachineInstrExpressionTrait - Special DenseMapInfo traits to compare @@ -1046,7 +1148,7 @@ private: /// useful for CSE, etc. struct MachineInstrExpressionTrait : DenseMapInfo<MachineInstr*> { static inline MachineInstr *getEmptyKey() { - return 0; + return nullptr; } static inline MachineInstr *getTombstoneKey() { |