[llvm-commits] [llvm] r128327 - in /llvm/trunk: include/llvm/CodeGen/MachineBasicBlock.h lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h test/CodeGen/X86/dbg-merge-loc-entry.ll
David Blaikie
dblaikie at gmail.com
Tue Oct 29 15:33:34 PDT 2013
+Alexey who's encountering this in ASan
On Fri, Oct 25, 2013 at 1:28 PM, David Blaikie <dblaikie at gmail.com> wrote:
> Bump because... argh. (I've also reformatted the samples to remove all the
> extra newlines, hopefully).
>
> Lang - you want to chat about this some time? Eric & I really aren't sure
> who else to chat to about this.
>
> Eric - this patch seems to be related to the issue I was discussing
>> at/with you yesterday. Specifically the "or when the basic block ends" part
>> is problematic for cases I'm looking at:
>>
>
>
>>
>> 1. struct foo {
>> 2. foo() : i(3) {}
>> 3. foo(const foo& f) : i(f.i) { }
>> 4. int i;
>> 5. };
>> 6.
>> 7. int func(foo f) {
>> 8. if (!f.i)
>> 9. return f.i + 1;
>> 10. return f.i + 2;
>> 11. }
>> 12.
>> 13. int main() {
>> 14. foo l;
>> 15. func(l);
>> 16. }
>>
>>
>> I get the following assembly for 'func':
>>
>>
>> 1. .globl _Z4func3foo
>> 2. .align 16, 0x90
>> 3. .type _Z4func3foo, at function
>> 4. _Z4func3foo: # @_Z4func3foo
>> 5. .cfi_startproc
>> 6. .Lfunc_begin0:
>> 7. .loc 1 7 0 # test.cpp:7:0
>> 8. # BB#0: # %entry
>> 9. pushq %rbp
>> 10. .Ltmp2:
>> 11. .cfi_def_cfa_offset 16
>> 12. .Ltmp3:
>> 13. .cfi_offset %rbp, -16
>> 14. movq %rsp, %rbp
>> 15. .Ltmp4:
>> 16. .cfi_def_cfa_register %rbp
>> 17. #DEBUG_VALUE: func:f <- RDI
>> 18. .loc 1 8 0 prologue_end # test.cpp:8:0
>> 19. .Ltmp5:
>> 20. cmpl $0, (%rdi)
>> 21. movq %rdi, -16(%rbp) # 8-byte Spill
>> 22. .Ltmp6:
>> 23. #DEBUG_VALUE: func:f <- [RBP+-16]
>> 24. jne .LBB0_2
>> 25. .Ltmp7:
>> 26. # BB#1: # %if.then
>> 27. .loc 1 9 0 # test.cpp:9:0
>> 28. movq -16(%rbp), %rax # 8-byte Reload
>> 29. movl (%rax), %ecx
>> 30. addl $1, %ecx
>> 31. movl %ecx, -4(%rbp)
>> 32. jmp .LBB0_3
>> 33. .Ltmp8:
>> 34. .LBB0_2: # %if.end
>> 35. .loc 1 10 0 # test.cpp:10:0
>> 36. movq -16(%rbp), %rax # 8-byte Reload
>> 37. movl (%rax), %ecx
>> 38. addl $2, %ecx
>> 39. movl %ecx, -4(%rbp)
>> 40. .LBB0_3: # %return
>> 41. .loc 1 11 0 # test.cpp:11:0
>> 42. movl -4(%rbp), %eax
>> 43. popq %rbp
>> 44. ret
>>
>>
>
>> And the debug_loc for 'func:f' is:
>>
>>
>> 1. .Ldebug_loc0:
>> 2. .quad .Lfunc_begin0
>> 3. .quad .Ltmp6
>> 4. .Lset0 = .Ltmp53-.Ltmp52 # Loc expr size
>> 5. .short .Lset0
>> 6. .Ltmp52:
>> 7. .byte 117 # DW_OP_breg5
>> 8. .byte 0
>> 9. .Ltmp53:
>> 10. .quad .Ltmp6
>> 11. .quad .Ltmp7
>> 12. .Lset1 = .Ltmp55-.Ltmp54 # Loc expr size
>> 13. .short .Lset1
>> 14. .Ltmp54:
>> 15. .byte 118 # DW_OP_breg6
>> 16. .byte 112
>> 17. .byte 6
>> 18. .Ltmp55:
>>
>>
>> The important point being that the second range for the variable (for
>> -16(%rbp)) ends at the end of the first basic block. Thus for the range
>> tmp7-func_end we have no location information for this variable.
>>
>> This bug appears to manifest on any non-trivial-pass-by-value parameter
>> and any trivial pass-by-value parameter than ends up lowered to LLVM
>> "byval" (if it's split into multiple reg parameters then we must
>> reconstitute it inside the function and then we track the debug info for
>> that reconstituted value - probably an alloca so everything is good at -O0
>> at least).
>>
>> Should we be special casing indirect dbg_values and letting them past the
>> edge of basic blocks?
>> Or only ones relative to the base pointer?
>> Or do we need to have dbg_value MI intrinsics inserted at the beginning
>> of every subsequent basic block to properly communicate where variables are?
>> Or something else entirely.
>>
>> The code is now ready to deal with variables that are sometimes in a
>>> register
>>> and sometimes on the stack. We just need to teach emitDebugLoc to say
>>> 'stack
>>> slot'.
>>>
>>
>> Not sure if this /\ point is relevant, irrelevant, or something that's
>> been addressed since this commit. My best guess is that this comment is
>> just about how we describe stack slots in a location list - in that we
>> could describe them more compactly than reg+offset (by using fbreg instead
>> of breg) and we aren't. That seems like an easy special case of "is the
>> register the frame register, then use fbreg".
>>
>>
>>>
>>> Modified:
>>> llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
>>> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
>>> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
>>> llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll
>>>
>>> Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=128327&r1=128326&r2=128327&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original)
>>> +++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Fri Mar 25
>>> 21:19:36 2011
>>> @@ -309,6 +309,10 @@
>>> /// instruction in the basic block, or end()
>>> iterator getLastNonDebugInstr();
>>>
>>> + const_iterator getLastNonDebugInstr() const {
>>> + return const_cast<MachineBasicBlock*>(this)->getLastNonDebugInstr();
>>> + }
>>> +
>>> /// SplitCriticalEdge - Split the critical edge from this block to the
>>> /// given successor block, and return the newly created block, or null
>>> /// if splitting is not possible.
>>>
>>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=128327&r1=128326&r2=128327&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
>>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Fri Mar 25 21:19:36
>>> 2011
>>> @@ -2408,38 +2408,21 @@
>>> /// collection info from MMI table.
>>> collectVariableInfoFromMMITable(MF, Processed);
>>>
>>> - SmallVector<const MachineInstr *, 8> DbgValues;
>>> - // Collect variable information from DBG_VALUE machine instructions;
>>> - for (MachineFunction::const_iterator I = Asm->MF->begin(), E =
>>> Asm->MF->end();
>>> - I != E; ++I)
>>> - for (MachineBasicBlock::const_iterator II = I->begin(), IE =
>>> I->end();
>>> - II != IE; ++II) {
>>> - const MachineInstr *MInsn = II;
>>> - if (!MInsn->isDebugValue())
>>> - continue;
>>> - DbgValues.push_back(MInsn);
>>> - }
>>> -
>>> - // 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) {
>>> - const MachineInstr *MInsn = *I;
>>> - MultipleValues.clear();
>>> - if (isDbgValueInDefinedReg(MInsn))
>>> - MultipleValues.push_back(MInsn);
>>> - DIVariable DV(MInsn->getOperand(MInsn->getNumOperands() -
>>> 1).getMetadata());
>>> - if (Processed.count(DV) != 0)
>>> + for (SmallVectorImpl<const MDNode*>::const_iterator
>>> + UVI = UserVariables.begin(), UVE = UserVariables.end(); UVI !=
>>> UVE;
>>> + ++UVI) {
>>> + const MDNode *Var = *UVI;
>>> + if (Processed.count(Var))
>>> continue;
>>>
>>> - for (SmallVector<const MachineInstr *, 8>::iterator MI = I+1,
>>> - ME = DbgValues.end(); MI != ME; ++MI) {
>>> - const MDNode *Var =
>>> - (*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata();
>>> - if (Var == DV)
>>> - MultipleValues.push_back(*MI);
>>> - }
>>> + // History contains relevant DBG_VALUE instructions for Var and
>>> instructions
>>> + // clobbering it.
>>> + SmallVectorImpl<const MachineInstr*> &History = DbgValues[Var];
>>> + if (History.empty())
>>> + continue;
>>> + const MachineInstr *MInsn = History.front();
>>>
>>> + DIVariable DV(Var);
>>> DbgScope *Scope = NULL;
>>> if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
>>> DISubprogram(DV.getContext()).describes(MF->getFunction()))
>>> @@ -2451,6 +2434,7 @@
>>> continue;
>>>
>>> Processed.insert(DV);
>>> + assert(MInsn->isDebugValue() && "History must begin with debug
>>> value");
>>> DbgVariable *RegVar = new DbgVariable(DV);
>>> if (!addCurrentFnArgument(MF, RegVar, Scope))
>>> Scope->addVariable(RegVar);
>>> @@ -2458,21 +2442,21 @@
>>> DbgVariableToDbgInstMap[AbsVar] = MInsn;
>>> VarToAbstractVarMap[RegVar] = AbsVar;
>>> }
>>> - if (MultipleValues.size() <= 1 && !RegClobberInsn.count(MInsn)) {
>>> +
>>> + // Simple ranges that are fully coalesced.
>>> + if (History.size() <= 1 || (History.size() == 2 &&
>>> + MInsn->isIdenticalTo(History.back()))) {
>>> DbgVariableToDbgInstMap[RegVar] = MInsn;
>>> continue;
>>> }
>>>
>>> // handle multiple DBG_VALUE instructions describing one variable.
>>> - if (DotDebugLocEntries.empty())
>>> - RegVar->setDotDebugLocOffset(0);
>>> - else
>>> - RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
>>> + RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
>>>
>>> - for (SmallVector<const MachineInstr *, 4>::iterator
>>> - MVI = MultipleValues.begin(), MVE = MultipleValues.end();
>>> - MVI != MVE; ++MVI) {
>>> - const MachineInstr *Begin = *MVI;
>>> + for (SmallVectorImpl<const MachineInstr*>::const_iterator
>>> + HI = History.begin(), HE = History.end(); HI != HE; ++HI) {
>>> + const MachineInstr *Begin = *HI;
>>> + assert(Begin->isDebugValue() && "Invalid History entry");
>>> MachineLocation MLoc;
>>> if (Begin->getNumOperands() == 3) {
>>> if (Begin->getOperand(0).isReg() &&
>>> Begin->getOperand(1).isImm())
>>> @@ -2480,6 +2464,7 @@
>>> } else
>>> MLoc = Asm->getDebugValueLocation(Begin);
>>>
>>> + // FIXME: emitDebugLoc only understands registers.
>>> if (!MLoc.getReg())
>>> continue;
>>>
>>> @@ -2487,17 +2472,23 @@
>>> const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
>>> 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
>>> + if (HI + 1 == HE)
>>> + // If Begin is the last instruction in History then its value
>>> is valid
>>> // until the end of the funtion.
>>> SLabel = FunctionEndSym;
>>> - else
>>> - // The value is valid until the next DBG_VALUE.
>>> - SLabel = getLabelBeforeInsn(MVI[1]);
>>> + else {
>>> + const MachineInstr *End = HI[1];
>>> + if (End->isDebugValue())
>>> + SLabel = getLabelBeforeInsn(End);
>>> + else {
>>> + // End is a normal instruction clobbering the range.
>>> + SLabel = getLabelAfterInsn(End);
>>> + assert(SLabel && "Forgot label after clobber instruction");
>>> + ++HI;
>>> + }
>>> + }
>>>
>>> + // The value is valid until the next DBG_VALUE or clobber.
>>> DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel,
>>> MLoc));
>>> }
>>> DotDebugLocEntries.push_back(DotDebugLocEntry());
>>> @@ -2519,21 +2510,14 @@
>>>
>>> /// getLabelBeforeInsn - Return Label preceding the instruction.
>>> const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) {
>>> - DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
>>> - LabelsBeforeInsn.find(MI);
>>> - if (I == LabelsBeforeInsn.end())
>>> - // FunctionBeginSym always preceeds all the instruction in current
>>> function.
>>> - return FunctionBeginSym;
>>> - return I->second;
>>> + MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
>>> + assert(Label && "Didn't insert label before instruction");
>>> + return Label;
>>> }
>>>
>>> /// getLabelAfterInsn - Return Label immediately following the
>>> instruction.
>>> const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
>>> - DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
>>> - LabelsAfterInsn.find(MI);
>>> - if (I == LabelsAfterInsn.end())
>>> - return NULL;
>>> - return I->second;
>>> + return LabelsAfterInsn.lookup(MI);
>>> }
>>>
>>> /// beginInstruction - Process beginning of an instruction.
>>> @@ -2552,14 +2536,22 @@
>>> }
>>>
>>> // Insert labels where requested.
>>> - if (!InsnNeedsLabel.count(MI))
>>> + DenseMap<const MachineInstr*, MCSymbol*>::iterator I =
>>> + LabelsBeforeInsn.find(MI);
>>> +
>>> + // No label needed.
>>> + if (I == LabelsBeforeInsn.end())
>>> + return;
>>> +
>>> + // Label already assigned.
>>> + if (I->second)
>>> return;
>>>
>>> if (!PrevLabel) {
>>> PrevLabel = MMI->getContext().CreateTempSymbol();
>>> Asm->OutStreamer.EmitLabel(PrevLabel);
>>> }
>>> - LabelsBeforeInsn[MI] = PrevLabel;
>>> + I->second = PrevLabel;
>>> }
>>>
>>> /// endInstruction - Process end of an instruction.
>>> @@ -2569,7 +2561,15 @@
>>> if (!MI->isDebugValue())
>>> PrevLabel = 0;
>>>
>>> - if (!InsnsNeedsLabelAfter.count(MI))
>>> + DenseMap<const MachineInstr*, MCSymbol*>::iterator I =
>>> + LabelsAfterInsn.find(MI);
>>> +
>>> + // No label needed.
>>> + if (I == LabelsAfterInsn.end())
>>> + return;
>>> +
>>> + // Label already assigned.
>>> + if (I->second)
>>> return;
>>>
>>> // We need a label after this instruction.
>>> @@ -2577,7 +2577,7 @@
>>> PrevLabel = MMI->getContext().CreateTempSymbol();
>>> Asm->OutStreamer.EmitLabel(PrevLabel);
>>> }
>>> - LabelsAfterInsn[MI] = PrevLabel;
>>> + I->second = PrevLabel;
>>> }
>>>
>>> /// getOrCreateDbgScope - Create DbgScope for the scope.
>>> @@ -2837,8 +2837,8 @@
>>> RE = Ranges.end(); RI != RE; ++RI) {
>>> assert(RI->first && "DbgRange does not have first instruction!");
>>> assert(RI->second && "DbgRange does not have second
>>> instruction!");
>>> - InsnNeedsLabel.insert(RI->first);
>>> - InsnsNeedsLabelAfter.insert(RI->second);
>>> + requestLabelBeforeInsn(RI->first);
>>> + requestLabelAfterInsn(RI->second);
>>> }
>>> }
>>> }
>>> @@ -2916,46 +2916,78 @@
>>>
>>> recordSourceLine(Line, Col, TheScope);
>>>
>>> + assert(UserVariables.empty() && DbgValues.empty() && "Maps weren't
>>> cleaned");
>>> +
>>> /// 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());
>>>
>>> for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
>>> - I != E; ++I)
>>> + I != E; ++I) {
>>> + bool AtBlockEntry = true;
>>> for (MachineBasicBlock::const_iterator II = I->begin(), IE =
>>> I->end();
>>> II != IE; ++II) {
>>> const MachineInstr *MI = II;
>>> - DebugLoc DL = MI->getDebugLoc();
>>> +
>>> if (MI->isDebugValue()) {
>>> assert (MI->getNumOperands() > 1 && "Invalid machine
>>> instruction!");
>>>
>>> - // Keep track of variables in registers.
>>> + // Keep track of user variables.
>>> const MDNode *Var =
>>> MI->getOperand(MI->getNumOperands() - 1).getMetadata();
>>> - LastDbgValue[Var] = MI;
>>> +
>>> + // Variable is in a register, we need to check for clobbers.
>>> 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)
>>> - InsnNeedsLabel.insert(MI);
>>> - // DBG_VALUE for inlined functions argument needs a label.
>>> - else if (!DISubprogram(getDISubprogram(DV.getContext())).
>>> - describes(MF->getFunction()))
>>> - InsnNeedsLabel.insert(MI);
>>> - // DBG_VALUE indicating argument location change needs a label.
>>> - else if (!ProcessedArgs.insert(DV))
>>> - InsnNeedsLabel.insert(MI);
>>> + // Check the history of this variable.
>>> + SmallVectorImpl<const MachineInstr*> &History = DbgValues[Var];
>>> + if (History.empty()) {
>>> + UserVariables.push_back(Var);
>>> + // The first mention of a function argument gets the
>>> FunctionBeginSym
>>> + // label, so arguments are visible when breaking at function
>>> entry.
>>> + DIVariable DV(Var);
>>> + if (DV.Verify() && DV.getTag() == dwarf::DW_TAG_arg_variable
>>> &&
>>> + DISubprogram(getDISubprogram(DV.getContext()))
>>> + .describes(MF->getFunction()))
>>> + LabelsBeforeInsn[MI] = FunctionBeginSym;
>>> + } else {
>>> + // We have seen this variable before. Try to coalesce
>>> DBG_VALUEs.
>>> + const MachineInstr *Prev = History.back();
>>> + if (Prev->isDebugValue()) {
>>> + // Coalesce identical entries at the end of History.
>>> + if (History.size() >= 2 &&
>>> + Prev->isIdenticalTo(History[History.size() - 2]))
>>> + History.pop_back();
>>> +
>>> + // Terminate old register assignments that don't reach MI;
>>> + MachineFunction::const_iterator PrevMBB = Prev->getParent();
>>> + if (PrevMBB != I && (!AtBlockEntry || llvm::next(PrevMBB)
>>> != I) &&
>>> + isDbgValueInDefinedReg(Prev)) {
>>> + // Previous register assignment needs to terminate at the
>>> end of
>>> + // its basic block.
>>> + MachineBasicBlock::const_iterator LastMI =
>>> + PrevMBB->getLastNonDebugInstr();
>>> + if (LastMI == PrevMBB->end())
>>> + // Drop DBG_VALUE for empty range.
>>> + History.pop_back();
>>> + else {
>>> + // Terminate after LastMI.
>>> + History.push_back(LastMI);
>>> + }
>>> + }
>>> + }
>>> + }
>>> + History.push_back(MI);
>>> } else {
>>> + // Not a DBG_VALUE instruction.
>>> + if (!MI->isLabel())
>>> + AtBlockEntry = false;
>>> +
>>> // 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) {
>>> @@ -2970,19 +3002,57 @@
>>> 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())
>>> + DbgValueHistoryMap::iterator HistI = DbgValues.find(Var);
>>> + if (HistI == DbgValues.end())
>>> continue;
>>> - if (!isDbgValueInDefinedReg(Last) ||
>>> - Last->getOperand(0).getReg() != Reg)
>>> + SmallVectorImpl<const MachineInstr*> &History =
>>> HistI->second;
>>> + if (History.empty())
>>> continue;
>>> - // MD is clobbered. Make sure the next instruction gets a
>>> label.
>>> - InsnsNeedsLabelAfter.insert(MI);
>>> - RegClobberInsn[Last] = MI;
>>> + const MachineInstr *Prev = History.back();
>>> + // Sanity-check: Register assignments are terminated at the
>>> end of
>>> + // their block.
>>> + if (!Prev->isDebugValue() || Prev->getParent() !=
>>> MI->getParent())
>>> + continue;
>>> + // Is the variable still in Reg?
>>> + if (!isDbgValueInDefinedReg(Prev) ||
>>> + Prev->getOperand(0).getReg() != Reg)
>>> + continue;
>>> + // Var is clobbered. Make sure the next instruction gets a
>>> label.
>>> + History.push_back(MI);
>>> }
>>> }
>>> }
>>> }
>>> + }
>>> +
>>> + for (DbgValueHistoryMap::iterator I = DbgValues.begin(), E =
>>> DbgValues.end();
>>> + I != E; ++I) {
>>> + SmallVectorImpl<const MachineInstr*> &History = I->second;
>>> + if (History.empty())
>>> + continue;
>>> +
>>> + // Make sure the final register assignments are terminated.
>>> + const MachineInstr *Prev = History.back();
>>> + if (Prev->isDebugValue() && isDbgValueInDefinedReg(Prev)) {
>>> + const MachineBasicBlock *PrevMBB = Prev->getParent();
>>> + MachineBasicBlock::const_iterator LastMI =
>>> PrevMBB->getLastNonDebugInstr();
>>> + if (LastMI == PrevMBB->end())
>>> + // Drop DBG_VALUE for empty range.
>>> + History.pop_back();
>>> + else {
>>> + // Terminate after LastMI.
>>> + History.push_back(LastMI);
>>> + }
>>> + }
>>> + // Request labels for the full history.
>>> + for (unsigned i = 0, e = History.size(); i != e; ++i) {
>>> + const MachineInstr *MI = History[i];
>>> + if (MI->isDebugValue())
>>> + requestLabelBeforeInsn(MI);
>>> + else
>>> + requestLabelAfterInsn(MI);
>>> + }
>>> + }
>>>
>>> PrevInstLoc = DebugLoc();
>>> PrevLabel = FunctionBeginSym;
>>> @@ -3043,13 +3113,12 @@
>>> // Clear debug info
>>> CurrentFnDbgScope = NULL;
>>> CurrentFnArguments.clear();
>>> - InsnNeedsLabel.clear();
>>> DbgVariableToFrameIndexMap.clear();
>>> VarToAbstractVarMap.clear();
>>> DbgVariableToDbgInstMap.clear();
>>> DeleteContainerSeconds(DbgScopeMap);
>>> - InsnsNeedsLabelAfter.clear();
>>> - RegClobberInsn.clear();
>>> + UserVariables.clear();
>>> + DbgValues.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=128327&r1=128326&r2=128327&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
>>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Fri Mar 25 21:19:36
>>> 2011
>>> @@ -218,19 +218,16 @@
>>> /// instruction.
>>> DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
>>>
>>> - /// insnNeedsLabel - Collection of instructions that need a label to
>>> mark
>>> - /// 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;
>>> + /// UserVariables - Every user variable mentioned by a DBG_VALUE
>>> instruction
>>> + /// in order of appearance.
>>> + SmallVector<const MDNode*, 8> UserVariables;
>>> +
>>> + /// DbgValues - For each user variable, keep a list of DBG_VALUE
>>> + /// instructions in order. The list can also contain normal
>>> instructions that
>>> + /// clobber the previous DBG_VALUE.
>>> + typedef DenseMap<const MDNode*, SmallVector<const MachineInstr*, 4> >
>>> + DbgValueHistoryMap;
>>> + DbgValueHistoryMap DbgValues;
>>>
>>> SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
>>>
>>> @@ -570,6 +567,23 @@
>>> /// side table maintained by MMI.
>>> void collectVariableInfoFromMMITable(const MachineFunction * MF,
>>> SmallPtrSet<const MDNode *, 16>
>>> &P);
>>> +
>>> + /// requestLabelBeforeInsn - Ensure that a label will be emitted
>>> before MI.
>>> + void requestLabelBeforeInsn(const MachineInstr *MI) {
>>> + LabelsBeforeInsn.insert(std::make_pair(MI, (MCSymbol*)0));
>>> + }
>>> +
>>> + /// getLabelBeforeInsn - Return Label preceding the instruction.
>>> + const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
>>> +
>>> + /// requestLabelAfterInsn - Ensure that a label will be emitted after
>>> MI.
>>> + void requestLabelAfterInsn(const MachineInstr *MI) {
>>> + LabelsAfterInsn.insert(std::make_pair(MI, (MCSymbol*)0));
>>> + }
>>> +
>>> + /// getLabelAfterInsn - Return Label immediately following the
>>> instruction.
>>> + const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
>>> +
>>> public:
>>>
>>> //===--------------------------------------------------------------------===//
>>> // Main entry points.
>>> @@ -593,12 +607,6 @@
>>> ///
>>> void endFunction(const MachineFunction *MF);
>>>
>>> - /// getLabelBeforeInsn - Return Label preceding the instruction.
>>> - const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
>>> -
>>> - /// getLabelAfterInsn - Return Label immediately following the
>>> instruction.
>>> - const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
>>> -
>>> /// beginInstruction - Process beginning of an instruction.
>>> void beginInstruction(const MachineInstr *MI);
>>>
>>>
>>> Modified: llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll?rev=128327&r1=128326&r2=128327&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll (original)
>>> +++ llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll Fri Mar 25
>>> 21:19:36 2011
>>> @@ -4,7 +4,7 @@
>>>
>>> ;CHECK: Ldebug_loc0:
>>> ;CHECK-NEXT: .quad Lfunc_begin0
>>> -;CHECK-NEXT: .quad Lfunc_end0
>>> +;CHECK-NEXT: .quad L
>>> ;CHECK-NEXT: .short 1 ## Loc expr size
>>> ;CHECK-NEXT: .byte 85 ## DW_OP_reg5
>>> ;CHECK-NEXT: .quad 0
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131029/3d9ff91a/attachment.html>
More information about the llvm-commits
mailing list