Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -180,8 +180,6 @@ void finishSubprogramDefinition(const DISubprogram *SP); - void collectDeadVariables(const DISubprogram *SP); - /// Set the skeleton unit associated with this unit. void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; } Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -695,25 +695,6 @@ applySubprogramAttributesToDefinition(SP, *D); } } -void DwarfCompileUnit::collectDeadVariables(const DISubprogram *SP) { - assert(SP && "CU's subprogram list contains a non-subprogram"); - assert(SP->isDefinition() && - "CU's subprogram list contains a subprogram declaration"); - auto Variables = SP->getVariables(); - if (Variables.size() == 0) - return; - - DIE *SPDIE = DU->getAbstractSPDies().lookup(SP); - if (!SPDIE) - SPDIE = getDIE(SP); - assert(SPDIE); - for (const DILocalVariable *DV : Variables) { - DbgVariable NewVar(DV, /* IA */ nullptr, DD); - auto VariableDie = constructVariableDIE(NewVar); - applyVariableAttributes(NewVar, *VariableDie); - SPDIE->addChild(std::move(VariableDie)); - } -} void DwarfCompileUnit::emitHeader(bool UseOffsets) { // Don't bother labeling the .dwo unit, as its offset isn't used. Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -320,9 +320,6 @@ /// Construct a DIE for this abstract scope. void constructAbstractSubprogramScopeDIE(LexicalScope *Scope); - /// Collect info for variables that were optimized out. - void collectDeadVariables(); - void finishVariableDefinitions(); void finishSubprogramDefinitions(); 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 {