[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 15 11:20:19 PDT 2013


and my pastebin highlighted formatting looked so pretty... then it got
mangled :(


On Tue, Oct 15, 2013 at 11:19 AM, David Blaikie <dblaikie at gmail.com> wrote:

>
>
>
> On Fri, Mar 25, 2011 at 7:19 PM, Jakob Stoklund Olesen <stoklund at 2pi.dk>wrote:
>
>> Author: stoklund
>> Date: Fri Mar 25 21:19:36 2011
>> New Revision: 128327
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=128327&view=rev
>> Log:
>> Collect and coalesce DBG_VALUE instructions before emitting the function.
>>
>> Correctly terminate the range of register DBG_VALUEs when the register is
>> clobbered or when the basic block ends.
>>
>
> 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
>    45.
>
>
> 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/20131015/f5667fa6/attachment.html>


More information about the llvm-commits mailing list