[llvm] r265861 - Support the Nodebug emission kind for DICompileUnits.

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 8 15:43:03 PDT 2016


Author: adrian
Date: Fri Apr  8 17:43:03 2016
New Revision: 265861

URL: http://llvm.org/viewvc/llvm-project?rev=265861&view=rev
Log:
Support the Nodebug emission kind for DICompileUnits.

Sample-based profiling and optimization remarks currently remove
DICompileUnits from llvm.dbg.cu to suppress the emission of debug info
from them. This is somewhat of a hack and only borderline legal IR.

This patch uses the recently introduced NoDebug emission kind in
DICompileUnit to achieve the same result without breaking the Verifier.
A nice side-effect of this change is that it is now possible to combine
NoDebug and regular compile units under LTO.

http://reviews.llvm.org/D18808
<rdar://problem/25427165>

Added:
    llvm/trunk/test/DebugInfo/X86/mixed-nodebug-cu.ll
Modified:
    llvm/trunk/include/llvm/IR/DIBuilder.h
    llvm/trunk/include/llvm/IR/DebugInfo.h
    llvm/trunk/include/llvm/IR/Module.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/lib/IR/DIBuilder.cpp
    llvm/trunk/lib/IR/DebugInfo.cpp
    llvm/trunk/lib/IR/Module.cpp
    llvm/trunk/tools/opt/BreakpointPrinter.cpp

Modified: llvm/trunk/include/llvm/IR/DIBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DIBuilder.h?rev=265861&r1=265860&r2=265861&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DIBuilder.h (original)
+++ llvm/trunk/include/llvm/IR/DIBuilder.h Fri Apr  8 17:43:03 2016
@@ -92,23 +92,13 @@ namespace llvm {
     ///                      out into.
     /// \param Kind          The kind of debug information to generate.
     /// \param DWOId         The DWOId if this is a split skeleton compile unit.
-    /// \param EmitDebugInfo A boolean flag which indicates whether
-    ///                      debug information should be written to
-    ///                      the final output or not. When this is
-    ///                      false, debug information annotations will
-    ///                      be present in the IL but they are not
-    ///                      written to the final assembly or object
-    ///                      file. This supports tracking source
-    ///                      location information in the back end
-    ///                      without actually changing the output
-    ///                      (e.g., when using optimization remarks).
     DICompileUnit *
     createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
                       StringRef Producer, bool isOptimized, StringRef Flags,
                       unsigned RV, StringRef SplitName = StringRef(),
                       DICompileUnit::DebugEmissionKind Kind =
                           DICompileUnit::DebugEmissionKind::FullDebug,
-                      uint64_t DWOId = 0, bool EmitDebugInfo = true);
+                      uint64_t DWOId = 0);
 
     /// Create a file descriptor to hold debugging information
     /// for a file.

Modified: llvm/trunk/include/llvm/IR/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugInfo.h?rev=265861&r1=265860&r2=265861&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DebugInfo.h (original)
+++ llvm/trunk/include/llvm/IR/DebugInfo.h Fri Apr  8 17:43:03 2016
@@ -40,7 +40,7 @@ typedef DenseMap<const MDString *, DITyp
 DISubprogram *getDISubprogram(const MDNode *Scope);
 
 /// \brief Generate map by visiting all retained types.
-DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
+DITypeIdentifierMap generateDITypeIdentifierMap(const Module &M);
 
 /// \brief Strip debug info in the module if it exists.
 ///

Modified: llvm/trunk/include/llvm/IR/Module.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=265861&r1=265860&r2=265861&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Module.h (original)
+++ llvm/trunk/include/llvm/IR/Module.h Fri Apr  8 17:43:03 2016
@@ -626,6 +626,58 @@ public:
     return make_range(named_metadata_begin(), named_metadata_end());
   }
 
