Update prebuilt Clang to r416183b from Android.
https://android.googlesource.com/platform/prebuilts/clang/host/
linux-x86/+/06a71ddac05c22edb2d10b590e1769b3f8619bef
clang 12.0.5 (based on r416183b) from build 7284624.
Change-Id: I277a316abcf47307562d8b748b84870f31a72866
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/linux-x64/clang/include/llvm/CodeGen/MachineInstr.h b/linux-x64/clang/include/llvm/CodeGen/MachineInstr.h
index c82c5b1..6bbe2d0 100644
--- a/linux-x64/clang/include/llvm/CodeGen/MachineInstr.h
+++ b/linux-x64/clang/include/llvm/CodeGen/MachineInstr.h
@@ -20,11 +20,9 @@
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/TargetOpcodes.h"
-#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/MC/MCInstrDesc.h"
@@ -38,12 +36,12 @@
namespace llvm {
+class AAResults;
template <typename T> class ArrayRef;
class DIExpression;
class DILocalVariable;
class MachineBasicBlock;
class MachineFunction;
-class MachineMemOperand;
class MachineRegisterInfo;
class ModuleSlotTracker;
class raw_ostream;
@@ -105,8 +103,11 @@
// no signed wrap.
IsExact = 1 << 13, // Instruction supports division is
// known to be exact.
- FPExcept = 1 << 14, // Instruction may raise floating-point
- // exceptions.
+ NoFPExcept = 1 << 14, // Instruction does not raise
+ // floatint-point exceptions.
+ NoMerge = 1 << 15, // Passes that drop source location info
+ // (e.g. branch folding) should skip
+ // this instruction.
};
private:
@@ -116,8 +117,6 @@
// Operands are allocated by an ArrayRecycler.
MachineOperand *Operands = nullptr; // Pointer to the first operand.
unsigned NumOperands = 0; // Number of operands on instruction.
- using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
- OperandCapacity CapOperands; // Capacity of the Operands array.
uint16_t Flags = 0; // Various bits of additional
// information about machine
@@ -130,6 +129,11 @@
// anything other than to convey comment
// information to AsmPrinter.
+ // OperandCapacity has uint8_t size, so it should be next to AsmPrinterFlags
+ // to properly pack.
+ using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
+ OperandCapacity CapOperands; // Capacity of the Operands array.
+
/// Internal implementation detail class that provides out-of-line storage for
/// extra info used by the machine instruction when this info cannot be stored
/// in-line within the instruction itself.
@@ -137,19 +141,23 @@
/// This has to be defined eagerly due to the implementation constraints of
/// `PointerSumType` where it is used.
class ExtraInfo final
- : TrailingObjects<ExtraInfo, MachineMemOperand *, MCSymbol *> {
+ : TrailingObjects<ExtraInfo, MachineMemOperand *, MCSymbol *, MDNode *> {
public:
static ExtraInfo *create(BumpPtrAllocator &Allocator,
ArrayRef<MachineMemOperand *> MMOs,
MCSymbol *PreInstrSymbol = nullptr,
- MCSymbol *PostInstrSymbol = nullptr) {
+ MCSymbol *PostInstrSymbol = nullptr,
+ MDNode *HeapAllocMarker = nullptr) {
bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
+ bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
auto *Result = new (Allocator.Allocate(
- totalSizeToAlloc<MachineMemOperand *, MCSymbol *>(
- MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol),
+ totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *>(
+ MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol,
+ HasHeapAllocMarker),
alignof(ExtraInfo)))
- ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol);
+ ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol,
+ HasHeapAllocMarker);
// Copy the actual data into the trailing objects.
std::copy(MMOs.begin(), MMOs.end(),
@@ -160,6 +168,8 @@
if (HasPostInstrSymbol)
Result->getTrailingObjects<MCSymbol *>()[HasPreInstrSymbol] =
PostInstrSymbol;
+ if (HasHeapAllocMarker)
+ Result->getTrailingObjects<MDNode *>()[0] = HeapAllocMarker;
return Result;
}
@@ -178,6 +188,10 @@
: nullptr;
}
+ MDNode *getHeapAllocMarker() const {
+ return HasHeapAllocMarker ? getTrailingObjects<MDNode *>()[0] : nullptr;
+ }
+
private:
friend TrailingObjects;
@@ -189,6 +203,7 @@
const int NumMMOs;
const bool HasPreInstrSymbol;
const bool HasPostInstrSymbol;
+ const bool HasHeapAllocMarker;
// Implement the `TrailingObjects` internal API.
size_t numTrailingObjects(OverloadToken<MachineMemOperand *>) const {
@@ -197,12 +212,17 @@
size_t numTrailingObjects(OverloadToken<MCSymbol *>) const {
return HasPreInstrSymbol + HasPostInstrSymbol;
}
+ size_t numTrailingObjects(OverloadToken<MDNode *>) const {
+ return HasHeapAllocMarker;
+ }
// Just a boring constructor to allow us to initialize the sizes. Always use
// the `create` routine above.
- ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol)
+ ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol,
+ bool HasHeapAllocMarker)
: NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol),
- HasPostInstrSymbol(HasPostInstrSymbol) {}
+ HasPostInstrSymbol(HasPostInstrSymbol),
+ HasHeapAllocMarker(HasHeapAllocMarker) {}
};
/// Enumeration of the kinds of inline extra info available. It is important
@@ -229,6 +249,10 @@
DebugLoc debugLoc; // Source line information.
+ /// Unique instruction number. Used by DBG_INSTR_REFs to refer to the values
+ /// defined by this instruction.
+ unsigned DebugInstrNum;
+
// Intrusive list support
friend struct ilist_traits<MachineInstr>;
friend struct ilist_callback_traits<MachineBasicBlock>;
@@ -247,6 +271,10 @@
// MachineInstrs are pool-allocated and owned by MachineFunction.
friend class MachineFunction;
+ void
+ dumprImpl(const MachineRegisterInfo &MRI, unsigned Depth, unsigned MaxDepth,
+ SmallPtrSetImpl<const MachineInstr *> &AlreadySeenInstrs) const;
+
public:
MachineInstr(const MachineInstr &) = delete;
MachineInstr &operator=(const MachineInstr &) = delete;
@@ -256,6 +284,9 @@
const MachineBasicBlock* getParent() const { return Parent; }
MachineBasicBlock* getParent() { return Parent; }
+ /// Move the instruction before \p MovePos.
+ void moveBefore(MachineInstr *MovePos);
+
/// Return the function that contains the basic block that this instruction
/// belongs to.
///
@@ -384,10 +415,31 @@
/// Returns the debug location id of this MachineInstr.
const DebugLoc &getDebugLoc() const { return debugLoc; }
+ /// Return the operand containing the offset to be used if this DBG_VALUE
+ /// instruction is indirect; will be an invalid register if this value is
+ /// not indirect, and an immediate with value 0 otherwise.
+ const MachineOperand &getDebugOffset() const {
+ assert(isDebugValue() && "not a DBG_VALUE");
+ return getOperand(1);
+ }
+ MachineOperand &getDebugOffset() {
+ assert(isDebugValue() && "not a DBG_VALUE");
+ return getOperand(1);
+ }
+
+ /// Return the operand for the debug variable referenced by
+ /// this DBG_VALUE instruction.
+ const MachineOperand &getDebugVariableOp() const;
+ MachineOperand &getDebugVariableOp();
+
/// Return the debug variable referenced by
/// this DBG_VALUE instruction.
const DILocalVariable *getDebugVariable() const;
+ /// Return the operand for the complex address expression referenced by
+ /// this DBG_VALUE instruction.
+ MachineOperand &getDebugExpressionOp();
+
/// Return the complex address expression referenced by
/// this DBG_VALUE instruction.
const DIExpression *getDebugExpression() const;
@@ -396,6 +448,18 @@
/// this DBG_LABEL instruction.
const DILabel *getDebugLabel() const;
+ /// Fetch the instruction number of this MachineInstr. If it does not have
+ /// one already, a new and unique number will be assigned.
+ unsigned getDebugInstrNum();
+
+ /// Examine the instruction number of this MachineInstr. May be zero if
+ /// it hasn't been assigned a number yet.
+ unsigned peekDebugInstrNum() const { return DebugInstrNum; }
+
+ /// Set instruction number of this MachineInstr. Avoid using unless you're
+ /// deserializing this information.
+ void setDebugInstrNum(unsigned Num) { DebugInstrNum = Num; }
+
/// 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
@@ -413,6 +477,11 @@
/// Retuns the total number of operands.
unsigned getNumOperands() const { return NumOperands; }
+ /// Returns the total number of operands which are debug locations.
+ unsigned getNumDebugOperands() const {
+ return std::distance(debug_operands().begin(), debug_operands().end());
+ }
+
const MachineOperand& getOperand(unsigned i) const {
assert(i < getNumOperands() && "getOperand() out of range!");
return Operands[i];
@@ -422,11 +491,59 @@
return Operands[i];
}
+ MachineOperand &getDebugOperand(unsigned Index) {
+ assert(Index < getNumDebugOperands() && "getDebugOperand() out of range!");
+ return *(debug_operands().begin() + Index);
+ }
+ const MachineOperand &getDebugOperand(unsigned Index) const {
+ assert(Index < getNumDebugOperands() && "getDebugOperand() out of range!");
+ return *(debug_operands().begin() + Index);
+ }
+
+ /// Returns a pointer to the operand corresponding to a debug use of Reg, or
+ /// nullptr if Reg is not used in any debug operand.
+ const MachineOperand *getDebugOperandForReg(Register Reg) const {
+ const MachineOperand *RegOp =
+ find_if(debug_operands(), [Reg](const MachineOperand &Op) {
+ return Op.isReg() && Op.getReg() == Reg;
+ });
+ return RegOp == adl_end(debug_operands()) ? nullptr : RegOp;
+ }
+ MachineOperand *getDebugOperandForReg(Register Reg) {
+ MachineOperand *RegOp =
+ find_if(debug_operands(), [Reg](const MachineOperand &Op) {
+ return Op.isReg() && Op.getReg() == Reg;
+ });
+ return RegOp == adl_end(debug_operands()) ? nullptr : RegOp;
+ }
+
+ unsigned getDebugOperandIndex(const MachineOperand *Op) const {
+ assert(Op >= adl_begin(debug_operands()) &&
+ Op <= adl_end(debug_operands()) && "Expected a debug operand.");
+ return std::distance(adl_begin(debug_operands()), Op);
+ }
+
/// Returns the total number of definitions.
unsigned getNumDefs() const {
return getNumExplicitDefs() + MCID->getNumImplicitDefs();
}
+ /// Returns true if the instruction has implicit definition.
+ bool hasImplicitDef() const {
+ for (unsigned I = getNumExplicitOperands(), E = getNumOperands();
+ I != E; ++I) {
+ const MachineOperand &MO = getOperand(I);
+ if (MO.isDef() && MO.isImplicit())
+ return true;
+ }
+ return false;
+ }
+
+ /// Returns the implicit operands number.
+ unsigned getNumImplicitOperands() const {
+ return getNumOperands() - getNumExplicitOperands();
+ }
+
/// Return true if operand \p OpIdx is a subregister index.
bool isOperandSubregIdx(unsigned OpIdx) const {
assert(getOperand(OpIdx).getType() == MachineOperand::MO_Immediate &&
@@ -478,6 +595,17 @@
iterator_range<const_mop_iterator> implicit_operands() const {
return make_range(explicit_operands().end(), operands_end());
}
+ /// Returns a range over all operands that are used to determine the variable
+ /// location for this DBG_VALUE instruction.
+ iterator_range<mop_iterator> debug_operands() {
+ assert(isDebugValue() && "Must be a debug value instruction.");
+ return make_range(operands_begin(), operands_begin() + 1);
+ }
+ /// \copydoc debug_operands()
+ iterator_range<const_mop_iterator> debug_operands() const {
+ assert(isDebugValue() && "Must be a debug value instruction.");
+ return make_range(operands_begin(), operands_begin() + 1);
+ }
/// Returns a range over all explicit operands that are register definitions.
/// Implicit definition are not included!
iterator_range<mop_iterator> defs() {
@@ -577,6 +705,16 @@
return nullptr;
}
+ /// Helper to extract a heap alloc marker if one has been added.
+ MDNode *getHeapAllocMarker() const {
+ if (!Info)
+ return nullptr;
+ if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
+ return EI->getHeapAllocMarker();
+
+ return nullptr;
+ }
+
/// API for querying MachineInstr properties. They are the same as MCInstrDesc
/// queries but they are bundle aware.
@@ -602,6 +740,12 @@
return hasPropertyInBundle(1ULL << MCFlag, Type);
}
+ /// Return true if this is an instruction that should go through the usual
+ /// legalization steps.
+ bool isPreISelOpcode(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::PreISelOpcode, Type);
+ }
+
/// Return true if this instruction can have a variable number of operands.
/// In this case, the variable operands will be after the normal
/// operands but before the implicit definitions and uses (if any are
@@ -636,6 +780,14 @@
return hasProperty(MCID::Call, Type);
}
+ /// Return true if this is a call instruction that may have an associated
+ /// call site entry in the debug info.
+ bool isCandidateForCallSiteEntry(QueryType Type = IgnoreBundle) const;
+ /// Return true if copying, moving, or erasing this instruction requires
+ /// updating Call Site Info (see \ref copyCallSiteInfo, \ref moveCallSiteInfo,
+ /// \ref eraseCallSiteInfo).
+ bool shouldUpdateCallSiteInfo() const;
+
/// Returns true if the specified instruction stops control flow
/// from executing the instruction immediately following it. Examples include
/// unconditional branches and return instructions.
@@ -654,7 +806,7 @@
/// Returns true if this is a conditional, unconditional, or indirect branch.
/// Predicates below can be used to discriminate between
- /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
+ /// these cases, and the TargetInstrInfo::analyzeBranch method can be used to
/// get more information.
bool isBranch(QueryType Type = AnyInBundle) const {
return hasProperty(MCID::Branch, Type);
@@ -668,18 +820,18 @@
/// Return true if this is a branch which may fall
/// through to the next instruction or may transfer control flow to some other
- /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more
+ /// block. The TargetInstrInfo::analyzeBranch method can be used to get more
/// information about this branch.
bool isConditionalBranch(QueryType Type = AnyInBundle) const {
- return isBranch(Type) & !isBarrier(Type) & !isIndirectBranch(Type);
+ return isBranch(Type) && !isBarrier(Type) && !isIndirectBranch(Type);
}
/// Return true if this is a branch which always
/// transfers control flow to some other block. The
- /// TargetInstrInfo::AnalyzeBranch method can be used to get more information
+ /// TargetInstrInfo::analyzeBranch method can be used to get more information
/// about this branch.
bool isUnconditionalBranch(QueryType Type = AnyInBundle) const {
- return isBranch(Type) & isBarrier(Type) & !isIndirectBranch(Type);
+ return isBranch(Type) && isBarrier(Type) && !isIndirectBranch(Type);
}
/// Return true if this instruction has a predicate operand that
@@ -838,10 +990,10 @@
/// instruction that can in principle raise an exception, as indicated
/// by the MCID::MayRaiseFPException property, *and* at the same time,
/// the instruction is used in a context where we expect floating-point
- /// exceptions might be enabled, as indicated by the FPExcept MI flag.
+ /// exceptions are not disabled, as indicated by the NoFPExcept MI flag.
bool mayRaiseFPException() const {
return hasProperty(MCID::MayRaiseFPException) &&
- getFlag(MachineInstr::MIFlag::FPExcept);
+ !getFlag(MachineInstr::MIFlag::NoFPExcept);
}
//===--------------------------------------------------------------------===//
@@ -1009,26 +1161,28 @@
bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; }
- bool isDebugInstr() const { return isDebugValue() || isDebugLabel(); }
+ bool isDebugRef() const { return getOpcode() == TargetOpcode::DBG_INSTR_REF; }
+ bool isDebugInstr() const {
+ return isDebugValue() || isDebugLabel() || isDebugRef();
+ }
- /// A DBG_VALUE is indirect iff the first operand is a register and
- /// the second operand is an immediate.
+ bool isDebugOffsetImm() const { return getDebugOffset().isImm(); }
+
+ /// A DBG_VALUE is indirect iff the location operand is a register and
+ /// the offset operand is an immediate.
bool isIndirectDebugValue() const {
- return isDebugValue()
- && getOperand(0).isReg()
- && getOperand(1).isImm();
+ return isDebugValue() && getDebugOperand(0).isReg() && isDebugOffsetImm();
}
/// A DBG_VALUE is an entry value iff its debug expression contains the
- /// DW_OP_entry_value DWARF operation.
- bool isDebugEntryValue() const {
- return isDebugValue() && getDebugExpression()->isEntryValue();
- }
+ /// DW_OP_LLVM_entry_value operation.
+ bool isDebugEntryValue() const;
/// Return true if the instruction is a debug value which describes a part of
/// a variable as unavailable.
bool isUndefDebugValue() const {
- return isDebugValue() && getOperand(0).isReg() && !getOperand(0).getReg();
+ return isDebugValue() && getDebugOperand(0).isReg() &&
+ !getDebugOperand(0).getReg().isValid();
}
bool isPHI() const {
@@ -1103,9 +1257,11 @@
case TargetOpcode::EH_LABEL:
case TargetOpcode::GC_LABEL:
case TargetOpcode::DBG_VALUE:
+ case TargetOpcode::DBG_INSTR_REF:
case TargetOpcode::DBG_LABEL:
case TargetOpcode::LIFETIME_START:
case TargetOpcode::LIFETIME_END:
+ case TargetOpcode::PSEUDO_PROBE:
return true;
}
}
@@ -1140,7 +1296,7 @@
/// 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,
+ bool readsRegister(Register Reg,
const TargetRegisterInfo *TRI = nullptr) const {
return findRegisterUseOperandIdx(Reg, false, TRI) != -1;
}
@@ -1148,20 +1304,20 @@
/// Return true if the MachineInstr reads the specified virtual register.
/// Take into account that a partial define is a
/// read-modify-write operation.
- bool readsVirtualRegister(unsigned Reg) const {
+ bool readsVirtualRegister(Register Reg) const {
return readsWritesVirtualRegister(Reg).first;
}
/// Return a pair of bools (reads, writes) indicating if this instruction
/// reads or writes Reg. This also considers partial defines.
/// If Ops is not null, all operand indices for Reg are added.
- std::pair<bool,bool> readsWritesVirtualRegister(unsigned Reg,
+ std::pair<bool,bool> readsWritesVirtualRegister(Register Reg,
SmallVectorImpl<unsigned> *Ops = nullptr) const;
/// 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,
+ bool killsRegister(Register Reg,
const TargetRegisterInfo *TRI = nullptr) const {
return findRegisterUseOperandIdx(Reg, true, TRI) != -1;
}
@@ -1170,7 +1326,7 @@
/// 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,
+ bool definesRegister(Register Reg,
const TargetRegisterInfo *TRI = nullptr) const {
return findRegisterDefOperandIdx(Reg, false, false, TRI) != -1;
}
@@ -1178,38 +1334,39 @@
/// Return true if the MachineInstr modifies (fully define or partially
/// define) the specified register.
/// NOTE: It's ignoring subreg indices on virtual registers.
- bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const {
+ bool modifiesRegister(Register Reg,
+ const TargetRegisterInfo *TRI = nullptr) const {
return findRegisterDefOperandIdx(Reg, false, true, TRI) != -1;
}
/// Returns true if the register is dead in this machine instruction.
/// If TargetRegisterInfo is passed, then it also checks
/// if there is a dead def of a super-register.
- bool registerDefIsDead(unsigned Reg,
+ bool registerDefIsDead(Register Reg,
const TargetRegisterInfo *TRI = nullptr) const {
return findRegisterDefOperandIdx(Reg, true, false, TRI) != -1;
}
/// Returns true if the MachineInstr has an implicit-use operand of exactly
/// the given register (not considering sub/super-registers).
- bool hasRegisterImplicitUseOperand(unsigned Reg) const;
+ bool hasRegisterImplicitUseOperand(Register Reg) const;
/// Returns the operand index that is a use of 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,
+ int findRegisterUseOperandIdx(Register Reg, bool isKill = false,
const TargetRegisterInfo *TRI = nullptr) const;
/// Wrapper for findRegisterUseOperandIdx, it returns
/// a pointer to the MachineOperand rather than an index.
- MachineOperand *findRegisterUseOperand(unsigned Reg, bool isKill = false,
+ MachineOperand *findRegisterUseOperand(Register Reg, bool isKill = false,
const TargetRegisterInfo *TRI = nullptr) {
int Idx = findRegisterUseOperandIdx(Reg, isKill, TRI);
return (Idx == -1) ? nullptr : &getOperand(Idx);
}
const MachineOperand *findRegisterUseOperand(
- unsigned Reg, bool isKill = false,
+ Register Reg, bool isKill = false,
const TargetRegisterInfo *TRI = nullptr) const {
return const_cast<MachineInstr *>(this)->
findRegisterUseOperand(Reg, isKill, TRI);
@@ -1221,14 +1378,14 @@
/// overlap the specified register. If TargetRegisterInfo is non-null,
/// then it also checks if there is a def of a super-register.
/// This may also return a register mask operand when Overlap is true.
- int findRegisterDefOperandIdx(unsigned Reg,
+ int findRegisterDefOperandIdx(Register Reg,
bool isDead = false, bool Overlap = false,
const TargetRegisterInfo *TRI = nullptr) const;
/// Wrapper for findRegisterDefOperandIdx, it returns
/// a pointer to the MachineOperand rather than an index.
MachineOperand *
- findRegisterDefOperand(unsigned Reg, bool isDead = false,
+ findRegisterDefOperand(Register Reg, bool isDead = false,
bool Overlap = false,
const TargetRegisterInfo *TRI = nullptr) {
int Idx = findRegisterDefOperandIdx(Reg, isDead, Overlap, TRI);
@@ -1236,7 +1393,7 @@
}
const MachineOperand *
- findRegisterDefOperand(unsigned Reg, bool isDead = false,
+ findRegisterDefOperand(Register Reg, bool isDead = false,
bool Overlap = false,
const TargetRegisterInfo *TRI = nullptr) const {
return const_cast<MachineInstr *>(this)->findRegisterDefOperand(
@@ -1283,7 +1440,7 @@
///
/// \pre CurRC must not be NULL.
const TargetRegisterClass *getRegClassConstraintEffectForVReg(
- unsigned Reg, const TargetRegisterClass *CurRC,
+ Register Reg, const TargetRegisterClass *CurRC,
const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
bool ExploreBundle = false) const;
@@ -1346,39 +1503,39 @@
/// Replace all occurrences of FromReg with ToReg:SubIdx,
/// properly composing subreg indices where necessary.
- void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx,
+ void substituteRegister(Register FromReg, Register ToReg, unsigned SubIdx,
const TargetRegisterInfo &RegInfo);
/// We have determined MI kills a register. Look for the
/// operand that uses it and mark it as IsKill. If AddIfNotFound is true,
/// add a implicit operand if it's not found. Returns true if the operand
/// exists / is added.
- bool addRegisterKilled(unsigned IncomingReg,
+ bool addRegisterKilled(Register IncomingReg,
const TargetRegisterInfo *RegInfo,
bool AddIfNotFound = false);
/// Clear all kill flags affecting Reg. If RegInfo is provided, this includes
/// all aliasing registers.
- void clearRegisterKills(unsigned Reg, const TargetRegisterInfo *RegInfo);
+ void clearRegisterKills(Register Reg, const TargetRegisterInfo *RegInfo);
/// We have determined MI defined a register without a use.
/// Look for the operand that defines it and mark it as IsDead. If
/// AddIfNotFound is true, add a implicit operand if it's not found. Returns
/// true if the operand exists / is added.
- bool addRegisterDead(unsigned Reg, const TargetRegisterInfo *RegInfo,
+ bool addRegisterDead(Register Reg, const TargetRegisterInfo *RegInfo,
bool AddIfNotFound = false);
/// Clear all dead flags on operands defining register @p Reg.
- void clearRegisterDeads(unsigned Reg);
+ void clearRegisterDeads(Register 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 setRegisterDefReadUndef(unsigned Reg, bool IsUndef = true);
+ void setRegisterDefReadUndef(Register Reg, bool IsUndef = true);
/// We have determined MI defines a register. Make sure there is an operand
/// defining Reg.
- void addRegisterDefined(unsigned Reg,
+ void addRegisterDefined(Register Reg,
const TargetRegisterInfo *RegInfo = nullptr);
/// Mark every physreg used by this instruction as
@@ -1386,13 +1543,13 @@
///
/// On instructions with register mask operands, also add implicit-def
/// operands for all registers in UsedRegs.
- void setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs,
+ void setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs,
const TargetRegisterInfo &TRI);
/// Return true if it is safe to move this instruction. If
/// SawStore is set to true, it means that there is a store (or call) between
/// the instruction's location and its intended destination.
- bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const;
+ bool isSafeToMove(AAResults *AA, bool &SawStore) const;
/// Returns true if this instruction's memory access aliases the memory
/// access of Other.
@@ -1404,7 +1561,7 @@
/// @param AA Optional alias analysis, used to compare memory operands.
/// @param Other MachineInstr to check aliasing against.
/// @param UseTBAA Whether to pass TBAA information to alias analysis.
- bool mayAlias(AliasAnalysis *AA, const MachineInstr &Other, bool UseTBAA) const;
+ bool mayAlias(AAResults *AA, const MachineInstr &Other, bool UseTBAA) const;
/// Return true if this instruction may have an ordered
/// or volatile memory reference, or if the information describing the memory
@@ -1419,7 +1576,7 @@
/// argument area of a function (if it does not change). If the instruction
/// does multiple loads, this returns true only if all of the loads are
/// dereferenceable and invariant.
- bool isDereferenceableInvariantLoad(AliasAnalysis *AA) const;
+ bool isDereferenceableInvariantLoad(AAResults *AA) const;
/// If the specified instruction is a PHI that always merges together the
/// same virtual register, return the register, otherwise return 0.
@@ -1485,6 +1642,10 @@
bool AddNewLine = true,
const TargetInstrInfo *TII = nullptr) const;
void dump() const;
+ /// Print on dbgs() the current instruction and the instructions defining its
+ /// operands and so on until we reach \p MaxDepth.
+ void dumpr(const MachineRegisterInfo &MRI,
+ unsigned MaxDepth = UINT_MAX) const;
/// @}
//===--------------------------------------------------------------------===//
@@ -1578,6 +1739,12 @@
/// replace ours with it.
void cloneInstrSymbols(MachineFunction &MF, const MachineInstr &MI);
+ /// Set a marker on instructions that denotes where we should create and emit
+ /// heap alloc site labels. This waits until after instruction selection and
+ /// optimizations to create the label, so it should still work if the
+ /// instruction is removed or duplicated.
+ void setHeapAllocMarker(MachineFunction &MF, MDNode *MD);
+
/// Return the MIFlags which represent both MachineInstrs. This
/// should be used when merging two MachineInstrs into one. This routine does
/// not modify the MIFlags of this MachineInstr.
@@ -1600,12 +1767,31 @@
/// Add all implicit def and use operands to this instruction.
void addImplicitDefUseOperands(MachineFunction &MF);
- /// Scan instructions following MI and collect any matching DBG_VALUEs.
+ /// Scan instructions immediately following MI and collect any matching
+ /// DBG_VALUEs.
void collectDebugValues(SmallVectorImpl<MachineInstr *> &DbgValues);
- /// Find all DBG_VALUEs immediately following this instruction that point
- /// to a register def in this instruction and point them to \p Reg instead.
- void changeDebugValuesDefReg(unsigned Reg);
+ /// Find all DBG_VALUEs that point to the register def in this instruction
+ /// and point them to \p Reg instead.
+ void changeDebugValuesDefReg(Register Reg);
+
+ /// Returns the Intrinsic::ID for this instruction.
+ /// \pre Must have an intrinsic ID operand.
+ unsigned getIntrinsicID() const {
+ return getOperand(getNumExplicitDefs()).getIntrinsicID();
+ }
+
+ /// Sets all register debug operands in this debug value instruction to be
+ /// undef.
+ void setDebugValueUndef() {
+ assert(isDebugValue() && "Must be a debug value instruction.");
+ for (MachineOperand &MO : debug_operands()) {
+ if (MO.isReg()) {
+ MO.setReg(0);
+ MO.setSubReg(0);
+ }
+ }
+ }
private:
/// If this instruction is embedded into a MachineFunction, return the
@@ -1630,8 +1816,14 @@
/// 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,
+ unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const;
+
+ /// Stores extra instruction information inline or allocates as ExtraInfo
+ /// based on the number of pointers.
+ void setExtraInfo(MachineFunction &MF, ArrayRef<MachineMemOperand *> MMOs,
+ MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol,
+ MDNode *HeapAllocMarker);
};
/// Special DenseMapInfo traits to compare MachineInstr* by *value* of the