[LLVMdev] Minimizing -gmlt

David Blaikie dblaikie at gmail.com
Wed Aug 27 16:40:59 PDT 2014


In an effort to fix inlined information for backtraces under DWARF Fission
in the absence of the split DWARF (.dwo) files, I'm planning on adding
-gmlt-like data to the .o file, alongside the skeleton CU.

Since that will involve teaching the LLVM about -gmlt (moreso than it
already has - the debug info LLVM metadata already describes -gmlt for the
purposes of omitting pubnames in that case) I figured I'd take the
opportunity to move the existing -gmlt functionality to the backend to
begin with, and, in doing so, minimize it a little further since we
wouldn't need to emit debug info for every function - possibly just those
that have functions inlined into them.

So here's an example of some of my ideas about minimized debug info. I'm
wondering if I'm right about what's needed for backtracing.

I've removed uninteresting things, like DW_AT_accessibility (which is a bug
anyway), DW_AT_external (there's no reason symbolication needs that, is
there?), but also less obviously uninteresting things like DW_AT_frame_base
(the location of the frame pointer - is that needed for symbolication?)

Also I've made a frontend (for now) change (see mgmlt_clang.diff) to omit
the data that causes DW_AT_decl_file/DW_AT_decl_line to be emitted - are
those needed? I don't think so.

But importantly: the only DW_TAG_subprograms are either functions that have
been inlined, or functions that have been inlined into. Is that enough?

Is it OK that I haven't included debug info for out of line definitions of
inline functions?

I'm assuming all that information can be retrieved from the symbol table.

(one other thing I noticed is that we don't use the mangled names for
functions in -gmlt - how on earth does that work? The backtrace would look
really strange if it included the unmangled names of functions - or does
the symbolizer use the address range of the out of line definition (if
there is one?) of the inlined function (in which case I'd need to provide
it... ) to find it in the symbol table, get the mangled name, and use that?)

One thing I was thinking of doing as well, is that since the
DW_AT_abstract_origin just points to a trivial subprogram with a name and
DW_AT_inline - perhaps instead of an abstract origin, we could just use
DW_AT_name directly? (with the mangled name, probably) That'd save us
emitting the extra indirection and the name is uniqued already anyway. (and
DW_FORM_strp is the same size as DW_FORM_ref4 (though DW_FORM_strp would
mean extra relocations...) - and perhaps in the near future, DW_FORM_strp
could be replaced by DW_FORM_str_index to reduce relocations)

So... yes/no/maybe?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140827/81edfe40/attachment.html>
-------------- next part --------------
diff --git lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.cpp
index 0b20f54..e3f23c4 100644
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -2534,8 +2534,12 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD,
     if (Loc.isInvalid())
       CurLoc = SourceLocation();
   }
-  unsigned LineNo = getLineNumber(Loc);
-  unsigned ScopeLine = getLineNumber(ScopeLoc);
+  unsigned LineNo = 0;
+  unsigned ScopeLine = 0;
+  if (DebugKind > CodeGenOptions::DebugLineTablesOnly) {
+    LineNo = getLineNumber(Loc);
+    ScopeLine = getLineNumber(ScopeLoc);
+  }
 
   // FIXME: The function declaration we're constructing here is mostly reusing
   // declarations from CXXMethodDecl and not constructing new ones for arbitrary
diff --git test/CodeGenCXX/debug-info-blocks.cpp test/CodeGenCXX/debug-info-blocks.cpp
index 5b20db5..207e2b0 100644
--- test/CodeGenCXX/debug-info-blocks.cpp
+++ test/CodeGenCXX/debug-info-blocks.cpp
@@ -10,5 +10,5 @@ void test() {
   __block A a;
 }
 
-// CHECK: [ DW_TAG_subprogram ] [line 10] [local] [def] [__Block_byref_object_copy_]
-// CHECK: [ DW_TAG_subprogram ] [line 10] [local] [def] [__Block_byref_object_dispose_]
+// CHECK: [ DW_TAG_subprogram ] [line 0] [local] [def] [__Block_byref_object_copy_]
+// CHECK: [ DW_TAG_subprogram ] [line 0] [local] [def] [__Block_byref_object_dispose_]
-------------- next part --------------
diff --git lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 58bc96d..da48e24 100644
--- lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -319,9 +319,12 @@ DIE &DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit &SPCU,
 
   attachLowHighPC(SPCU, *SPDie, FunctionBeginSym, FunctionEndSym);
 
