Skip to content

Commit

Permalink
Don't internalize __llvm_profile_counter_bias
Browse files Browse the repository at this point in the history
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
  • Loading branch information
abrachet committed Oct 13, 2022
1 parent 0265a3e commit 2f7b4d9
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
15 changes: 11 additions & 4 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 9 additions & 0 deletions src/test/codegen/pgo-counter-bias.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 2f7b4d9

Please sign in to comment.