+  /// An iterator for DICompileUnits that skips those marked NoDebug.
+  class debug_compile_units_iterator
+      : public std::iterator<std::input_iterator_tag, DICompileUnit *> {
+    NamedMDNode *CUs;
+    unsigned Idx;
+    void SkipNoDebugCUs();
+  public:
+    explicit debug_compile_units_iterator(NamedMDNode *CUs, unsigned Idx)
+        : CUs(CUs), Idx(Idx) {
+      SkipNoDebugCUs();
+    }
+    debug_compile_units_iterator &operator++() {
+      ++Idx;
+      SkipNoDebugCUs();
+      return *this;
+    }
+    debug_compile_units_iterator operator++(int) {
+      debug_compile_units_iterator T(*this);
+      ++Idx;
+      return T;
+    }
+    bool operator==(const debug_compile_units_iterator &I) const {
+      return Idx == I.Idx;
+    }
+    bool operator!=(const debug_compile_units_iterator &I) const {
+      return Idx != I.Idx;
+    }
+    DICompileUnit *operator*() const;
+    DICompileUnit *operator->() const;
+  };
+
+  debug_compile_units_iterator debug_compile_units_begin() const {
+    auto *CUs = getNamedMetadata("llvm.dbg.cu");
+    return debug_compile_units_iterator(CUs, 0);
+  }
+
+  debug_compile_units_iterator debug_compile_units_end() const {
+    auto *CUs = getNamedMetadata("llvm.dbg.cu");
+    return debug_compile_units_iterator(CUs, CUs ? CUs->getNumOperands() : 0);
+  }
+
+  /// Return an iterator for all DICompileUnits listed in this Module's
+  /// llvm.dbg.cu named metadata node and aren't explicitly marked as
+  /// NoDebug.
+  iterator_range<debug_compile_units_iterator> debug_compile_units() const {
+    auto *CUs = getNamedMetadata("llvm.dbg.cu");
+    return make_range(
+        debug_compile_units_iterator(CUs, 0),
+        debug_compile_units_iterator(CUs, CUs ? CUs->getNumOperands() : 0));
+  }
+/// @}
+
   /// Destroy ConstantArrays in LLVMContext if they are not used.
   /// ConstantArrays constructed during linking can cause quadratic memory
   /// explosion. Releasing all unused constants can cause a 20% LTO compile-time
@@ -635,7 +687,6 @@ public:
   /// be called where all uses of the LLVMContext are understood.
   void dropTriviallyDeadConstantArrays();
 
