Currently for thin-lto, the imported static global values (functions, variables, etc) will be promoted/renamed from e.g., foo() to foo.llvm.(). Such a renaming caused difficulties in live patching since function name is changed ([1]). It is possible that some global value names have to be promoted to avoid name collision and linker failure. But in practice, majority of name promotions can be avoided. In [2], the suggestion is that thin-lto pre-link decides whether a particular global value needs name promotion or not. If yes, later on in thinBackend() the name will be promoted. I compiled a particular linux kernel version (latest bpf-next tree) and found 1216 global values with suffix .llvm.. With this patch, the number of promoted functions is 2, 98% reduction from the original kernel build. If some native objects are not participating with LTO, name promotions have to be done to avoid potential linker issues. So the current implementation cannot be on by default. But in certain cases, e.g., linux kernel build, people can enable lld flag --lto-whole-program-visibility to reduce the number of functions like foo.llvm.(). For ThinLTOCodeGenerator.cpp which is used by llvm-lto tool and a few other rare cases, reducing the number of renaming due to promotion, is not implemented as lld flag '-lto-whole-program-visibility' is not supported in ThinLTOCodeGenerator.cpp for now. In summary, this pull request only supports llvm-lto2 style workflow. The feature is off by default. To enable the future, lld flag '-lto-whole-program-visibility' and llvm flag '-always-rename-promoted-locals=false' are needed. The link [3] has more context for the pull request discussions. [1] https://lpc.events/event/19/contributions/2212 [2] https://discourse.llvm.org/t/rfc-avoid-functions-like-foo-llvm-for-kernel-live-patch/89400 [3] https://github.com/llvm/llvm-project/pull/178587
44 lines
1.7 KiB
LLVM
44 lines
1.7 KiB
LLVM
;; Test to ensure that we can still read old bitcode containing the now
|
|
;; deprected PERMODULE_RELBF record. It should be read and the relbf itself
|
|
;; ignored.
|
|
|
|
; RUN: llvm-bcanalyzer -dump %S/Inputs/thinlto-function-summary-callgraph-relbf.bc | FileCheck %s
|
|
; RUN: llvm-dis -o - %S/Inputs/thinlto-function-summary-callgraph-relbf.bc | FileCheck %s --check-prefix=DIS
|
|
|
|
; CHECK: <SOURCE_FILENAME
|
|
; CHECK-NEXT: <GLOBALVAR
|
|
; CHECK-NEXT: <FUNCTION
|
|
; "func"
|
|
; CHECK-NEXT: <FUNCTION op0=17 op1=4
|
|
; CHECK: <GLOBALVAL_SUMMARY_BLOCK
|
|
; CHECK-NEXT: <VERSION
|
|
; CHECK-NEXT: <FLAGS
|
|
; See if the call to func is registered.
|
|
; CHECK-NEXT: <PERMODULE_RELBF {{.*}} op4=1 {{.*}} op9=256
|
|
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
|
; CHECK: <STRTAB_BLOCK
|
|
; CHECK-NEXT: blob data = 'undefinedglobmainfunc{{.*}}'
|
|
|
|
|
|
; ModuleID = 'thinlto-function-summary-callgraph.ll'
|
|
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 i32 @main() #0 {
|
|
entry:
|
|
call void (...) @func()
|
|
%u = load i32, i32* @undefinedglob
|
|
ret i32 %u
|
|
}
|
|
|
|
declare void @func(...) #1
|
|
@undefinedglob = external global i32
|
|
|
|
; DIS: ^0 = module: (path: "{{.*}}", hash: (0, 0, 0, 0, 0))
|
|
; DIS: ^1 = gv: (name: "func") ; guid = 7289175272376759421
|
|
;; We should have ignored the relbf in the old bitcode, and it no longer shows
|
|
;; up in the summary.
|
|
; DIS: ^2 = gv: (name: "main", summaries: (function: (module: ^0, flags: (linkage: external, visibility: default, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0, importType: definition, noRenameOnPromotion: 0), insts: 3, calls: ((callee: ^1)), refs: (readonly ^3)))) ; guid = 15822663052811949562
|
|
; DIS: ^3 = gv: (name: "undefinedglob") ; guid = 18036901804029949403
|