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

David Blaikie dblaikie at gmail.com
Sun Aug 31 14:26:22 PDT 2014


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
 





More information about the llvm-commits mailing list