aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineInstr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/MachineInstr.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineInstr.cpp119
1 files changed, 91 insertions, 28 deletions
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 94afaff..f0b2eaa 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 {
@@ -1712,7 +1719,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() << '\"';
@@ -2116,8 +2123,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 +2138,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 +2183,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,
+ Register SpillReg) {
+ assert(MI.hasDebugOperandForReg(SpillReg) && "Spill Reg is not used in MI.");
assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
"Expected inlined-at fields to agree");
@@ -2167,6 +2207,14 @@ 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 : MI.getDebugOperandsForReg(SpillReg)) {
+ unsigned OpIdx = MI.getDebugOperandIndex(&Op);
+ Expr = DIExpression::appendOpsToArg(Expr, Ops, OpIdx);
+ }
}
return Expr;
}
@@ -2175,18 +2223,32 @@ 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);
+ Register SpillReg = Orig.getDebugOperand(0).getReg();
+ 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;
}
void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex) {
- const DIExpression *Expr = computeExprForSpill(Orig);
- Orig.getDebugOperand(0).ChangeToFrameIndex(FrameIndex);
- Orig.getDebugOffset().ChangeToImmediate(0U);
+ Register SpillReg = Orig.getDebugOperand(0).getReg();
+ const DIExpression *Expr = computeExprForSpill(Orig, SpillReg);
+ if (Orig.isNonListDebugValue())
+ Orig.getDebugOffset().ChangeToImmediate(0U);
+ for (MachineOperand &Op : Orig.getDebugOperandsForReg(SpillReg))
+ Op.ChangeToFrameIndex(FrameIndex);
Orig.getDebugExpressionOp().setMetadata(Expr);
}
@@ -2201,7 +2263,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 +2281,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>;