Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -706,6 +706,10 @@ DIE *SPDIE = DU->getAbstractSPDies().lookup(SP); if (!SPDIE) SPDIE = getDIE(SP); + // Don't do this if the function is not referenced by either an + // abstract scope or an llvm::Function. + if (!SPDIE) + return; assert(SPDIE); for (const DILocalVariable *DV : Variables) { DbgVariable NewVar(DV, /* IA */ nullptr, DD); Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -527,29 +527,10 @@ void DwarfDebug::finishSubprogramDefinitions() { for (const auto &P : SPMap) - forBothCUs(*P.second, [&](DwarfCompileUnit &CU) { - CU.finishSubprogramDefinition(cast(P.first)); - }); -} - -// Collect info for variables that were optimized out. -void DwarfDebug::collectDeadVariables() { - const Module *M = MMI->getModule(); - - if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) { - for (MDNode *N : CU_Nodes->operands()) { - auto *TheCU = cast(N); - // Construct subprogram DIE and add variables DIEs. - DwarfCompileUnit *SPCU = - static_cast(CUMap.lookup(TheCU)); - assert(SPCU && "Unable to find Compile Unit!"); - for (auto *SP : TheCU->getSubprograms()) { - if (ProcessedSPNodes.count(SP) != 0) - continue; - SPCU->collectDeadVariables(SP); - } - } - } + if (ProcessedSPNodes.count(P.first)) + forBothCUs(*P.second, [&](DwarfCompileUnit &CU) { + CU.finishSubprogramDefinition(cast(P.first)); + }); } void DwarfDebug::finalizeModuleInfo() { @@ -559,9 +540,6 @@ finishVariableDefinitions(); - // Collect info for variables that were optimized out. - collectDeadVariables(); - // Handle anything that needs to be done on a per-unit basis after // all other generation. for (const auto &P : CUMap) { @@ -1121,6 +1099,10 @@ PrevCU = nullptr; CurFn = nullptr; DebugHandlerBase::endFunction(MF); + // Mark functions with no debug info on any instructions, but a + // valid DISubprogram as processed. + if (auto *SP = MF->getFunction()->getSubprogram()) + ProcessedSPNodes.insert(SP); return; } Index: test/DebugInfo/Generic/cross-cu-linkonce-distinct.ll =================================================================== --- test/DebugInfo/Generic/cross-cu-linkonce-distinct.ll +++ test/DebugInfo/Generic/cross-cu-linkonce-distinct.ll @@ -26,24 +26,16 @@ ; } ; int (*y)(int) = &func; +; The DISubprogram should show up in compile unit a. ; CHECK: DW_TAG_compile_unit -; CHECK: DW_TAG_subprogram ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_name {{.*}} "func" -; CHECK: DW_TAG_compile_unit - -; FIXME: Maybe we should drop the subprogram here - since the function was -; emitted in one CU, due to linkonce_odr uniquing. We certainly don't emit the -; subprogram here if the source location for this definition is the same (see -; test/DebugInfo/cross-cu-linkonce.ll), though it's very easy to tickle that -; into failing even without duplicating the source as has been done in this -; case (two cpp files in different directories, including the same header that -; contains an inline function - clang will produce distinct subprogram metadata -; that won't deduplicate owing to the file location information containing the -; directory of the source file even though the file name is absolute, not -; relative) +; CHECK: DW_AT_name {{.*}}"b.cpp" +; CHECK-NOT: DW_TAG_subprogram -; CHECK: DW_TAG_subprogram +; CHECK: DW_TAG_compile_unit +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}}"a.cpp" +; CHECK: DW_AT_name {{.*}} "func" @x = global i32 (i32)* @_Z4funci, align 8 @y = global i32 (i32)* @_Z4funci, align 8 Index: test/DebugInfo/Generic/nodebug.ll =================================================================== --- test/DebugInfo/Generic/nodebug.ll +++ test/DebugInfo/Generic/nodebug.ll @@ -16,10 +16,8 @@ ; f1(); ; } -; Check that there's only one DW_TAG_subprogram, nothing for the 'f2' function. -; CHECK: DW_TAG_subprogram -; CHECK-NOT: DW_TAG -; CHECK: DW_AT_name {{.*}} "f1" +; Check that there's no DW_TAG_subprogram, not even for the 'f2' function. +; CHECK: DW_TAG_compile_unit ; CHECK-NOT: DW_TAG_subprogram @i = external global i32 Index: test/DebugInfo/X86/debug-dead-local-var.ll =================================================================== --- test/DebugInfo/X86/debug-dead-local-var.ll +++ test/DebugInfo/X86/debug-dead-local-var.ll @@ -11,9 +11,12 @@ ; return 1; ; } -; Check that we still have the structure type for X even though we're not -; going to emit a low/high_pc for foo. -; CHECK: DW_TAG_structure_type +; Check that don't have the structure type for X since its scope has +; been optimized away. +; CHECK-NOT: DW_TAG_structure_type +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_name {{.*}}"bar" +; CHECK-NOT: DW_TAG_structure_type ; Function Attrs: nounwind readnone uwtable define i32 @bar() #0 !dbg !4 {