aprantl removed rL LLVM as the repository for this revision.
aprantl updated this revision to Diff 52842.
aprantl added a comment.
This patch adds a DICompileUnit iterator to Module that skips over NoDebug CUs.
http://reviews.llvm.org/D18808
Files:
include/llvm/IR/DIBuilder.h
include/llvm/IR/DebugInfo.h
include/llvm/IR/Module.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/IR/DIBuilder.cpp
lib/IR/DebugInfo.cpp
lib/IR/Module.cpp
test/DebugInfo/X86/mixed-nodebug-cu.ll
tools/clang/lib/CodeGen/CGDebugInfo.cpp
tools/clang/test/Frontend/optimization-remark.c
tools/clang/test/Frontend/profile-sample-use-loc-tracking.c
tools/opt/BreakpointPrinter.cpp
Index: tools/clang/test/Frontend/profile-sample-use-loc-tracking.c
===================================================================
--- tools/clang/test/Frontend/profile-sample-use-loc-tracking.c
+++ tools/clang/test/Frontend/profile-sample-use-loc-tracking.c
@@ -10,9 +10,10 @@
// CHECK: , !dbg !
// CHECK-NOT: DW_TAG_base_type
-// But llvm.dbg.cu should be missing (to prevent writing debug info to
+// The CU should be marked NoDebug (to prevent writing debug info to
// the final output).
-// CHECK-NOT: !llvm.dbg.cu = !{
+// CHECK: !llvm.dbg.cu = !{![[CU:.*]]}
+// CHECK: ![[CU]] = distinct !DICompileUnit({{.*}}emissionKind: NoDebug
int bar(int j) {
return (j + j - 2) * (j - 2) * j;
Index: tools/clang/test/Frontend/optimization-remark.c
===================================================================
--- tools/clang/test/Frontend/optimization-remark.c
+++ tools/clang/test/Frontend/optimization-remark.c
@@ -27,9 +27,10 @@
// CHECK: , !dbg !
// CHECK-NOT: DW_TAG_base_type
-// But llvm.dbg.cu should be missing (to prevent writing debug info to
+// The CU should be marked NoDebug (to prevent writing debug info to
// the final output).
-// CHECK-NOT: !llvm.dbg.cu = !{
+// CHECK: !llvm.dbg.cu = !{![[CU:.*]]}
+// CHECK: ![[CU]] = distinct !DICompileUnit({{.*}}emissionKind: NoDebug
int foo(int x, int y) __attribute__((always_inline));
int foo(int x, int y) { return x + y; }
Index: tools/clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- tools/clang/lib/CodeGen/CGDebugInfo.cpp
+++ tools/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -396,16 +396,27 @@
if (LO.ObjC1)
RuntimeVers = LO.ObjCRuntime.isNonFragile() ? 2 : 1;
+ llvm::DICompileUnit::DebugEmissionKind EmissionKind;
+ switch (DebugKind) {
+ case codegenoptions::NoDebugInfo:
+ case codegenoptions::LocTrackingOnly:
+ EmissionKind = llvm::DICompileUnit::NoDebug;
+ break;
+ case codegenoptions::DebugLineTablesOnly:
+ EmissionKind = llvm::DICompileUnit::LineTablesOnly;
+ break;
+ case codegenoptions::LimitedDebugInfo:
+ case codegenoptions::FullDebugInfo:
+ EmissionKind = llvm::DICompileUnit::FullDebug;
+ break;
+ }
+
// Create new compile unit.
// FIXME - Eliminate TheCU.
TheCU = DBuilder.createCompileUnit(
LangTag, remapDIPath(MainFileName), remapDIPath(getCurrentDirname()),
Producer, LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers,
- CGM.getCodeGenOpts().SplitDwarfFile,
- DebugKind <= codegenoptions::DebugLineTablesOnly
- ? llvm::DICompileUnit::LineTablesOnly
- : llvm::DICompileUnit::FullDebug,
- 0 /* DWOid */, DebugKind != codegenoptions::LocTrackingOnly);
+ CGM.getCodeGenOpts().SplitDwarfFile, EmissionKind, 0 /* DWOid */);
}
llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
Index: tools/opt/BreakpointPrinter.cpp
===================================================================
--- tools/opt/BreakpointPrinter.cpp
+++ tools/opt/BreakpointPrinter.cpp
@@ -45,9 +45,7 @@
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"))
Index: test/DebugInfo/X86/mixed-nodebug-cu.ll
===================================================================
--- /dev/null
+++ test/DebugInfo/X86/mixed-nodebug-cu.ll
@@ -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)
Index: lib/IR/Module.cpp
===================================================================
--- lib/IR/Module.cpp
+++ lib/IR/Module.cpp
@@ -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"
@@ -374,6 +375,19 @@
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.
//
Index: lib/IR/DebugInfo.cpp
===================================================================
--- lib/IR/DebugInfo.cpp
+++ lib/IR/DebugInfo.cpp
@@ -39,10 +39,9 @@
}
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::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());
}
}
}
Index: lib/IR/DIBuilder.cpp
===================================================================
--- lib/IR/DIBuilder.cpp
+++ lib/IR/DIBuilder.cpp
@@ -137,7 +137,7 @@
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 @@
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;
}
Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp
===================================================================
--- lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -466,15 +466,16 @@
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())
+ ++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 +501,6 @@
for (auto *IE : CUNode->getImportedEntities())
constructAndAddImportedEntityDIE(CU, IE);
}
-
- // Tell MMI that we have debug info.
- MMI->setDebugInfoAvailability(true);
}
void DwarfDebug::finishVariableDefinitions() {
@@ -538,6 +536,9 @@
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 +1091,10 @@
// 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 +1117,10 @@
"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.
Index: include/llvm/IR/Module.h
===================================================================
--- include/llvm/IR/Module.h
+++ include/llvm/IR/Module.h
@@ -583,6 +583,58 @@
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
@@ -592,7 +644,6 @@
/// be called where all uses of the LLVMContext are understood.
void dropTriviallyDeadConstantArrays();
-/// @}
/// @name Utility functions for printing and dumping Module objects
/// @{
Index: include/llvm/IR/DebugInfo.h
===================================================================
--- include/llvm/IR/DebugInfo.h
+++ include/llvm/IR/DebugInfo.h
@@ -40,7 +40,7 @@
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.
///
Index: include/llvm/IR/DIBuilder.h
===================================================================
--- include/llvm/IR/DIBuilder.h
+++ include/llvm/IR/DIBuilder.h
@@ -92,23 +92,13 @@
/// 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.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits