summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/RegAllocFast.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-09-15 21:49:56 +0000
committerReid Kleckner <rnk@google.com>2017-09-15 21:49:56 +0000
commit9e6c309ef343acc13a14ca97f370e35079fbea1f (patch)
tree72a3937bb888c2a47ae4f66224fb092ba9d68bfb /llvm/lib/CodeGen/RegAllocFast.cpp
parentab211df5de42bf2b2f45fc73134c76f24835b47a (diff)
downloadbcm5719-llvm-9e6c309ef343acc13a14ca97f370e35079fbea1f.tar.gz
bcm5719-llvm-9e6c309ef343acc13a14ca97f370e35079fbea1f.zip
[DebugInfo] Add missing DW_OP_deref when an NRVO pointer is spilled
Summary: Fixes PR34513. Indirect DBG_VALUEs typically come from dbg.declares of non-trivially copyable C++ objects that must be passed by address. We were already handling the case where the virtual register gets allocated to a physical register and is later spilled. That's what usually happens for normal parameters that aren't NRVO variables: they usually appear in physical register parameters, and are spilled later in the function, which would correctly add deref. NRVO variables are different because the dbg.declare can come much later after earlier instructions cause the incoming virtual register to be spilled. Also, clean up this code. We only need to look at the first operand of a DBG_VALUE, which eliminates the operand loop. Reviewers: aprantl, dblaikie, probinson Subscribers: MatzeB, qcolombet, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D37929 llvm-svn: 313399
Diffstat (limited to 'llvm/lib/CodeGen/RegAllocFast.cpp')
-rw-r--r--llvm/lib/CodeGen/RegAllocFast.cpp78
1 files changed, 31 insertions, 47 deletions
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