summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/MachineInstr.cpp40
-rw-r--r--llvm/lib/CodeGen/RegAllocFast.cpp78
2 files changed, 56 insertions, 62 deletions
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 6684f4e5d1c..66de99156b4 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -2408,26 +2408,36 @@ MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
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");
+ assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
+ "Expected inlined-at fields to agree");
+
+ const DIExpression *Expr = MI.getDebugExpression();
+ if (MI.isIndirectDebugValue()) {
+ assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset");
+ Expr = DIExpression::prepend(Expr, DIExpression::WithDeref);
+ }
+ return Expr;
+}
+
MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
const MachineInstr &Orig,
int FrameIndex) {
- const MDNode *Var = Orig.getDebugVariable();
- const auto *Expr = cast_or_null<DIExpression>(Orig.getDebugExpression());
- bool IsIndirect = Orig.isIndirectDebugValue();
- if (IsIndirect)
- assert(Orig.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset");
- DebugLoc DL = Orig.getDebugLoc();
- assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
- "Expected inlined-at fields to agree");
- // If the DBG_VALUE already was a memory location, add an extra
- // DW_OP_deref. Otherwise just turning this from a register into a
- // memory/indirect location is sufficient.
- if (IsIndirect)
- Expr = DIExpression::prepend(Expr, DIExpression::WithDeref);
- return BuildMI(BB, I, DL, Orig.getDesc())
+ const DIExpression *Expr = computeExprForSpill(Orig);
+ return BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc())
.addFrameIndex(FrameIndex)
.addImm(0U)
- .addMetadata(Var)
+ .addMetadata(Orig.getDebugVariable())
.addMetadata(Expr);
}
+
+void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex) {
+ const DIExpression *Expr = computeExprForSpill(Orig);
+ Orig.getOperand(0).ChangeToFrameIndex(FrameIndex);
+ Orig.getOperand(1).ChangeToImmediate(0U);
+ Orig.getOperand(3).setMetadata(Expr);
+}
diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp
index f00a0312dad..7061c3ff652 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -871,56 +871,40 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) {
// Debug values are not allowed to change codegen in any way.
if (MI.isDebugValue()) {
- bool ScanDbgValue = true;
MachineInstr *DebugMI = &MI;
- while (ScanDbgValue) {
- ScanDbgValue = false;
- for (unsigned I = 0, E = DebugMI->getNumOperands(); I != E; ++I) {
- MachineOperand &MO = DebugMI->getOperand(I);
- if (!MO.isReg()) continue;
- unsigned Reg = MO.getReg();
- if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue;
- LiveRegMap::iterator LRI = findLiveVirtReg(Reg);
- if (LRI != LiveVirtRegs.end())
- setPhysReg(*DebugMI, I, LRI->PhysReg);
- else {
- int SS = StackSlotForVirtReg[Reg];
- if (SS == -1) {
- // We can't allocate a physreg for a DebugValue, sorry!
- DEBUG(dbgs() << "Unable to allocate vreg used by DBG_VALUE");
- MO.setReg(0);
- }
- else {
- // Modify DBG_VALUE now that the value is in a spill slot.
- bool IsIndirect = DebugMI->isIndirectDebugValue();
- if (IsIndirect)
- assert(DebugMI->getOperand(1).getImm() == 0 &&
- "DBG_VALUE with nonzero offset");
- const MDNode *Var = DebugMI->getDebugVariable();
- const MDNode *Expr = DebugMI->getDebugExpression();
- DebugLoc DL = DebugMI->getDebugLoc();
- MachineBasicBlock *MBB = DebugMI->getParent();
- assert(
- cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
- "Expected inlined-at fields to agree");
- MachineInstr *NewDV = BuildMI(*MBB, MBB->erase(DebugMI), DL,
- TII->get(TargetOpcode::DBG_VALUE))
- .addFrameIndex(SS)
- .addImm(0U)
- .addMetadata(Var)
- .addMetadata(Expr);
- DEBUG(dbgs() << "Modifying debug info due to spill:"
- << "\t" << *NewDV);
- // Scan NewDV operands from the beginning.
- DebugMI = NewDV;
- ScanDbgValue = true;
- break;
- }
- }
- LiveDbgValueMap[Reg].push_back(DebugMI);
+ MachineOperand &MO = DebugMI->getOperand(0);
+
+ // Ignore DBG_VALUEs that aren't based on virtual registers. These are
+ // mostly constants and frame indices.
+ if (!MO.isReg())
+ continue;
+ unsigned Reg = MO.getReg();
+ if (!TargetRegisterInfo::isVirtualRegister(Reg))
+ continue;
+
+ // See if this virtual register has already been allocated to a physical
+ // register or spilled to a stack slot.
+ LiveRegMap::iterator LRI = findLiveVirtReg(Reg);
+ if (LRI != LiveVirtRegs.end())
+ setPhysReg(*DebugMI, 0, LRI->PhysReg);
+ else {
+ int SS = StackSlotForVirtReg[Reg];
+ if (SS != -1) {
+ // Modify DBG_VALUE now that the value is in a spill slot.
+ updateDbgValueForSpill(*DebugMI, SS);
+ DEBUG(dbgs() << "Modifying debug info due to spill:"
+ << "\t" << *DebugMI);
+ continue;
}
+
+ // We can't allocate a physreg for a DebugValue, sorry!
+ DEBUG(dbgs() << "Unable to allocate vreg used by DBG_VALUE");
+ MO.setReg(0);
}
- // Next instruction.
+
+ // If Reg hasn't been spilled, put this DBG_VALUE in LiveDbgValueMap so
+ // that future spills of Reg will have DBG_VALUEs.
+ LiveDbgValueMap[Reg].push_back(DebugMI);
continue;
}
OpenPOWER on IntegriCloud