[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