llvm.org GIT mirror llvm / dfa5766
[ThinLTO] Remove dead and dropped symbol declarations when possible Summary: Removing the dropped symbols will prevent indirect call promotion in the ThinLTO Backend from adding a new reference to a symbol, which can result in linker unsats. This can happen when we compile with a sample profile collected from one binary by used for another, which may have profiled targets that aren't used in the new binary. Note that until dropDeadSymbols handles variables and aliases (in progress), we may not be able to remove the declaration and can still have an issue. Reviewers: grimar, davidxl Subscribers: mehdi_amini, inglorion, llvm-commits, eraman Differential Revision: https://reviews.llvm.org/D42816 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@324299 91177308-0d34-0410-b5e6-96231b3b80d8 Teresa Johnson 1 year, 7 months ago
4 changed file(s) with 90 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
400400
401401 static void dropDeadSymbols(Module &Mod, const GVSummaryMapTy &DefinedGlobals,
402402 const ModuleSummaryIndex &Index) {
403 std::vector *> ReplacedGlobals;
403 std::vector*> DeadGVs;
404404 for (auto &GV : Mod.global_values())
405405 if (GlobalValueSummary *GVS = DefinedGlobals.lookup(GV.getGUID()))
406 if (!Index.isGlobalValueLive(GVS) && !convertToDeclaration(GV))
407 ReplacedGlobals.push_back(&GV);
408
409 for (GlobalValue *GV : ReplacedGlobals)
410 GV->eraseFromParent();
406 if (!Index.isGlobalValueLive(GVS)) {
407 DeadGVs.push_back(&GV);
408 convertToDeclaration(GV);
409 }
410
411 // Now that all dead bodies have been dropped, delete the actual objects
412 // themselves when possible.
413 for (GlobalValue *GV : DeadGVs) {
414 GV->removeDeadConstantUsers();
415 // Might reference something defined in native object (i.e. dropped a
416 // non-prevailing IR def, but we need to keep the declaration).
417 if (GV->use_empty())
418 GV->eraseFromParent();
419 }
411420 }
412421
413422 Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream,
4949 ; LTO2: define internal void @_GLOBAL__I_a()
5050 ; LTO2: define internal void @bar() {
5151 ; LTO2: define internal void @bar_internal()
52 ; LTO2: declare dso_local void @dead_func()
52 ; LTO2-NOT: @dead_func()
5353 ; LTO2-NOT: available_externally {{.*}} @baz()
5454
5555 ; Make sure we didn't internalize @boo, which is reachable via
0 ; REQUIRES: x86-registered-target
1
2 ; RUN: opt -module-summary %s -o %t.bc
3
4 ; Tests that with dead stripping in the thin link enabled (default), we do not
5 ; promote to target of the dropped dead symbol _ZL3foov. This can happen with a
6 ; sample profile collected for one binary used to optimize for another binary.
7 ; RUN: llvm-lto2 run -save-temps -o %t2 %t.bc -r %t.bc,fptr,plx \
8 ; RUN: -r %t.bc,main,plx -r %t.bc,_ZL3foov,l
9 ; RUN: llvm-dis < %t2.1.4.opt.bc | FileCheck %s --check-prefix=OPT
10 ; RUN: llvm-lto2 run -save-temps -o %t2 %t.bc -r %t.bc,fptr,plx \
11 ; RUN: -r %t.bc,main,plx -r %t.bc,_ZL3foov,l -compute-dead=false
12 ; RUN: llvm-dis < %t2.1.4.opt.bc | FileCheck %s --check-prefix=OPT-NODEAD
13
14 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
15 target triple = "x86_64-unknown-linux-gnu"
16
17 @fptr = local_unnamed_addr global void ()* null, align 8
18
19 define void @_ZL3foov() #1 {
20 entry:
21 ret void
22 }
23
24 define i32 @main() local_unnamed_addr #0 !prof !34 {
25 entry:
26 %0 = load void ()*, void ()** @fptr, align 8
27 ; OPT-NOT: label %if.false.orig_indirect
28 ; OPT-NODEAD: br i1 %{{[0-9]+}}, label %if.end.icp, label %if.false.orig_indirect
29 tail call void %0(), !prof !40
30 ret i32 0
31 }
32
33 !llvm.dbg.cu = !{!0}
34 !llvm.module.flags = !{!3,!4}
35 !llvm.ident = !{!31}
36
37 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 5.0.0 (trunk 297016)", isOptimized: true, runtimeVersion: 0, emissionKind: NoDebug, enums: !2)
38 !1 = !DIFile(filename: "main.cc", directory: ".")
39 !2 = !{}
40 !3 = !{i32 2, !"Debug Info Version", i32 3}
41 !4 = !{i32 1, !"ProfileSummary", !5}
42 !5 = !{!6, !7, !8, !9, !10, !11, !12, !13}
43 !6 = !{!"ProfileFormat", !"SampleProfile"}
44 !7 = !{!"TotalCount", i64 3003}
45 !8 = !{!"MaxCount", i64 3000}
46 !9 = !{!"MaxInternalCount", i64 0}
47 !10 = !{!"MaxFunctionCount", i64 0}
48 !11 = !{!"NumCounts", i64 3}
49 !12 = !{!"NumFunctions", i64 1}
50 !13 = !{!"DetailedSummary", !14}
51 !14 = !{!15, !16, !17, !18, !19, !20, !20, !21, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30}
52 !15 = !{i32 10000, i64 3000, i32 1}
53 !16 = !{i32 100000, i64 3000, i32 1}
54 !17 = !{i32 200000, i64 3000, i32 1}
55 !18 = !{i32 300000, i64 3000, i32 1}
56 !19 = !{i32 400000, i64 3000, i32 1}
57 !20 = !{i32 500000, i64 3000, i32 1}
58 !21 = !{i32 600000, i64 3000, i32 1}
59 !22 = !{i32 700000, i64 3000, i32 1}
60 !23 = !{i32 800000, i64 3000, i32 1}
61 !24 = !{i32 900000, i64 3000, i32 1}
62 !25 = !{i32 950000, i64 3000, i32 1}
63 !26 = !{i32 990000, i64 3000, i32 1}
64 !27 = !{i32 999000, i64 3000, i32 1}
65 !28 = !{i32 999900, i64 2, i32 2}
66 !29 = !{i32 999990, i64 2, i32 2}
67 !30 = !{i32 999999, i64 2, i32 2}
68 !31 = !{!"clang version 5.0.0 (trunk 297016)"}
69 !34 = !{!"function_entry_count", i64 1}
70 !40 = !{!"VP", i32 0, i64 3000, i64 -8789629626369651636, i64 3000}
4646 ; the expected internalization.
4747 ; CHECK-REGULARLTO-DAG: @var_with_nonC_section = internal global i32 0, section ".nonCsection"
4848 ; Check we dropped definition of dead variable.
49 ; CHECK-THINLTO-DAG: @var_with_nonC_section = external dso_local global i32, section ".nonCsection"
49 ; CHECK-THINLTO-NOT: @var_with_nonC_section
5050 @var_with_nonC_section = global i32 0, section ".nonCsection"
5151
5252 ; We should not internalize @deadfunc_with_section due to section
6060 ; the expected internalization.
6161 ; CHECK2-REGULARLTO-DAG: define internal void @deadfunc_with_nonC_section() section ".nonCsection"
6262 ; Check dead function converted to declaration.
63 ; CHECK-THINLTO-DAG: declare dso_local void @deadfunc_with_nonC_section() section ".nonCsection"
63 ; CHECK-THINLTO-NOT: @deadfunc_with_nonC_section()
6464 define void @deadfunc_with_nonC_section() section ".nonCsection" {
6565 call void @deadfunc2_called_from_nonC_section()
6666 ret void
7979 ; are getting the expected internalization.
8080 ; CHECK2-REGULARLTO: define internal void @deadfunc2_called_from_nonC_section
8181 ; Check dead function converted to declaration.
82 ; CHECK2-THINLTO: declare dso_local void @deadfunc2_called_from_nonC_section
82 ; CHECK2-THINLTO-NOT: @deadfunc2_called_from_nonC_section
8383 declare void @deadfunc2_called_from_nonC_section()