[llvm-commits] [llvm] r128114 - in /llvm/trunk: lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h lib/CodeGen/LiveDebugVariables.cpp test/CodeGen/X86/dbg-value-range.ll
Jakob Stoklund Olesen
stoklund at 2pi.dk
Tue Mar 22 15:33:08 PDT 2011
Author: stoklund
Date: Tue Mar 22 17:33:08 2011
New Revision: 128114
URL: http://llvm.org/viewvc/llvm-project?rev=128114&view=rev
Log:
Reapply r128045 and r128051 with fixes.
This will extend the ranges of debug info variables in registers until they are
clobbered.
Fix 1: Don't mistake DBG_VALUE instructions referring to incoming arguments on
the stack with DBG_VALUE instructions referring to variables in the frame
pointer. This fixes the gdb test-suite failure.
Fix 2: Don't trace through copies to physical registers setting up call
arguments. These registers are call clobbered, and the source register is more
likely to be a callee-saved register that can be extended through the call
instruction.
Modified:
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp
llvm/trunk/test/CodeGen/X86/dbg-value-range.ll
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=128114&r1=128113&r2=128114&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Mar 22 17:33:08 2011
@@ -2382,9 +2382,9 @@
/// DBG_VALUE instruction, is in a defined reg.
static bool isDbgValueInDefinedReg(const MachineInstr *MI) {
assert (MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!");
- if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg())
- return true;
- return false;
+ return MI->getNumOperands() == 3 &&
+ MI->getOperand(0).isReg() && MI->getOperand(0).getReg() &&
+ MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0;
}
/// collectVariableInfo - Populate DbgScope entries with variables' info.
@@ -2407,7 +2407,7 @@
DbgValues.push_back(MInsn);
}
- // This is a collection of DBV_VALUE instructions describing same variable.
+ // This is a collection of DBG_VALUE instructions describing same variable.
SmallVector<const MachineInstr *, 4> MultipleValues;
for(SmallVector<const MachineInstr *, 8>::iterator I = DbgValues.begin(),
E = DbgValues.end(); I != E; ++I) {
@@ -2424,8 +2424,7 @@
ME = DbgValues.end(); MI != ME; ++MI) {
const MDNode *Var =
(*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata();
- if (Var == DV &&
- !PrevMI->isIdenticalTo(*MI))
+ if (Var == DV && !PrevMI->isIdenticalTo(*MI))
MultipleValues.push_back(*MI);
PrevMI = *MI;
}
@@ -2448,7 +2447,7 @@
DbgVariableToDbgInstMap[AbsVar] = MInsn;
VarToAbstractVarMap[RegVar] = AbsVar;
}
- if (MultipleValues.size() <= 1) {
+ if (MultipleValues.size() <= 1 && !RegClobberInsn.count(MInsn)) {
DbgVariableToDbgInstMap[RegVar] = MInsn;
continue;
}
@@ -2458,16 +2457,11 @@
RegVar->setDotDebugLocOffset(0);
else
RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
- const MachineInstr *Begin = NULL;
- const MachineInstr *End = NULL;
+
for (SmallVector<const MachineInstr *, 4>::iterator
MVI = MultipleValues.begin(), MVE = MultipleValues.end();
MVI != MVE; ++MVI) {
- if (!Begin) {
- Begin = *MVI;
- continue;
- }
- End = *MVI;
+ const MachineInstr *Begin = *MVI;
MachineLocation MLoc;
if (Begin->getNumOperands() == 3) {
if (Begin->getOperand(0).isReg() && Begin->getOperand(1).isImm())
@@ -2475,25 +2469,25 @@
} else
MLoc = Asm->getDebugValueLocation(Begin);
+ if (!MLoc.getReg())
+ continue;
+
+ // Compute the range for a register location.
const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
- const MCSymbol *SLabel = getLabelBeforeInsn(End);
- if (MLoc.getReg())
- DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
-
- Begin = End;
- if (MVI + 1 == MVE) {
- // If End is the last instruction then its value is valid
+ const MCSymbol *SLabel = 0;
+
+ if (const MachineInstr *ClobberMI = RegClobberInsn.lookup(Begin))
+ // The register range starting at Begin may be clobbered.
+ SLabel = getLabelAfterInsn(ClobberMI);
+ else if (MVI + 1 == MVE)
+ // If Begin is the last instruction then its value is valid
// until the end of the funtion.
- MachineLocation EMLoc;
- if (End->getNumOperands() == 3) {
- if (End->getOperand(0).isReg() && Begin->getOperand(1).isImm())
- EMLoc.set(Begin->getOperand(0).getReg(), Begin->getOperand(1).getImm());
- } else
- EMLoc = Asm->getDebugValueLocation(End);
- if (EMLoc.getReg())
- DotDebugLocEntries.
- push_back(DotDebugLocEntry(SLabel, FunctionEndSym, EMLoc));
- }
+ SLabel = FunctionEndSym;
+ else
+ // The value is valid until the next DBG_VALUE.
+ SLabel = getLabelBeforeInsn(MVI[1]);
+
+ DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
}
DotDebugLocEntries.push_back(DotDebugLocEntry());
}
@@ -2568,7 +2562,7 @@
/// endInstruction - Process end of an instruction.
void DwarfDebug::endInstruction(const MachineInstr *MI) {
- if (InsnsEndScopeSet.count(MI) != 0) {
+ if (InsnsNeedsLabelAfter.count(MI) != 0) {
// Emit a label if this instruction ends a scope.
MCSymbol *Label = MMI->getContext().CreateTempSymbol();
Asm->OutStreamer.EmitLabel(Label);
@@ -2833,7 +2827,7 @@
RE = Ranges.end(); RI != RE; ++RI) {
assert(RI->first && "DbgRange does not have first instruction!");
assert(RI->second && "DbgRange does not have second instruction!");
- InsnsEndScopeSet.insert(RI->second);
+ InsnsNeedsLabelAfter.insert(RI->second);
}
}
}
@@ -2914,6 +2908,14 @@
/// ProcessedArgs - Collection of arguments already processed.
SmallPtrSet<const MDNode *, 8> ProcessedArgs;
+ /// LastDbgValue - Refer back to the last DBG_VALUE instruction to mention MD.
+ DenseMap<const MDNode*, const MachineInstr*> LastDbgValue;
+
+ const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
+
+ /// LiveUserVar - Map physreg numbers to the MDNode they contain.
+ std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs());
+
DebugLoc PrevLoc;
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
I != E; ++I)
@@ -2923,7 +2925,15 @@
DebugLoc DL = MI->getDebugLoc();
if (MI->isDebugValue()) {
assert (MI->getNumOperands() > 1 && "Invalid machine instruction!");
- DIVariable DV(MI->getOperand(MI->getNumOperands() - 1).getMetadata());
+
+ // Keep track of variables in registers.
+ const MDNode *Var =
+ MI->getOperand(MI->getNumOperands() - 1).getMetadata();
+ LastDbgValue[Var] = MI;
+ if (isDbgValueInDefinedReg(MI))
+ LiveUserVar[MI->getOperand(0).getReg()] = Var;
+
+ DIVariable DV(Var);
if (!DV.Verify()) continue;
// If DBG_VALUE is for a local variable then it needs a label.
if (DV.getTag() != dwarf::DW_TAG_arg_variable)
@@ -2944,6 +2954,32 @@
} else if (DL != PrevLoc)
// Otherwise, instruction needs a location only if it is new location.
InsnNeedsLabel.insert(MI);
+
+ // Check if the instruction clobbers any registers with debug vars.
+ for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(),
+ MOE = MI->operands_end(); MOI != MOE; ++MOI) {
+ if (!MOI->isReg() || !MOI->isDef() || !MOI->getReg())
+ continue;
+ for (const unsigned *AI = TRI->getOverlaps(MOI->getReg());
+ unsigned Reg = *AI; ++AI) {
+ const MDNode *Var = LiveUserVar[Reg];
+ if (!Var)
+ continue;
+ // Reg is now clobbered.
+ LiveUserVar[Reg] = 0;
+
+ // Was MD last defined by a DBG_VALUE referring to Reg?
+ const MachineInstr *Last = LastDbgValue.lookup(Var);
+ if (!Last || Last->getParent() != MI->getParent())
+ continue;
+ if (!isDbgValueInDefinedReg(Last) ||
+ Last->getOperand(0).getReg() != Reg)
+ continue;
+ // MD is clobbered. Make sure the next instruction gets a label.
+ InsnsNeedsLabelAfter.insert(MI);
+ RegClobberInsn[Last] = MI;
+ }
+ }
}
if (!DL.isUnknown() || UnknownLocations)
@@ -3013,7 +3049,8 @@
VarToAbstractVarMap.clear();
DbgVariableToDbgInstMap.clear();
DeleteContainerSeconds(DbgScopeMap);
- InsnsEndScopeSet.clear();
+ InsnsNeedsLabelAfter.clear();
+ RegClobberInsn.clear();
ConcreteScopes.clear();
DeleteContainerSeconds(AbstractScopes);
AbstractScopesList.clear();
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=128114&r1=128113&r2=128114&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Mar 22 17:33:08 2011
@@ -200,8 +200,6 @@
typedef SmallVector<DbgScope *, 2> ScopeVector;
- SmallPtrSet<const MachineInstr *, 8> InsnsEndScopeSet;
-
/// InlineInfo - Keep track of inlined functions and their location. This
/// information is used to populate debug_inlined section.
typedef std::pair<const MCSymbol *, DIE *> InlineInfoLabels;
@@ -224,6 +222,16 @@
/// a debuggging information entity.
SmallPtrSet<const MachineInstr *, 8> InsnNeedsLabel;
+ /// InsnsNeedsLabelAfter - Collection of instructions that need a label after
+ /// the instruction because they end a scope of clobber a register.
+ SmallPtrSet<const MachineInstr *, 8> InsnsNeedsLabelAfter;
+
+ /// RegClobberInsn - For each DBG_VALUE instruction referring to a register
+ /// that is clobbered before the variable gets a new DBG_VALUE, map the
+ /// instruction that clobbered the register. This instruction will also be in
+ /// InsnsNeedsLabelAfter.
+ DenseMap<const MachineInstr *, const MachineInstr *> RegClobberInsn;
+
SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
/// Previous instruction's location information. This is used to determine
Modified: llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp?rev=128114&r1=128113&r2=128114&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp Tue Mar 22 17:33:08 2011
@@ -101,10 +101,6 @@
void insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, unsigned LocNo,
LiveIntervals &LIS, const TargetInstrInfo &TII);
- /// insertDebugKill - Insert an undef DBG_VALUE into MBB at Idx.
- void insertDebugKill(MachineBasicBlock *MBB, SlotIndex Idx,
- LiveIntervals &LIS, const TargetInstrInfo &TII);
-
public:
/// UserValue - Create a new UserValue.
UserValue(const MDNode *var, unsigned o, DebugLoc L,
@@ -515,6 +511,13 @@
MachineInstr *MI = &*UI;
unsigned DstReg = MI->getOperand(0).getReg();
+ // Don't follow copies to physregs. These are usually setting up call
+ // arguments, and the argument registers are always call clobbered. We are
+ // better off in the source register which could be a callee-saved register,
+ // or it could be spilled.
+ if (!TargetRegisterInfo::isVirtualRegister(DstReg))
+ continue;
+
// Is LocNo extended to reach this copy? If not, another def may be blocking
// it, or we are looking at a wrong value of LI.
SlotIndex Idx = LIS.getInstructionIndex(MI);
@@ -752,13 +755,6 @@
.addOperand(Loc).addImm(offset).addMetadata(variable);
}
-void UserValue::insertDebugKill(MachineBasicBlock *MBB, SlotIndex Idx,
- LiveIntervals &LIS, const TargetInstrInfo &TII) {
- MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, LIS);
- BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE)).addReg(0)
- .addImm(offset).addMetadata(variable);
-}
-
void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
const TargetInstrInfo &TII) {
MachineFunction::iterator MFEnd = VRM->getMachineFunction().end();
@@ -790,12 +786,6 @@
break;
++I;
- if (Stop == MBBEnd)
- continue;
- // The current interval ends before MBB.
- // Insert a kill if there is a gap.
- if (!I.valid() || I.start() > Stop)
- insertDebugKill(MBB, Stop, LIS, TII);
}
}
Modified: llvm/trunk/test/CodeGen/X86/dbg-value-range.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dbg-value-range.ll?rev=128114&r1=128113&r2=128114&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dbg-value-range.ll (original)
+++ llvm/trunk/test/CodeGen/X86/dbg-value-range.ll Tue Mar 22 17:33:08 2011
@@ -41,15 +41,17 @@
!18 = metadata !{i32 7, i32 2, metadata !12, null}
!19 = metadata !{i32 8, i32 2, metadata !12, null}
-; check that variable bar:b value range is appropriately trucated in debug info. Here Ltmp5 is end of
-; location range.
+; Check that variable bar:b value range is appropriately trucated in debug info.
+; The variable is in %rdi which is clobbered by 'movl %ebx, %edi'
+; Here Ltmp7 is the end of the location range.
;CHECK:Ltmp6
-;CHECK-NEXT: DEBUG_VALUE: bar:b <- undef
+;CHECK-NEXT: movl
+;CHECK-NEXT: Ltmp7
;CHECK:Ldebug_loc0:
;CHECK-NEXT: .quad Ltmp
-;CHECK-NEXT: .quad Ltmp6
+;CHECK-NEXT: .quad Ltmp7
;CHECK-NEXT: .short 1
;CHECK-NEXT: .byte 85
;CHECK-NEXT: .quad 0
More information about the llvm-commits
mailing list