summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineInstr.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/CodeGen/MachineInstr.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/lib/CodeGen/MachineInstr.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineInstr.cpp171
1 files changed, 133 insertions, 38 deletions
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 59d98054e3a2..0707945e7fb7 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -841,28 +841,35 @@ const DILabel *MachineInstr::getDebugLabel() const {
}
const MachineOperand &MachineInstr::getDebugVariableOp() const {
- assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
- return getOperand(2);
+ assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*");
+ unsigned VariableOp = isDebugValueList() ? 0 : 2;
+ return getOperand(VariableOp);
}
MachineOperand &MachineInstr::getDebugVariableOp() {
- assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
- return getOperand(2);
+ assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*");
+ unsigned VariableOp = isDebugValueList() ? 0 : 2;
+ return getOperand(VariableOp);
}
const DILocalVariable *MachineInstr::getDebugVariable() const {
- assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
- return cast<DILocalVariable>(getOperand(2).getMetadata());
+ return cast<DILocalVariable>(getDebugVariableOp().getMetadata());
+}
+
+const MachineOperand &MachineInstr::getDebugExpressionOp() const {
+ assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*");
+ unsigned ExpressionOp = isDebugValueList() ? 1 : 3;
+ return getOperand(ExpressionOp);
}
MachineOperand &MachineInstr::getDebugExpressionOp() {
- assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
- return getOperand(3);
+ assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*");
+ unsigned ExpressionOp = isDebugValueList() ? 1 : 3;
+ return getOperand(ExpressionOp);
}
const DIExpression *MachineInstr::getDebugExpression() const {
- assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE");
- return cast<DIExpression>(getOperand(3).getMetadata());
+ return cast<DIExpression>(getDebugExpressionOp().getMetadata());
}
bool MachineInstr::isDebugEntryValue() const {
@@ -1312,12 +1319,10 @@ static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA,
int64_t OverlapB =
KnownWidthB ? WidthB + OffsetB - MinOffset : MemoryLocation::UnknownSize;
- AliasResult AAResult = AA->alias(
+ return !AA->isNoAlias(
MemoryLocation(ValA, OverlapA, UseTBAA ? MMOa->getAAInfo() : AAMDNodes()),
MemoryLocation(ValB, OverlapB,
UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));
-
- return (AAResult != NoAlias);
}
bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
@@ -1462,7 +1467,8 @@ bool MachineInstr::hasUnmodeledSideEffects() const {
}
bool MachineInstr::isLoadFoldBarrier() const {
- return mayStore() || isCall() || hasUnmodeledSideEffects();
+ return mayStore() || isCall() ||
+ (hasUnmodeledSideEffects() && !isPseudoProbe());
}
/// allDefsAreDead - Return true if all the defs of this instruction are dead.
@@ -1711,7 +1717,7 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
OS << " ";
if (isDebugValue() && MO.isMetadata()) {
- // Pretty print DBG_VALUE instructions.
+ // Pretty print DBG_VALUE* instructions.
auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata());
if (DIV && !DIV->getName().empty())
OS << "!\"" << DIV->getName() << '\"';
@@ -2056,9 +2062,8 @@ void MachineInstr::setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs,
// This is a call with a register mask operand.
// Mask clobbers are always dead, so add defs for the non-dead defines.
if (HasRegMask)
- for (ArrayRef<Register>::iterator I = UsedRegs.begin(), E = UsedRegs.end();
- I != E; ++I)
- addRegisterDefined(*I, &TRI);
+ for (const Register &UsedReg : UsedRegs)
+ addRegisterDefined(UsedReg, &TRI);
}
unsigned
@@ -2078,7 +2083,7 @@ MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) {
void MachineInstr::emitError(StringRef Msg) const {
// Find the source location cookie.
- unsigned LocCookie = 0;
+ uint64_t LocCookie = 0;
const MDNode *LocMD = nullptr;
for (unsigned i = getNumOperands(); i != 0; --i) {
if (getOperand(i-1).isMetadata() &&
@@ -2116,8 +2121,8 @@ MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
const MCInstrDesc &MCID, bool IsIndirect,
- MachineOperand &MO, const MDNode *Variable,
- const MDNode *Expr) {
+ const MachineOperand &MO,
+ const MDNode *Variable, const MDNode *Expr) {
assert(isa<DILocalVariable>(Variable) && "not a variable");
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
@@ -2131,7 +2136,28 @@ MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
else
MIB.addReg(0U, RegState::Debug);
return MIB.addMetadata(Variable).addMetadata(Expr);
- }
+}
+
+MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
+ const MCInstrDesc &MCID, bool IsIndirect,
+ ArrayRef<MachineOperand> MOs,
+ const MDNode *Variable, const MDNode *Expr) {
+ assert(isa<DILocalVariable>(Variable) && "not a variable");
+ assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
+ assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
+ "Expected inlined-at fields to agree");
+ if (MCID.Opcode == TargetOpcode::DBG_VALUE)
+ return BuildMI(MF, DL, MCID, IsIndirect, MOs[0], Variable, Expr);
+
+ auto MIB = BuildMI(MF, DL, MCID);
+ MIB.addMetadata(Variable).addMetadata(Expr);
+ for (const MachineOperand &MO : MOs)
+ if (MO.isReg())
+ MIB.addReg(MO.getReg(), RegState::Debug);
+ else
+ MIB.add(MO);
+ return MIB;
+}
MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
@@ -2155,10 +2181,22 @@ MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
return MachineInstrBuilder(MF, *MI);
}
+MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ const DebugLoc &DL, const MCInstrDesc &MCID,
+ bool IsIndirect, ArrayRef<MachineOperand> MOs,
+ const MDNode *Variable, const MDNode *Expr) {
+ MachineFunction &MF = *BB.getParent();
+ MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, MOs, Variable, Expr);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MF, *MI);
+}
+
/// Compute the new DIExpression to use with a DBG_VALUE for a spill slot.
/// This prepends DW_OP_deref when spilling an indirect DBG_VALUE.
-static const DIExpression *computeExprForSpill(const MachineInstr &MI) {
- assert(MI.getOperand(0).isReg() && "can't spill non-register");
+static const DIExpression *
+computeExprForSpill(const MachineInstr &MI,
+ SmallVectorImpl<const MachineOperand *> &SpilledOperands) {
assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
"Expected inlined-at fields to agree");
@@ -2167,26 +2205,76 @@ static const DIExpression *computeExprForSpill(const MachineInstr &MI) {
assert(MI.getDebugOffset().getImm() == 0 &&
"DBG_VALUE with nonzero offset");
Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore);
+ } else if (MI.isDebugValueList()) {
+ // We will replace the spilled register with a frame index, so
+ // immediately deref all references to the spilled register.
+ std::array<uint64_t, 1> Ops{{dwarf::DW_OP_deref}};
+ for (const MachineOperand *Op : SpilledOperands) {
+ unsigned OpIdx = MI.getDebugOperandIndex(Op);
+ Expr = DIExpression::appendOpsToArg(Expr, Ops, OpIdx);
+ }
}
return Expr;
}
+static const DIExpression *computeExprForSpill(const MachineInstr &MI,
+ Register SpillReg) {
+ assert(MI.hasDebugOperandForReg(SpillReg) && "Spill Reg is not used in MI.");
+ SmallVector<const MachineOperand *> SpillOperands;
+ for (const MachineOperand &Op : MI.getDebugOperandsForReg(SpillReg))
+ SpillOperands.push_back(&Op);
+ return computeExprForSpill(MI, SpillOperands);
+}
MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
const MachineInstr &Orig,
- int FrameIndex) {
- const DIExpression *Expr = computeExprForSpill(Orig);
- return BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc())
- .addFrameIndex(FrameIndex)
- .addImm(0U)
- .addMetadata(Orig.getDebugVariable())
- .addMetadata(Expr);
+ int FrameIndex, Register SpillReg) {
+ const DIExpression *Expr = computeExprForSpill(Orig, SpillReg);
+ MachineInstrBuilder NewMI =
+ BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc());
+ // Non-Variadic Operands: Location, Offset, Variable, Expression
+ // Variadic Operands: Variable, Expression, Locations...
+ if (Orig.isNonListDebugValue())
+ NewMI.addFrameIndex(FrameIndex).addImm(0U);
+ NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr);
+ if (Orig.isDebugValueList()) {
+ for (const MachineOperand &Op : Orig.debug_operands())
+ if (Op.isReg() && Op.getReg() == SpillReg)
+ NewMI.addFrameIndex(FrameIndex);
+ else
+ NewMI.add(MachineOperand(Op));
+ }
+ return NewMI;
+}
+MachineInstr *llvm::buildDbgValueForSpill(
+ MachineBasicBlock &BB, MachineBasicBlock::iterator I,
+ const MachineInstr &Orig, int FrameIndex,
+ SmallVectorImpl<const MachineOperand *> &SpilledOperands) {
+ const DIExpression *Expr = computeExprForSpill(Orig, SpilledOperands);
+ MachineInstrBuilder NewMI =
+ BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc());
+ // Non-Variadic Operands: Location, Offset, Variable, Expression
+ // Variadic Operands: Variable, Expression, Locations...
+ if (Orig.isNonListDebugValue())
+ NewMI.addFrameIndex(FrameIndex).addImm(0U);
+ NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr);
+ if (Orig.isDebugValueList()) {
+ for (const MachineOperand &Op : Orig.debug_operands())
+ if (is_contained(SpilledOperands, &Op))
+ NewMI.addFrameIndex(FrameIndex);
+ else
+ NewMI.add(MachineOperand(Op));
+ }
+ return NewMI;
}
-void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex) {
- const DIExpression *Expr = computeExprForSpill(Orig);
- Orig.getDebugOperand(0).ChangeToFrameIndex(FrameIndex);
- Orig.getDebugOffset().ChangeToImmediate(0U);
+void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex,
+ Register Reg) {
+ const DIExpression *Expr = computeExprForSpill(Orig, Reg);
+ if (Orig.isNonListDebugValue())
+ Orig.getDebugOffset().ChangeToImmediate(0U);
+ for (MachineOperand &Op : Orig.getDebugOperandsForReg(Reg))
+ Op.ChangeToFrameIndex(FrameIndex);
Orig.getDebugExpressionOp().setMetadata(Expr);
}
@@ -2201,7 +2289,7 @@ void MachineInstr::collectDebugValues(
DI != DE; ++DI) {
if (!DI->isDebugValue())
return;
- if (DI->getDebugOperandForReg(MI.getOperand(0).getReg()))
+ if (DI->hasDebugOperandForReg(MI.getOperand(0).getReg()))
DbgValues.push_back(&*DI);
}
}
@@ -2219,14 +2307,15 @@ void MachineInstr::changeDebugValuesDefReg(Register Reg) {
auto *DI = MO.getParent();
if (!DI->isDebugValue())
continue;
- if (DI->getDebugOperandForReg(DefReg)) {
+ if (DI->hasDebugOperandForReg(DefReg)) {
DbgValues.push_back(DI);
}
}
// Propagate Reg to debug value instructions.
for (auto *DBI : DbgValues)
- DBI->getDebugOperandForReg(DefReg)->setReg(Reg);
+ for (MachineOperand &Op : DBI->getDebugOperandsForReg(DefReg))
+ Op.setReg(Reg);
}
using MMOList = SmallVector<const MachineMemOperand *, 2>;
@@ -2285,3 +2374,9 @@ unsigned MachineInstr::getDebugInstrNum() {
DebugInstrNum = getParent()->getParent()->getNewDebugInstrNum();
return DebugInstrNum;
}
+
+unsigned MachineInstr::getDebugInstrNum(MachineFunction &MF) {
+ if (DebugInstrNum == 0)
+ DebugInstrNum = MF.getNewDebugInstrNum();
+ return DebugInstrNum;
+}