From 2f7b4d91e21863cd7e9ffc24d18299db432639c5 Mon Sep 17 00:00:00 2001 From: Alex Brachet Date: Mon, 10 Oct 2022 20:13:10 +0000 Subject: [PATCH] Don't internalize __llvm_profile_counter_bias Currently, LLVM profiling runtime counter relocation cannot be used by rust during LTO because symbols are being internalized before all symbol information is known. This mode makes LLVM emit a __llvm_profile_counter_bias symbol which is referenced by the profiling initialization, which itself is pulled in by the rust driver here [1]. It is enabled with -Cllvm-args=-runtime-counter-relocation for platforms which are opt-in to this mode like Linux. On these platforms there will be no link error, rather just surprising behavior for a user which request runtime counter relocation. The profiling runtime will not see that symbol go on as if it were never there. On Fuchsia, the profiling runtime must have this symbol which will cause a hard link error. As an aside, I don't have enough context as to why rust's LTO model is how it is. AFAICT, the internalize pass is only safe to run at link time when all symbol information is actually known, this being an example as to why. I think special casing this symbol as a known one that LLVM can emit which should not have it's visbility de-escalated should be fine given how seldom this pattern of defining an undefined symbol to get initilization code pulled in is. From a quick grep, __llvm_profile_runtime is the only symbol that rustc does this for. [1] https://github.com/rust-lang/rust/blob/0265a3e93bf1b89d97cae113ed214954d5c35e22/compiler/rustc_codegen_ssa/src/back/linker.rs#L598 --- .../rustc_codegen_ssa/src/back/symbol_export.rs | 15 +++++++++++---- src/test/codegen/pgo-counter-bias.rs | 9 +++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 src/test/codegen/pgo-counter-bias.rs diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 8d7e2c5cf3939..341b28424e40b 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -212,10 +212,17 @@ fn exported_symbols_provider_local<'tcx>( // These are weak symbols that point to the profile version and the // profile name, which need to be treated as exported so LTO doesn't nix // them. - const PROFILER_WEAK_SYMBOLS: [&str; 2] = - ["__llvm_profile_raw_version", "__llvm_profile_filename"]; - - symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| { + // __llvm_profile_counter_bias is not weak, but is only referenced by the + // profiling initialization runtime, which is itself pulled in by an + // undefined reference to __llvm_profile_runtime. This happens at link time + // and thus this symbol cannot be internalized until then. + const PROFILER_DEFAULT_VIS_SYMBOLS: [&str; 3] = [ + "__llvm_profile_raw_version", + "__llvm_profile_filename", + "__llvm_profile_counter_bias", + ]; + + symbols.extend(PROFILER_DEFAULT_VIS_SYMBOLS.iter().map(|sym| { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym)); ( exported_symbol, diff --git a/src/test/codegen/pgo-counter-bias.rs b/src/test/codegen/pgo-counter-bias.rs new file mode 100644 index 0000000000000..b9019e9de7b22 --- /dev/null +++ b/src/test/codegen/pgo-counter-bias.rs @@ -0,0 +1,9 @@ +// Test that __llvm_profile_counter_bias does not get internalized by lto. + +// compile-flags: -Cprofile-generate -Cllvm-args=-runtime-counter-relocation -Clto=fat +// needs-profiler-support +// no-prefer-dynamic + +// CHECK: @__llvm_profile_counter_bias = {{.*}}global + +pub fn main() {}