summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/LiveDebugValues.cpp
diff options
context:
space:
mode:
authorJeremy Morse <jeremy.morse.llvm@gmail.com>2019-08-16 10:04:17 +0000
committerJeremy Morse <jeremy.morse.llvm@gmail.com>2019-08-16 10:04:17 +0000
commit8b593480d33f8e8f5c4ec1f921a2c692bd0b7f45 (patch)
tree741faaa26c7e9e099459d1dc1d852670ccf3c9b5 /llvm/lib/CodeGen/LiveDebugValues.cpp
parent22970d66be7856693ea56e7395909351d0885e57 (diff)
downloadbcm5719-llvm-8b593480d33f8e8f5c4ec1f921a2c692bd0b7f45.tar.gz
bcm5719-llvm-8b593480d33f8e8f5c4ec1f921a2c692bd0b7f45.zip
[DebugInfo] Handle complex expressions with spills in LiveDebugValues
In r369026 we disabled spill-recognition in LiveDebugValues for anything that has a complex expression. This is because it's hard to recover the complex expression once the spill location is baked into it. This patch re-enables spill-recognition and slightly adjusts the DBG_VALUE insts that LiveDebugValues tracks: instead of tracking the last DBG_VALUE for a variable, it tracks the last _unspilt_ DBG_VALUE. The spill-restore code is then able to access and copy the original complex expression; but the rest of LiveDebugValues has to be aware of the slight semantic shift, and produce a new spilt location if a spilt location is propagated between blocks. The test added produces an incorrect variable location (see FIXME), which will be the subject of future work. Differential Revision: https://reviews.llvm.org/D65368 llvm-svn: 369092
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugValues.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues.cpp58
1 files changed, 27 insertions, 31 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues.cpp
index b82cef90589..74e641be060 100644
--- a/llvm/lib/CodeGen/LiveDebugValues.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues.cpp
@@ -227,8 +227,8 @@ private:
/// The constructor for spill locations.
VarLoc(const MachineInstr &MI, unsigned SpillBase, int SpillOffset,
- LexicalScopes &LS)
- : Var(MI), MI(MI), UVS(MI.getDebugLoc(), LS) {
+ LexicalScopes &LS, const MachineInstr &OrigMI)
+ : Var(MI), MI(OrigMI), UVS(MI.getDebugLoc(), LS) {
assert(MI.isDebugValue() && "not a DBG_VALUE");
assert(MI.getNumOperands() == 4 && "malformed DBG_VALUE");
Kind = SpillLocKind;
@@ -567,11 +567,7 @@ void LiveDebugValues::transferDebugValue(const MachineInstr &MI,
ID = VarLocIDs.insert(VL);
OpenRanges.insert(ID, VL.Var);
} else if (MI.hasOneMemOperand()) {
- // It's a stack spill -- fetch spill base and offset.
- VarLoc::SpillLoc SpillLocation = extractSpillBaseRegAndOffset(MI);
- VarLoc VL(MI, SpillLocation.SpillBase, SpillLocation.SpillOffset, LS);
- ID = VarLocIDs.insert(VL);
- OpenRanges.insert(ID, VL.Var);
+ llvm_unreachable("DBG_VALUE with mem operand encountered after regalloc?");
} else {
// This must be an undefined location. We should leave OpenRanges closed.
assert(MI.getOperand(0).isReg() && MI.getOperand(0).getReg() == 0 &&
@@ -678,7 +674,7 @@ void LiveDebugValues::insertTransferDebugPair(
*MF, DebugInstr->getDebugLoc(), DebugInstr->getDesc(), true,
SpillLocation.SpillBase, DebugInstr->getDebugVariable(), SpillExpr);
VarLoc VL(*NewDebugInstr, SpillLocation.SpillBase,
- SpillLocation.SpillOffset, LS);
+ SpillLocation.SpillOffset, LS, *DebugInstr);
ProcessVarLoc(VL, NewDebugInstr);
LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for spill: ";
NewDebugInstr->print(dbgs(), /*IsStandalone*/false,
@@ -691,17 +687,11 @@ void LiveDebugValues::insertTransferDebugPair(
"No register supplied when handling a restore of a debug value");
MachineFunction *MF = MI.getMF();
DIBuilder DIB(*const_cast<Function &>(MF->getFunction()).getParent());
-
- const DIExpression *NewExpr;
- if (auto Fragment = DebugInstr->getDebugExpression()->getFragmentInfo())
- NewExpr = *DIExpression::createFragmentExpression(DIB.createExpression(),
- Fragment->OffsetInBits, Fragment->SizeInBits);
- else
- NewExpr = DIB.createExpression();
-
- NewDebugInstr =
- BuildMI(*MF, DebugInstr->getDebugLoc(), DebugInstr->getDesc(), false,
- NewReg, DebugInstr->getDebugVariable(), NewExpr);
+ // DebugInstr refers to the pre-spill location, therefore we can reuse
+ // its expression.
+ NewDebugInstr = BuildMI(
+ *MF, DebugInstr->getDebugLoc(), DebugInstr->getDesc(), false, NewReg,
+ DebugInstr->getDebugVariable(), DebugInstr->getDebugExpression());
VarLoc VL(*NewDebugInstr, LS);
ProcessVarLoc(VL, NewDebugInstr);
LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for register restore: ";
@@ -856,14 +846,9 @@ void LiveDebugValues::transferSpillOrRestoreInst(MachineInstr &MI,
<< "\n");
}
// Check if the register or spill location is the location of a debug value.
- // FIXME: Don't create a spill transfer if there is a complex expression,
- // because we currently cannot recover the original expression on restore.
for (unsigned ID : OpenRanges.getVarLocs()) {
- const MachineInstr *DebugInstr = &VarLocIDs[ID].MI;
-
if (TKind == TransferKind::TransferSpill &&
- VarLocIDs[ID].isDescribedByReg() == Reg &&
- !DebugInstr->getDebugExpression()->isComplex()) {
+ VarLocIDs[ID].isDescribedByReg() == Reg) {
LLVM_DEBUG(dbgs() << "Spilling Register " << printReg(Reg, TRI) << '('
<< VarLocIDs[ID].Var.getVar()->getName() << ")\n");
} else if (TKind == TransferKind::TransferRestore &&
@@ -1121,13 +1106,24 @@ bool LiveDebugValues::join(
DebugInstr->getDebugVariable(),
DebugInstr->getDebugExpression());
} else {
+ auto *DebugExpr = DebugInstr->getDebugExpression();
+ Register Reg = DebugInstr->getOperand(0).getReg();
+ bool IsIndirect = DebugInstr->isIndirectDebugValue();
+
+ if (DiffIt.Kind == VarLoc::SpillLocKind) {
+ // This is is a spilt location; DebugInstr refers to the unspilt
+ // location. We need to rebuild the spilt location expression and
+ // point the DBG_VALUE at the frame register.
+ DebugExpr = DIExpression::prepend(DebugInstr->getDebugExpression(),
+ DIExpression::ApplyOffset,
+ DiffIt.Loc.SpillLocation.SpillOffset);
+ Reg = TRI->getFrameRegister(*DebugInstr->getMF());
+ IsIndirect = true;
+ }
+
MI = BuildMI(MBB, MBB.instr_begin(), DebugInstr->getDebugLoc(),
- DebugInstr->getDesc(), DebugInstr->isIndirectDebugValue(),
- DebugInstr->getOperand(0).getReg(),
- DebugInstr->getDebugVariable(),
- DebugInstr->getDebugExpression());
- if (DebugInstr->isIndirectDebugValue())
- MI->getOperand(1).setImm(DebugInstr->getOperand(1).getImm());
+ DebugInstr->getDesc(), IsIndirect, Reg,
+ DebugInstr->getDebugVariable(), DebugExpr);
}
LLVM_DEBUG(dbgs() << "Inserted: "; MI->dump(););
ILS.set(ID);
OpenPOWER on IntegriCloud