[llvm] r216861 - DebugInfo: Elide lexical scopes which only contain other (inline or lexical) scopes.

David Blaikie dblaikie at gmail.com
Tue Sep 2 16:19:43 PDT 2014


On Tue, Sep 2, 2014 at 4:12 PM, Kostya Serebryany <kcc at google.com> wrote:

>
>
>
> On Sun, Aug 31, 2014 at 2:40 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
>> Not sure if you guys have found binary size of -gmlt to be an issue - but
>> if you have, this might be of interest.
>>
>
> For -gline-tables-only we did see issues with binary size, but then Alexey
> added compression and the issue reduced significantly, IIRC
>

Ah, good call :) Yeah, with compression on I doubt my change makes much
difference (might have to check, though, just out of curiosity). Maybe
minor linking time improvements due to fewer relocations... maybe.

- David


>
>
>>
>> (the numbers here are uncompressed debug info)
>>
>>
>> On Sun, Aug 31, 2014 at 2:26 PM, David Blaikie <dblaikie at gmail.com>
>> wrote:
>>
>>> Author: dblaikie
>>> Date: Sun Aug 31 16:26:22 2014
>>> New Revision: 216861
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=216861&view=rev
>>> Log:
>>> DebugInfo: Elide lexical scopes which only contain other (inline or
>>> lexical) scopes.
>>>
>>> DW_TAG_lexical_scopes inform debuggers about the instruction range for
>>> which a given variable (or imported declaration/module/etc) is valid. If
>>> the scope doesn't itself contain any such entities, it's a waste of
>>> space and should be omitted.
>>>
>>> We were correctly doing this for entirely empty leaves, but not for
>>> intermediate nodes.
>>>
>>> Reduces total (not just debug sections) .o file size for a bootstrap
>>> -gmlt LLVM by 22% and bootstrap -gmlt clang executable by 13%. The wins
>>> for a full -g build will be less as a % (and in absolute terms), but
>>> should still be substantial - with some of that win being fewer
>>> relocations, thus more substantiall reducing link times than fewer bytes
>>> alone would have.
>>>
>>> Modified:
>>>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
>>>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
>>>     llvm/trunk/test/DebugInfo/PR20038.ll
>>>     llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll
>>>     llvm/trunk/test/DebugInfo/X86/fission-ranges.ll
>>>     llvm/trunk/test/DebugInfo/missing-abstract-variable.ll
>>>
>>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=216861&r1=216860&r2=216861&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
>>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Sun Aug 31 16:26:22
>>> 2014
>>> @@ -455,15 +455,21 @@ static std::unique_ptr<DIE> constructVar
>>>
>>>  DIE *DwarfDebug::createScopeChildrenDIE(
>>>      DwarfCompileUnit &TheCU, LexicalScope *Scope,
>>> -    SmallVectorImpl<std::unique_ptr<DIE>> &Children) {
>>> +    SmallVectorImpl<std::unique_ptr<DIE>> &Children,
>>> +    unsigned *ChildScopeCount) {
>>>    DIE *ObjectPointer = nullptr;
>>>
>>>    for (DbgVariable *DV : ScopeVariables.lookup(Scope))
>>>      Children.push_back(constructVariableDIE(TheCU, *DV, *Scope,
>>> ObjectPointer));
>>>
>>> +  unsigned ChildCountWithoutScopes = Children.size();
>>> +
>>>    for (LexicalScope *LS : Scope->getChildren())
>>> -    if (std::unique_ptr<DIE> Nested = constructScopeDIE(TheCU, LS))
>>> -      Children.push_back(std::move(Nested));
>>> +    constructScopeDIE(TheCU, LS, Children);
>>> +
>>> +  if (ChildScopeCount)
>>> +    *ChildScopeCount = Children.size() - ChildCountWithoutScopes;
>>> +
>>>    return ObjectPointer;
>>>  }
>>>
>>> @@ -565,10 +571,11 @@ DIE &DwarfDebug::constructSubprogramScop
>>>  }
>>>
>>>  // Construct a DIE for this scope.
>>> -std::unique_ptr<DIE> DwarfDebug::constructScopeDIE(DwarfCompileUnit
>>> &TheCU,
>>> -                                                   LexicalScope *Scope)
>>> {
>>> +void DwarfDebug::constructScopeDIE(
>>> +    DwarfCompileUnit &TheCU, LexicalScope *Scope,
>>> +    SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren) {
>>>    if (!Scope || !Scope->getScopeNode())
>>> -    return nullptr;
>>> +    return;
>>>
>>>    DIScope DS(Scope->getScopeNode());
>>>
>>> @@ -586,17 +593,19 @@ std::unique_ptr<DIE> DwarfDebug::constru
>>>    if (Scope->getParent() && DS.isSubprogram()) {
>>>      ScopeDIE = constructInlinedScopeDIE(TheCU, Scope);
>>>      if (!ScopeDIE)
>>> -      return nullptr;
>>> +      return;
>>>      // We create children when the scope DIE is not null.
>>>      createScopeChildrenDIE(TheCU, Scope, Children);
>>>    } else {
>>>      // Early exit when we know the scope DIE is going to be null.
>>>      if (isLexicalScopeDIENull(Scope))
>>> -      return nullptr;
>>> +      return;
>>> +
>>> +    unsigned ChildScopeCount;
>>>
>>>      // We create children here when we know the scope DIE is not going
>>> to be
>>>      // null and the children will be added to the scope DIE.
>>> -    createScopeChildrenDIE(TheCU, Scope, Children);
>>> +    createScopeChildrenDIE(TheCU, Scope, Children, &ChildScopeCount);
>>>
>>>      // There is no need to emit empty lexical block DIE.
>>>      std::pair<ImportedEntityMap::const_iterator,
>>> @@ -609,8 +618,14 @@ std::unique_ptr<DIE> DwarfDebug::constru
>>>           ++i)
>>>        Children.push_back(
>>>            constructImportedEntityDIE(TheCU,
>>> DIImportedEntity(i->second)));
>>> -    if (Children.empty())
>>> -      return nullptr;
>>> +    // If there are only other scopes as children, put them directly in
>>> the
>>> +    // parent instead, as this scope would serve no purpose.
>>> +    if (Children.size() == ChildScopeCount) {
>>> +      FinalChildren.insert(FinalChildren.end(),
>>> +                           std::make_move_iterator(Children.begin()),
>>> +                           std::make_move_iterator(Children.end()));
>>> +      return;
>>> +    }
>>>      ScopeDIE = constructLexicalScopeDIE(TheCU, Scope);
>>>      assert(ScopeDIE && "Scope DIE should not be null.");
>>>    }
>>> @@ -619,7 +634,7 @@ std::unique_ptr<DIE> DwarfDebug::constru
>>>    for (auto &I : Children)
>>>      ScopeDIE->addChild(std::move(I));
>>>
>>> -  return ScopeDIE;
>>> +  FinalChildren.push_back(std::move(ScopeDIE));
>>>  }
>>>
>>>  void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const {
>>>
>>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=216861&r1=216860&r2=216861&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
>>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Sun Aug 31 16:26:22
>>> 2014
>>> @@ -377,8 +377,8 @@ class DwarfDebug : public AsmPrinterHand
>>>                                                  LexicalScope *Scope);
>>>
>>>    /// \brief Construct a DIE for this scope.
>>> -  std::unique_ptr<DIE> constructScopeDIE(DwarfCompileUnit &TheCU,
>>> -                                         LexicalScope *Scope);
>>> +  void constructScopeDIE(DwarfCompileUnit &TheCU, LexicalScope *Scope,
>>> +                         SmallVectorImpl<std::unique_ptr<DIE>>
>>> &FinalChildren);
>>>    DIE *createAndAddScopeChildren(DwarfCompileUnit &TheCU, LexicalScope
>>> *Scope,
>>>                                   DIE &ScopeDIE);
>>>    /// \brief Construct a DIE for this abstract scope.
>>> @@ -389,7 +389,8 @@ class DwarfDebug : public AsmPrinterHand
>>>                                     LexicalScope *Scope);
>>>    /// A helper function to create children of a Scope DIE.
>>>    DIE *createScopeChildrenDIE(DwarfCompileUnit &TheCU, LexicalScope
>>> *Scope,
>>> -                              SmallVectorImpl<std::unique_ptr<DIE>>
>>> &Children);
>>> +                              SmallVectorImpl<std::unique_ptr<DIE>>
>>> &Children,
>>> +                              unsigned *ChildScopeCount = nullptr);
>>>
>>>    /// \brief Emit initial Dwarf sections with a label at the start of
>>> each one.
>>>    void emitSectionLabels();
>>>
>>> Modified: llvm/trunk/test/DebugInfo/PR20038.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PR20038.ll?rev=216861&r1=216860&r2=216861&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/test/DebugInfo/PR20038.ll (original)
>>> +++ llvm/trunk/test/DebugInfo/PR20038.ll Sun Aug 31 16:26:22 2014
>>> @@ -30,23 +30,19 @@
>>>  ; CHECK-NOT: DW_TAG
>>>  ; CHECK:   DW_AT_name {{.*}} "fun4"
>>>  ; CHECK-NOT: {{DW_TAG|NULL}}
>>> -; CHECK:   DW_TAG_lexical_block
>>> -; CHECK-NOT: {{DW_TAG|NULL}}
>>> -; CHECK:     DW_TAG_inlined_subroutine
>>> +; CHECK:   DW_TAG_inlined_subroutine
>>>  ; CHECK-NOT: DW_TAG
>>> -; CHECK:       DW_AT_abstract_origin {{.*}} {[[D1_ABS]]}
>>> +; CHECK:     DW_AT_abstract_origin {{.*}} {[[D1_ABS]]}
>>>  ; CHECK-NOT: {{DW_TAG|NULL}}
>>> -; CHECK:       DW_TAG_formal_parameter
>>> +; CHECK:     DW_TAG_formal_parameter
>>>  ; CHECK-NOT: DW_TAG
>>> -; CHECK:         DW_AT_abstract_origin {{.*}} {[[D1_THIS_ABS]]}
>>> +; CHECK:       DW_AT_abstract_origin {{.*}} {[[D1_THIS_ABS]]}
>>>
>>>  ; FIXME: D2 is actually inlined into D1 but doesn't show up here,
>>> possibly due
>>>  ; to there being no work in D2 (calling another member function from
>>> the dtor
>>>  ; causes D2 to show up, calling a free function doesn't).
>>>
>>>  ; CHECK-NOT: DW_TAG
>>> -; CHECK:       NULL
>>> -; CHECK-NOT: DW_TAG
>>>  ; CHECK:     NULL
>>>  ; CHECK-NOT: DW_TAG
>>>  ; CHECK:   NULL
>>>
>>> Modified: llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll?rev=216861&r1=216860&r2=216861&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll (original)
>>> +++ llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll Sun Aug 31
>>> 16:26:22 2014
>>> @@ -32,9 +32,6 @@
>>>  ; CHECK: DW_TAG_formal_parameter
>>>  ; CHECK-NOT: NULL
>>>  ; CHECK-NOT: DW_TAG
>>> -; CHECK: DW_TAG_lexical_block
>>> -; CHECK-NOT: NULL
>>> -; CHECK-NOT: DW_TAG
>>>  ; CHECK: DW_TAG_inlined_subroutine
>>>  ; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[ASSIGN:0x........]]}
>>>  ; CHECK-NOT: NULL
>>>
>>> Modified: llvm/trunk/test/DebugInfo/X86/fission-ranges.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/fission-ranges.ll?rev=216861&r1=216860&r2=216861&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/test/DebugInfo/X86/fission-ranges.ll (original)
>>> +++ llvm/trunk/test/DebugInfo/X86/fission-ranges.ll Sun Aug 31 16:26:22
>>> 2014
>>> @@ -16,7 +16,7 @@
>>>  ; CHECK: DW_AT_location [DW_FORM_sec_offset]   ([[E:0x[0-9a-z]*]])
>>>  ; CHECK: DW_AT_location [DW_FORM_sec_offset]   ([[B:0x[0-9a-z]*]])
>>>  ; CHECK: DW_AT_location [DW_FORM_sec_offset]   ([[D:0x[0-9a-z]*]])
>>> -; CHECK: DW_AT_ranges [DW_FORM_sec_offset]   (0x000000a0)
>>> +; CHECK: DW_AT_ranges [DW_FORM_sec_offset]   (0x00000000)
>>>  ; CHECK: .debug_loc contents:
>>>  ; CHECK-NOT: Beginning address offset
>>>  ; CHECK: .debug_loc.dwo contents:
>>>
>>> Modified: llvm/trunk/test/DebugInfo/missing-abstract-variable.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/missing-abstract-variable.ll?rev=216861&r1=216860&r2=216861&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/test/DebugInfo/missing-abstract-variable.ll (original)
>>> +++ llvm/trunk/test/DebugInfo/missing-abstract-variable.ll Sun Aug 31
>>> 16:26:22 2014
>>> @@ -45,8 +45,6 @@
>>>  ; CHECK-NOT: DW_TAG
>>>  ; CHECK:     DW_AT_name {{.*}} "b"
>>>  ; CHECK-NOT: {{DW_TAG|NULL}}
>>> -; CHECK:     DW_TAG_lexical_block
>>> -; CHECK-NOT: {{DW_TAG|NULL}}
>>>  ; CHECK:       DW_TAG_lexical_block
>>>  ; CHECK-NOT: {{DW_TAG|NULL}}
>>>  ; CHECK: [[ABS_S:.*]]:       DW_TAG_variable
>>> @@ -89,19 +87,12 @@
>>>  ; CHECK-NOT: DW_TAG
>>>  ; CHECK:       DW_AT_abstract_origin {{.*}} {[[ABS_B]]}
>>>
>>> -; The two lexical blocks here are caused by the scope of the if that
>>> includes
>>> -; the condition variable, and the scope within the if's composite
>>> statement. I'm
>>> -; not sure we really need both of them since there's no variable
>>> declared in the
>>> -; outer of the two
>>> -
>>>  ; CHECK-NOT: {{DW_TAG|NULL}}
>>>  ; CHECK:     DW_TAG_lexical_block
>>>  ; CHECK-NOT: {{DW_TAG|NULL}}
>>> -; CHECK:       DW_TAG_lexical_block
>>> -; CHECK-NOT: {{DW_TAG|NULL}}
>>> -; CHECK:         DW_TAG_variable
>>> +; CHECK:       DW_TAG_variable
>>>  ; CHECK-NOT: DW_TAG
>>> -; CHECK:           DW_AT_abstract_origin {{.*}} {[[ABS_S]]}
>>> +; CHECK:         DW_AT_abstract_origin {{.*}} {[[ABS_S]]}
>>>
>>>  @t = external global i32
>>>
>>>
>>>
>>> _______________________________________________
>>> 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/20140902/bdb369c5/attachment.html>


More information about the llvm-commits mailing list