-  const TargetRegisterInfo *RI = Asm->TM.getSubtargetImpl()->getRegisterInfo();
-  MachineLocation Location(RI->getFrameRegister(*Asm->MF));
-  SPCU.addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
+  if (SPCU.getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly) {
+    const TargetRegisterInfo *RI =
+        Asm->TM.getSubtargetImpl()->getRegisterInfo();
+    MachineLocation Location(RI->getFrameRegister(*Asm->MF));
+    SPCU.addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
+  }
 
   // Add name to the name table, we do this here because we're guaranteed
   // to have concrete versions of our DW_TAG_subprogram nodes.
@@ -751,6 +754,11 @@ void DwarfDebug::beginModule() {
   for (MDNode *N : CU_Nodes->operands()) {
     DICompileUnit CUNode(N);
     DwarfCompileUnit &CU = constructDwarfCompileUnit(CUNode);
+    DIArray SPs = CUNode.getSubprograms();
+    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i)
+      SPMap.insert(std::make_pair(SPs.getElement(i), &CU));
+    if (CU.getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly)
+      continue;
     DIArray ImportedEntities = CUNode.getImportedEntities();
     for (unsigned i = 0, e = ImportedEntities.getNumElements(); i != e; ++i)
       ScopesWithImportedEntities.push_back(std::make_pair(
@@ -761,9 +769,6 @@ void DwarfDebug::beginModule() {
     DIArray GVs = CUNode.getGlobalVariables();
     for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i)
       CU.createGlobalVariableDIE(DIGlobalVariable(GVs.getElement(i)));
-    DIArray SPs = CUNode.getSubprograms();
-    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i)
-      SPMap.insert(std::make_pair(SPs.getElement(i), &CU));
     DIArray EnumTypes = CUNode.getEnumTypes();
     for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) {
       DIType Ty(EnumTypes.getElement(i));
@@ -833,12 +838,13 @@ void DwarfDebug::finishSubprogramDefinitions() {
           // If this subprogram has an abstract definition, reference that
           SPCU->addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
       } else {
-        if (!D)
+        if (!D && TheCU.getEmissionKind() != DIBuilder::LineTablesOnly)
           // Lazily construct the subprogram if we didn't see either concrete or
           // inlined versions during codegen.
           D = SPCU->getOrCreateSubprogramDIE(SP);
-        // And attach the attributes
-        SPCU->applySubprogramAttributesToDefinition(SP, *D);
+        if (D)
+          // And attach the attributes
+          SPCU->applySubprogramAttributesToDefinition(SP, *D);
       }
     }
   }
@@ -1670,6 +1676,17 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
 
   LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
   DwarfCompileUnit &TheCU = *SPMap.lookup(FnScope->getScopeNode());
+  if (TheCU.getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly && LScopes.getAbstractScopesList().empty()) {
+    assert(ScopeVariables.empty());
+    assert(CurrentFnArguments.empty());
+    assert(DbgValues.empty());
+    assert(AbstractVariables.empty());
+    LabelsBeforeInsn.clear();
+    LabelsAfterInsn.clear();
+    PrevLabel = nullptr;
+    CurFn = nullptr;
+    return;
+  }
 
   // Construct abstract scopes.
   for (LexicalScope *AScope : LScopes.getAbstractScopesList()) {
diff --git lib/CodeGen/AsmPrinter/DwarfUnit.cpp lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index e0be080..78ac1e6 100644
--- lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1518,6 +1518,9 @@ void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie) {
     constructSubprogramArguments(SPDie, Args);
   }
 
+  if(getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly)
+    return;
+
   if (SP.isArtificial())
     addFlag(SPDie, dwarf::DW_AT_artificial);
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: funcs.cpp
Type: text/x-c++src
Size: 175 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140827/81edfe40/attachment.cpp>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: funcs.s
Type: application/octet-stream
Size: 9751 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140827/81edfe40/attachment.obj>


More information about the llvm-dev mailing list