aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/InlineSpiller.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2010-07-02 19:54:40 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2010-07-02 19:54:40 +0000
commit3b9c7ebc444ccc311a5e4125b904f9767244577a (patch)
tree28978aac0d81e43202eec2ce95dc57adb39bcc3e /lib/CodeGen/InlineSpiller.cpp
parent135d7fe9bb27594820ae3b64e6f6937b5cef771e (diff)
downloadexternal_llvm-3b9c7ebc444ccc311a5e4125b904f9767244577a.tar.gz
external_llvm-3b9c7ebc444ccc311a5e4125b904f9767244577a.tar.bz2
external_llvm-3b9c7ebc444ccc311a5e4125b904f9767244577a.zip
Properly handle debug values during inline spilling.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107503 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/InlineSpiller.cpp')
-rw-r--r--lib/CodeGen/InlineSpiller.cpp45
1 files changed, 32 insertions, 13 deletions
diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp
index 405ec258d5..71305ed863 100644
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -245,20 +245,21 @@ void InlineSpiller::reMaterializeAll() {
return;
// Removing values may cause debug uses where li_ is not live.
- for (MachineRegisterInfo::use_iterator
- RI = mri_.use_begin(li_->reg), RE = mri_.use_end(); RI != RE;) {
- MachineOperand &MO = RI.getOperand();
- MachineInstr *MI = MO.getParent();
- ++RI;
- SlotIndex UseIdx = lis_.getInstructionIndex(MI).getUseIndex();
- DEBUG(dbgs() << "\tremaining use: " << UseIdx << '\t' << *MI);
- if (li_->liveAt(UseIdx))
+ for (MachineRegisterInfo::use_iterator RI = mri_.use_begin(li_->reg);
+ MachineInstr *MI = RI.skipInstruction();) {
+ if (!MI->isDebugValue())
continue;
- assert(MI->isDebugValue() && "Remaining non-debug use after remat dead.");
- if (li_->empty())
- MO.setIsUndef();
- else
- MO.setReg(0);
+ // Try to preserve the debug value if li_ is live immediately after it.
+ MachineBasicBlock::iterator NextMI = MI;
+ ++NextMI;
+ if (NextMI != MI->getParent()->end() && !lis_.isNotInMIMap(NextMI)) {
+ SlotIndex NearIdx = lis_.getInstructionIndex(NextMI);
+ if (li_->liveAt(NearIdx))
+ continue;
+ }
+ DEBUG(dbgs() << "Removing debug info due to remat:" << "\t" << *MI);
+ assert(&*RI != MI && "Multiple register operands on debug value");
+ MI->eraseFromParent();
}
}
@@ -348,6 +349,24 @@ void InlineSpiller::spill(LiveInterval *li,
for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(li->reg);
MachineInstr *MI = RI.skipInstruction();) {
+ // Debug values are not allowed to affect codegen.
+ if (MI->isDebugValue()) {
+ // Modify DBG_VALUE now that the value is in a spill slot.
+ uint64_t Offset = MI->getOperand(1).getImm();
+ const MDNode *MDPtr = MI->getOperand(2).getMetadata();
+ DebugLoc DL = MI->getDebugLoc();
+ if (MachineInstr *NewDV = tii_.emitFrameIndexDebugValue(mf_, stackSlot_,
+ Offset, MDPtr, DL)) {
+ DEBUG(dbgs() << "Modifying debug info due to spill:" << "\t" << *MI);
+ MachineBasicBlock *MBB = MI->getParent();
+ MBB->insert(MBB->erase(MI), NewDV);
+ } else {
+ DEBUG(dbgs() << "Removing debug info due to spill:" << "\t" << *MI);
+ MI->eraseFromParent();
+ }
+ continue;
+ }
+
// Analyze instruction.
bool Reads, Writes;
SmallVector<unsigned, 8> Ops;