DebugLoc debugLoc; // Source line information.
- MachineInstr(const MachineInstr&) LLVM_DELETED_FUNCTION;
- void operator=(const MachineInstr&) LLVM_DELETED_FUNCTION;
+ MachineInstr(const MachineInstr&) = delete;
+ void operator=(const MachineInstr&) = delete;
// Use MachineFunction::DeleteMachineInstr() instead.
- ~MachineInstr() LLVM_DELETED_FUNCTION;
+ ~MachineInstr() = delete;
// Intrusive list support
friend struct ilist_traits<MachineInstr>;
/// MachineInstr ctor - This constructor create a MachineInstr and add the
/// implicit operands. It reserves space for number of operands specified by
/// MCInstrDesc. An explicit DebugLoc is supplied.
- MachineInstr(MachineFunction&, const MCInstrDesc &MCID,
- const DebugLoc dl, bool NoImp = false);
+ MachineInstr(MachineFunction &, const MCInstrDesc &MCID, DebugLoc dl,
+ bool NoImp = false);
// MachineInstrs are pool-allocated and owned by MachineFunction.
friend class MachineFunction;
/// getDebugLoc - Returns the debug location id of this MachineInstr.
///
- DebugLoc getDebugLoc() const { return debugLoc; }
+ const DebugLoc &getDebugLoc() const { return debugLoc; }
- /// getDebugVariable() - Return the debug variable referenced by
+ /// \brief Return the debug variable referenced by
/// this DBG_VALUE instruction.
- DIVariable getDebugVariable() const {
+ const DILocalVariable *getDebugVariable() const {
assert(isDebugValue() && "not a DBG_VALUE");
- const MDNode *Var = getOperand(getNumOperands() - 1).getMetadata();
- return DIVariable(Var);
+ return cast<DILocalVariable>(getOperand(2).getMetadata());
+ }
+
+ /// \brief Return the complex address expression referenced by
+ /// this DBG_VALUE instruction.
+ const DIExpression *getDebugExpression() const {
+ assert(isDebugValue() && "not a DBG_VALUE");
+ return cast<DIExpression>(getOperand(3).getMetadata());
}
/// emitError - Emit an error referring to the source location of this
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; }
return hasProperty(MCID::FoldableAsLoad, Type);
}
+ /// \brief Return true if this instruction behaves
+ /// the same way as the generic REG_SEQUENCE instructions.
+ /// E.g., on ARM,
+ /// dX VMOVDRR rY, rZ
+ /// is equivalent to
+ /// dX = REG_SEQUENCE rY, ssub_0, rZ, ssub_1.
+ ///
+ /// Note that for the optimizers to be able to take advantage of
+ /// this property, TargetInstrInfo::getRegSequenceLikeInputs has to be
+ /// override accordingly.
+ bool isRegSequenceLike(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::RegSequence, Type);
+ }
+
+ /// \brief Return true if this instruction behaves
+ /// the same way as the generic EXTRACT_SUBREG instructions.
+ /// E.g., on ARM,
+ /// rX, rY VMOVRRD dZ
+ /// is equivalent to two EXTRACT_SUBREG:
+ /// rX = EXTRACT_SUBREG dZ, ssub_0
+ /// rY = EXTRACT_SUBREG dZ, ssub_1
+ ///
+ /// Note that for the optimizers to be able to take advantage of
+ /// this property, TargetInstrInfo::getExtractSubregLikeInputs has to be
+ /// override accordingly.
+ bool isExtractSubregLike(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::ExtractSubreg, Type);
+ }
+
+ /// \brief Return true if this instruction behaves
+ /// the same way as the generic INSERT_SUBREG instructions.
+ /// E.g., on ARM,
+ /// dX = VSETLNi32 dY, rZ, Imm
+ /// is equivalent to a INSERT_SUBREG:
+ /// dX = INSERT_SUBREG dY, rZ, translateImmToSubIdx(Imm)
+ ///
+ /// Note that for the optimizers to be able to take advantage of
+ /// this property, TargetInstrInfo::getInsertSubregLikeInputs has to be
+ /// override accordingly.
+ bool isInsertSubregLike(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::InsertSubreg, Type);
+ }
+
//===--------------------------------------------------------------------===//
// Side Effect Analysis
//===--------------------------------------------------------------------===//
/// are not marking copies from and to the same register class with this flag.
bool isAsCheapAsAMove(QueryType Type = AllInBundle) const {
// Only returns true for a bundle if all bundled instructions are cheap.
- // FIXME: This probably requires a target hook.
return hasProperty(MCID::CheapAsAMove, Type);
}
/// eraseFromBundle() to erase individual bundled instructions.
void eraseFromParent();
+ /// Unlink 'this' from the containing basic block and delete it.
+ ///
+ /// For all definitions mark their uses in DBG_VALUE nodes
+ /// as undefined. Otherwise like eraseFromParent().
+ void eraseFromParentAndMarkDBGValuesForRemoval();
+
/// Unlink 'this' form its basic block and delete it.
///
/// If the instruction is part of a bundle, the other instructions in the
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.
/// 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;
}
/// 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;
}
/// 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;
}
/// 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;
}
/// 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
/// 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
/// 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
/// 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;
}
/// 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;
bool addRegisterDead(unsigned Reg, const TargetRegisterInfo *RegInfo,
bool AddIfNotFound = false);
+ /// Clear all dead flags on operands defining register @p Reg.
+ void clearRegisterDeads(unsigned Reg);
+
+ /// Mark all subregister defs of register @p Reg with the undef flag.
+ /// This function is used when we determined to have a subregister def in an
+ /// otherwise undefined super register.
+ void addRegisterDefReadUndef(unsigned Reg);
+
/// 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.
//
// Debugging support
//
- void print(raw_ostream &OS, const TargetMachine *TM = 0,
- bool SkipOpers = false) const;
+ void print(raw_ostream &OS, bool SkipOpers = false) const;
void dump() const;
//===--------------------------------------------------------------------===//
/// setDebugLoc - Replace current source information with new such.
/// Avoid using this, the constructor argument is preferable.
///
- void setDebugLoc(const DebugLoc dl) { debugLoc = dl; }
+ void setDebugLoc(DebugLoc dl) {
+ debugLoc = std::move(dl);
+ assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
+ }
/// RemoveOperand - Erase an operand from an instruction, leaving it with one
/// fewer operand than it started with.
assert(NumMemRefs == NewMemRefsEnd - NewMemRefs && "Too many memrefs");
}
+ /// clearMemRefs - Clear this MachineInstr's memory reference descriptor list.
+ void clearMemRefs() {
+ MemRefs = nullptr;
+ NumMemRefs = 0;
+ }
+
private:
/// getRegInfo - If this instruction is embedded into a MachineFunction,
/// return the MachineRegisterInfo object for the current function, otherwise
/// useful for CSE, etc.
struct MachineInstrExpressionTrait : DenseMapInfo<MachineInstr*> {
static inline MachineInstr *getEmptyKey() {
- return 0;
+ return nullptr;
}
static inline MachineInstr *getTombstoneKey() {