diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -124,8 +124,15 @@ DenseSet DummyGroups; auto *Obj = cast>(File); Obj->parse(DummyGroups); - for (Symbol *Sym : Obj->getGlobalSymbols()) - Sym->parseSymbolVersion(); + ArrayRef Syms = Obj->getGlobalSymbols(); + if (Syms.size() > 0) { + // Global symbols mean the object is live, but MarkLive may not + // see that because all uses may be inlined. Therefore, mark the + // object live here. + Obj->HasLiveCodeOrData = true; + for (Symbol *Sym : Syms) + Sym->parseSymbolVersion(); + } ObjectFiles.push_back(File); } } diff --git a/lld/test/ELF/lto/Inputs/structfoo.ll b/lld/test/ELF/lto/Inputs/structfoo.ll new file mode 100644 --- /dev/null +++ b/lld/test/ELF/lto/Inputs/structfoo.ll @@ -0,0 +1,62 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define dso_local i32 @_Z1fv() local_unnamed_addr #0 !dbg !8 { + %var.sroa.0 = alloca i32, align 4 + %var.sroa.4 = alloca i32, align 4 + call void @llvm.dbg.declare(metadata i32* %var.sroa.0, metadata !13, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !19 + call void @llvm.dbg.declare(metadata i32* %var.sroa.4, metadata !13, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32)), !dbg !19 + store volatile i32 13, i32* %var.sroa.0, align 4, !dbg !21, !tbaa !22 + store volatile i32 14, i32* %var.sroa.4, align 4, !dbg !27, !tbaa !28 + %var.sroa.0.0.var.sroa.0.0.var.sroa.0.0. = load volatile i32, i32* %var.sroa.0, align 4, !dbg !29, !tbaa !22 + %var.sroa.4.0.var.sroa.4.0.var.sroa.4.4. = load volatile i32, i32* %var.sroa.4, align 4, !dbg !30, !tbaa !28 + %add = add nsw i32 %var.sroa.4.0.var.sroa.4.0.var.sroa.4.4., %var.sroa.0.0.var.sroa.0.0.var.sroa.0.0., !dbg !31 + ret i32 %add, !dbg !33 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) #0 + +attributes #0 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "structfoo.cpp", directory: "/home/tests") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{i32 1, !"EnableSplitLTOUnit", i32 0} +!7 = !{!"clang"} +!8 = distinct !DISubprogram(name: "f", linkageName: "_Z1fv", scope: !1, file: !1, line: 5, type: !9, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12) +!9 = !DISubroutineType(types: !10) +!10 = !{!11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !{!13} +!13 = !DILocalVariable(name: "var", scope: !8, file: !1, line: 6, type: !14) +!14 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !15) +!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !1, line: 1, size: 64, flags: DIFlagTypePassByValue, elements: !16, identifier: "_ZTS3Foo") +!16 = !{!17, !18} +!17 = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !15, file: !1, line: 2, baseType: !11, size: 32) +!18 = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: !15, file: !1, line: 2, baseType: !11, size: 32, offset: 32) +!19 = !DILocation(line: 6, column: 16, scope: !8) +!20 = !DILocation(line: 6, column: 3, scope: !8) +!21 = !DILocation(line: 7, column: 9, scope: !8) +!22 = !{!23, !24, i64 0} +!23 = !{!"_ZTS3Foo", !24, i64 0, !24, i64 4} +!24 = !{!"int", !25, i64 0} +!25 = !{!"omnipotent char", !26, i64 0} +!26 = !{!"Simple C++ TBAA"} +!27 = !DILocation(line: 8, column: 9, scope: !8) +!28 = !{!23, !24, i64 4} +!29 = !DILocation(line: 9, column: 14, scope: !8) +!30 = !DILocation(line: 9, column: 22, scope: !8) +!31 = !DILocation(line: 9, column: 16, scope: !8) +!32 = !DILocation(line: 10, column: 1, scope: !8) +!33 = !DILocation(line: 9, column: 3, scope: !8) + +^0 = module: (path: "structfoo.bc", hash: (1764250837, 803149122, 2095734431, 310569936, 1025282646)) +^1 = gv: (name: "_Z1fv", summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 1), insts: 14))) ; guid = 2964830440387334114 +^2 = gv: (name: "llvm.dbg.declare") ; guid = 13513223491971101989 diff --git a/lld/test/ELF/lto/keepdbg.ll b/lld/test/ELF/lto/keepdbg.ll new file mode 100644 --- /dev/null +++ b/lld/test/ELF/lto/keepdbg.ll @@ -0,0 +1,49 @@ +; RUN: llvm-as -o %t.o %s +; RUN: llvm-as -o %t.structfoo.o %S/Inputs/structfoo.ll +; RUN: ld.lld -plugin-opt=thinlto -save-temps -gc-sections -print-gc-sections %t.o %t.structfoo.o -o %t +; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s + +; CHECK: DW_TAG_structure_type +; CHECK-NOT: DW_TAG_ +; CHECK: DW_AT_name ("Foo") +; CHECK: DW_TAG_member +; CHECK: DW_AT_name ("x") +; CHECK: DW_AT_type ({{[^ ]+}} "int") +; CHECK: DW_TAG_member +; CHECK: DW_AT_name ("y") +; CHECK: DW_AT_type ({{[^ ]+}} "int") + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define dso_local i32 @main() local_unnamed_addr #0 !dbg !8 { + %call = tail call i32 @_Z1fv(), !dbg !12 + ret i32 %call, !dbg !13 +} + +declare dso_local i32 @_Z1fv() local_unnamed_addr #0 + +attributes #0 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "keepdbg.cpp", directory: "/home/tests") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{i32 1, !"EnableSplitLTOUnit", i32 0} +!7 = !{!"clang"} +!8 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 3, type: !9, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!9 = !DISubroutineType(types: !10) +!10 = !{!11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DILocation(line: 4, column: 10, scope: !8) +!13 = !DILocation(line: 4, column: 3, scope: !8) + +^0 = module: (path: "keepdbg.bc", hash: (1783178388, 1195490640, 2048955326, 1635682736, 2020218366)) +^1 = gv: (name: "_Z1fv") ; guid = 2964830440387334114 +^2 = gv: (name: "main", summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 1), insts: 2, funcFlags: (readNone: 0, readOnly: 0, noRecurse: 1, returnDoesNotAlias: 0, noInline: 0), calls: ((callee: ^1))))) ; guid = 15822663052811949562