From: David Blaikie Date: Thu, 15 Dec 2016 23:17:52 +0000 (+0000) Subject: DebugInfo: Emit ranges for functions with DISubprograms but lacking locations on... X-Git-Tag: llvmorg-4.0.0-rc1~1914 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3e3eb33ed7fbf1140cb05c6d47d5ae60f61a1ec5;p=platform%2Fupstream%2Fllvm.git DebugInfo: Emit ranges for functions with DISubprograms but lacking locations on any instructions This seems more consistent, and helps tidy up/simplify some other code in this change. llvm-svn: 289889 --- diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 024f6d2..e313b8a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -568,25 +568,24 @@ DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope, return ObjectPointer; } -void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) { - assert(Scope && Scope->getScopeNode()); - assert(!Scope->getInlinedAt()); - assert(!Scope->isAbstractScope()); - auto *Sub = cast(Scope->getScopeNode()); - +void DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope) { DD->getProcessedSPNodes().insert(Sub); DIE &ScopeDIE = updateSubprogramScopeDIE(Sub); + if (Scope) { + assert(!Scope->getInlinedAt()); + assert(!Scope->isAbstractScope()); + // Collect lexical scope children first. + // ObjectPointer might be a local (non-argument) local variable if it's a + // block's synthetic this pointer. + if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE)) + addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); + } + // If this is a variadic function, add an unspecified parameter. DITypeRefArray FnArgs = Sub->getType()->getTypeArray(); - // Collect lexical scope children first. - // ObjectPointer might be a local (non-argument) local variable if it's a - // block's synthetic this pointer. - if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE)) - addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); - // If we have a single element of null, it is a function that returns void. // If we have more than one elements and the last one is null, it is a // variadic function. @@ -678,11 +677,7 @@ void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) { // If this subprogram has an abstract definition, reference that addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); } else { - if (!D && !includeMinimalInlineScopes()) - // Lazily construct the subprogram if we didn't see either concrete or - // inlined versions during codegen. (except in -gmlt ^ where we want - // to omit these entirely) - D = getOrCreateSubprogramDIE(SP); + assert(D || includeMinimalInlineScopes()); if (D) // And attach the attributes applySubprogramAttributesToDefinition(SP, *D); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 9412e50..da20bef 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -172,7 +172,7 @@ public: unsigned *ChildScopeCount = nullptr); /// \brief Construct a DIE for this subprogram scope. - void constructSubprogramScopeDIE(LexicalScope *Scope); + void constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope); DIE *createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index b57f804b3..384c0ab 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1155,18 +1155,14 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { "endFunction should be called with the same function as beginFunction"); const DISubprogram *SP = MF->getFunction()->getSubprogram(); - if (!MMI->hasDebugInfo() || LScopes.empty() || !SP || + if (!MMI->hasDebugInfo() || !SP || SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug) { - // 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. + // If we don't have a subprogram 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. PrevCU = nullptr; CurFn = nullptr; DebugHandlerBase::endFunction(MF); - // Mark functions with no debug info on any instructions, but a - // valid DISubprogram as processed. - if (SP) - ProcessedSPNodes.insert(SP); return; } @@ -1174,7 +1170,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { Asm->OutStreamer->getContext().setDwarfCompileUnitID(0); LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); - SP = cast(FnScope->getScopeNode()); + assert(!FnScope || SP == FnScope->getScopeNode()); DwarfCompileUnit &TheCU = *CUMap.lookup(SP->getUnit()); DenseSet ProcessedVars; @@ -1216,11 +1212,11 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { constructAbstractSubprogramScopeDIE(AScope); } - TheCU.constructSubprogramScopeDIE(FnScope); + TheCU.constructSubprogramScopeDIE(SP, FnScope); if (auto *SkelCU = TheCU.getSkeleton()) if (!LScopes.getAbstractScopesList().empty() && TheCU.getCUNode()->getSplitDebugInlining()) - SkelCU->constructSubprogramScopeDIE(FnScope); + SkelCU->constructSubprogramScopeDIE(SP, FnScope); // Clear debug info // Ownership of DbgVariables is a bit subtle - ScopeVariables owns all the diff --git a/llvm/test/DebugInfo/Generic/2010-10-01-crash.ll b/llvm/test/DebugInfo/Generic/2010-10-01-crash.ll index 7cdce97..86c50a9 100644 --- a/llvm/test/DebugInfo/Generic/2010-10-01-crash.ll +++ b/llvm/test/DebugInfo/Generic/2010-10-01-crash.ll @@ -13,7 +13,7 @@ declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, !llvm.dbg.cu = !{!2} !llvm.module.flags = !{!27} -!0 = distinct !DISubprogram(name: "CGRectStandardize", linkageName: "CGRectStandardize", line: 54, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !2, file: !1, scope: null) +!0 = distinct !DISubprogram(name: "CGRectStandardize", linkageName: "CGRectStandardize", line: 54, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !2, file: !1, scope: null, type: !28) !1 = !DIFile(filename: "GSFusedSilica.m", directory: "/Volumes/Data/Users/sabre/Desktop") !2 = distinct !DICompileUnit(language: DW_LANG_ObjC, producer: "clang version 2.9 (trunk 115292)", isOptimized: true, runtimeVersion: 1, emissionKind: FullDebug, file: !25, enums: !26, retainedTypes: !26) !5 = !DIDerivedType(tag: DW_TAG_typedef, name: "CGRect", line: 49, file: !25, baseType: null) @@ -22,3 +22,5 @@ declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, !25 = !DIFile(filename: "GSFusedSilica.m", directory: "/Volumes/Data/Users/sabre/Desktop") !26 = !{} !27 = !{i32 1, !"Debug Info Version", i32 3} +!28 = !DISubroutineType(types: !29) +!29 = !{null} diff --git a/llvm/test/DebugInfo/Generic/noscopes.ll b/llvm/test/DebugInfo/Generic/noscopes.ll new file mode 100644 index 0000000..05d9df2 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/noscopes.ll @@ -0,0 +1,40 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump - | FileCheck %s + +; Just because there are no scopes/locations on any instructions in the +; function doesn't mean we can't describe the address range of the function. +; Check that we do that + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: TAG +; CHECK: DW_AT_low_pc + +; ModuleID = 'noscopes.c' +source_filename = "noscopes.c" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind uwtable +define void @f() #0 !dbg !6 { +entry: + ret void +} + +attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 4.0.0 (trunk 289692) (llvm/trunk 289697)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "noscopes.c", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang version 4.0.0 (trunk 289692) (llvm/trunk 289697)"} +!6 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, variables: !2) +!7 = !DISubroutineType(types: !8) +!8 = !{null} +!9 = !DILocation(line: 2, column: 1, scope: !6) +