-/// @}
 /// @name Utility functions for printing and dumping Module objects
 /// @{
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=265861&r1=265860&r2=265861&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Fri Apr  8 17:43:03 2016
@@ -466,15 +466,18 @@ void DwarfDebug::beginModule() {
 
   const Module *M = MMI->getModule();
 
-  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
-  if (!CU_Nodes)
-    return;
-  TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
+  TypeIdentifierMap = generateDITypeIdentifierMap(*M);
+  unsigned NumDebugCUs = 0;
+  for (DICompileUnit *CUNode : M->debug_compile_units()) {
+    (void)CUNode;
+    ++NumDebugCUs;
+  }
 
-  SingleCU = CU_Nodes->getNumOperands() == 1;
+  // Tell MMI whether we have debug info.
+  MMI->setDebugInfoAvailability(NumDebugCUs > 0);
+  SingleCU = NumDebugCUs == 1;
 
-  for (MDNode *N : CU_Nodes->operands()) {
-    auto *CUNode = cast<DICompileUnit>(N);
+  for (DICompileUnit *CUNode : M->debug_compile_units()) {
     DwarfCompileUnit &CU = constructDwarfCompileUnit(CUNode);
     for (auto *IE : CUNode->getImportedEntities())
       CU.addImportedEntity(IE);
@@ -500,9 +503,6 @@ void DwarfDebug::beginModule() {
     for (auto *IE : CUNode->getImportedEntities())
       constructAndAddImportedEntityDIE(CU, IE);
   }
-
-  // Tell MMI that we have debug info.
-  MMI->setDebugInfoAvailability(true);
 }
 
 void DwarfDebug::finishVariableDefinitions() {
@@ -538,6 +538,9 @@ void DwarfDebug::collectDeadVariables()
   if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) {
     for (MDNode *N : CU_Nodes->operands()) {
       auto *TheCU = cast<DICompileUnit>(N);
+      if (TheCU->getEmissionKind() == DICompileUnit::NoDebug)
+        continue;
+
       // Construct subprogram DIE and add variables DIEs.
       DwarfCompileUnit *SPCU =
           static_cast<DwarfCompileUnit *>(CUMap.lookup(TheCU));
@@ -1090,7 +1093,10 @@ void DwarfDebug::beginFunction(const Mac
   // includes the directory of the cpp file being built, even when the file name
   // is absolute (such as an <> lookup header)))
   DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
-  assert(TheCU && "Unable to find compile unit!");
+  if (!TheCU)
+    // Once DISubprogram points to the owning CU, we can assert that the CU has
+    // a NoDebug EmissionKind here.
+    return;
   if (Asm->OutStreamer->hasRawTextSupport())
     // Use a single line table if we are generating assembly.
     Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
@@ -1113,7 +1119,10 @@ void DwarfDebug::endFunction(const Machi
       "endFunction should be called with the same function as beginFunction");
 
   if (!MMI->hasDebugInfo() || LScopes.empty() ||
-      !MF->getFunction()->getSubprogram()) {
+      !MF->getFunction()->getSubprogram() ||
+      // Once DISubprogram points to the owning CU, we can check for a
+      // CU with a NoDebug EmissionKind here.
+      !SPMap.lookup(MF->getFunction()->getSubprogram())) {
     // If we don't have a lexical scope for this function then there will
     // be a hole in the range information. Keep note of this by setting the
     // previously used section to nullptr.

Modified: llvm/trunk/lib/IR/DIBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DIBuilder.cpp?rev=265861&r1=265860&r2=265861&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DIBuilder.cpp (original)
+++ llvm/trunk/lib/IR/DIBuilder.cpp Fri Apr  8 17:43:03 2016
@@ -137,7 +137,7 @@ static DIScope *getNonCompileUnitScope(D
 DICompileUnit *DIBuilder::createCompileUnit(
     unsigned Lang, StringRef Filename, StringRef Directory, StringRef Producer,
     bool isOptimized, StringRef Flags, unsigned RunTimeVer, StringRef SplitName,
-    DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId, bool EmitDebugInfo) {
+    DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId) {
 
   assert(((Lang <= dwarf::DW_LANG_Fortran08 && Lang >= dwarf::DW_LANG_C89) ||
           (Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) &&
@@ -152,15 +152,8 @@ DICompileUnit *DIBuilder::createCompileU
       nullptr, nullptr, nullptr, nullptr, nullptr, DWOId);
 
   // Create a named metadata so that it is easier to find cu in a module.
-  // Note that we only generate this when the caller wants to actually
-  // emit debug information. When we are only interested in tracking
-  // source line locations throughout the backend, we prevent codegen from
-  // emitting debug info in the final output by not generating llvm.dbg.cu.
-  if (EmitDebugInfo) {
-    NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
-    NMD->addOperand(CUNode);
-  }
-
+  NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
+  NMD->addOperand(CUNode);
   trackIfUnresolved(CUNode);
   return CUNode;
 }

Modified: llvm/trunk/lib/IR/DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfo.cpp?rev=265861&r1=265860&r2=265861&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DebugInfo.cpp (original)
+++ llvm/trunk/lib/IR/DebugInfo.cpp Fri Apr  8 17:43:03 2016
@@ -39,10 +39,9 @@ DISubprogram *llvm::getDISubprogram(cons
 }
 
 DITypeIdentifierMap
-llvm::generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes) {
+llvm::generateDITypeIdentifierMap(const Module &M) {
   DITypeIdentifierMap Map;
-  for (unsigned CUi = 0, CUe = CU_Nodes->getNumOperands(); CUi != CUe; ++CUi) {
-    auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(CUi));
+  for (DICompileUnit *CU : M.debug_compile_units()) {
     DINodeArray Retain = CU->getRetainedTypes();
     for (unsigned Ti = 0, Te = Retain.size(); Ti != Te; ++Ti) {
       if (!isa<DICompositeType>(Retain[Ti]))
@@ -79,42 +78,38 @@ void DebugInfoFinder::reset() {
 }
 
 void DebugInfoFinder::InitializeTypeMap(const Module &M) {
-  if (!TypeMapInitialized)
-    if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) {
-      TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
-      TypeMapInitialized = true;
-    }
+  if (TypeMapInitialized)
+    return;
+  TypeIdentifierMap = generateDITypeIdentifierMap(M);
+  TypeMapInitialized = true;
 }
 
 void DebugInfoFinder::processModule(const Module &M) {
   InitializeTypeMap(M);
-  if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) {
-    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
-      auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i));
-      addCompileUnit(CU);
-      for (auto *DIG : CU->getGlobalVariables()) {
-        if (addGlobalVariable(DIG)) {
-          processScope(DIG->getScope());
-          processType(DIG->getType().resolve(TypeIdentifierMap));
-        }
+  for (auto *CU : M.debug_compile_units()) {
+    addCompileUnit(CU);
+    for (auto *DIG : CU->getGlobalVariables()) {
+      if (addGlobalVariable(DIG)) {
+        processScope(DIG->getScope());
+        processType(DIG->getType().resolve(TypeIdentifierMap));
       }
-      for (auto *SP : CU->getSubprograms())
+    }
+    for (auto *SP : CU->getSubprograms())
+      processSubprogram(SP);
+    for (auto *ET : CU->getEnumTypes())
+      processType(ET);
+    for (auto *RT : CU->getRetainedTypes())
+      processType(RT);
+    for (auto *Import : CU->getImportedEntities()) {
+      auto *Entity = Import->getEntity().resolve(TypeIdentifierMap);
+      if (auto *T = dyn_cast<DIType>(Entity))
+        processType(T);
+      else if (auto *SP = dyn_cast<DISubprogram>(Entity))
         processSubprogram(SP);
-      for (auto *ET : CU->getEnumTypes())
-        processType(ET);
-      for (auto *RT : CU->getRetainedTypes())
-        processType(RT);
-      for (auto *Import : CU->getImportedEntities()) {
-        auto *Entity = Import->getEntity().resolve(TypeIdentifierMap);
-        if (auto *T = dyn_cast<DIType>(Entity))
-          processType(T);
-        else if (auto *SP = dyn_cast<DISubprogram>(Entity))
-          processSubprogram(SP);
-        else if (auto *NS = dyn_cast<DINamespace>(Entity))
-          processScope(NS->getScope());
-        else if (auto *M = dyn_cast<DIModule>(Entity))
-          processScope(M->getScope());
-      }
+      else if (auto *NS = dyn_cast<DINamespace>(Entity))
+        processScope(NS->getScope());
+      else if (auto *M = dyn_cast<DIModule>(Entity))
+        processScope(M->getScope());
     }
   }
 }

Modified: llvm/trunk/lib/IR/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Module.cpp?rev=265861&r1=265860&r2=265861&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Module.cpp (original)
+++ llvm/trunk/lib/IR/Module.cpp Fri Apr  8 17:43:03 2016
@@ -19,6 +19,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/GVMaterializer.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/LLVMContext.h"
@@ -380,6 +381,19 @@ void Module::setDataLayout(const DataLay
 
 const DataLayout &Module::getDataLayout() const { return DL; }
 
+DICompileUnit *Module::debug_compile_units_iterator::operator*() const {
+  return cast<DICompileUnit>(CUs->getOperand(Idx));
+}
+DICompileUnit *Module::debug_compile_units_iterator::operator->() const {
+  return cast<DICompileUnit>(CUs->getOperand(Idx));
+}
+
+void Module::debug_compile_units_iterator::SkipNoDebugCUs() {
+  while (CUs && (Idx < CUs->getNumOperands()) &&
+         ((*this)->getEmissionKind() == DICompileUnit::NoDebug))
+    ++Idx;
+}
+
 //===----------------------------------------------------------------------===//
 // Methods to control the materialization of GlobalValues in the Module.
 //

Added: llvm/trunk/test/DebugInfo/X86/mixed-nodebug-cu.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/mixed-nodebug-cu.ll?rev=265861&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/mixed-nodebug-cu.ll (added)
+++ llvm/trunk/test/DebugInfo/X86/mixed-nodebug-cu.ll Fri Apr  8 17:43:03 2016
@@ -0,0 +1,50 @@
+; RUN: llc %s -o %t -filetype=obj
+; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s
+; CHECK: DW_TAG_compile_unit
+; CHECK:   DW_TAG_subprogram
+; CHECK:     DW_AT_name{{.*}}"f"
+; CHECK-NOT: DW_TAG_compile_unit
+;
+; created from
+;   void f() {} // compile with -g
+;   void g() {} // compile with -Rpass=inline
+; and llvm-linking the result.
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+; Function Attrs: nounwind ssp uwtable
+define void @f() #0 !dbg !4 {
+entry:
+  ret void, !dbg !15
+}
+
+; Function Attrs: nounwind ssp uwtable
+define void @g() #0 !dbg !9 {
+entry:
+  ret void, !dbg !16
+}
+
+attributes #0 = { nounwind ssp uwtable }
+
+!llvm.dbg.cu = !{!0, !7}
+!llvm.ident = !{!11, !11}
+!llvm.module.flags = !{!12, !13, !14}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 265328) (llvm/trunk 265330)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, subprograms: !3)
+!1 = !DIFile(filename: "test.c", directory: "/Volumes/Data/llvm")
+!2 = !{}
+!3 = !{!4}
+!4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, variables: !2)
+!5 = !DISubroutineType(types: !6)
+!6 = !{null}
+!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 265328) (llvm/trunk 265330)", isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug, enums: !2, subprograms: !8)
+!8 = !{!9}
+!9 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 1, type: !10, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, variables: !2)
+!10 = !DISubroutineType(types: !2)
+!11 = !{!"clang version 3.9.0 (trunk 265328) (llvm/trunk 265330)"}
+!12 = !{i32 2, !"Dwarf Version", i32 2}
+!13 = !{i32 2, !"Debug Info Version", i32 3}
+!14 = !{i32 1, !"PIC Level", i32 2}
+!15 = !DILocation(line: 1, column: 12, scope: !4)
+!16 = !DILocation(line: 1, column: 12, scope: !9)

Modified: llvm/trunk/tools/opt/BreakpointPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/BreakpointPrinter.cpp?rev=265861&r1=265860&r2=265861&view=diff
==============================================================================
--- llvm/trunk/tools/opt/BreakpointPrinter.cpp (original)
+++ llvm/trunk/tools/opt/BreakpointPrinter.cpp Fri Apr  8 17:43:03 2016
@@ -45,9 +45,7 @@ struct BreakpointPrinter : public Module
 
   bool runOnModule(Module &M) override {
     TypeIdentifierMap.clear();
-    NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu");
-    if (CU_Nodes)
-      TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
+    TypeIdentifierMap = generateDITypeIdentifierMap(M);
 
     StringSet<> Processed;
     if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp"))




More information about the llvm-commits mailing list