Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build-std compatible profile(code coverage) support #101392

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -2736,15 +2736,6 @@ dependencies = [
"std",
]

[[package]]
name = "profiler_builtins"
version = "0.0.0"
dependencies = [
"cc",
"compiler_builtins",
"core",
]

[[package]]
name = "psm"
version = "0.1.16"
@@ -4684,7 +4675,6 @@ dependencies = [
"object 0.26.2",
"panic_abort",
"panic_unwind",
"profiler_builtins",
"rand 0.7.3",
"rustc-demangle",
"std_detect",
70 changes: 53 additions & 17 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
@@ -1144,23 +1144,46 @@ fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut d
}
}

fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
fn find_sanitizer_runtime(sess: &Session, filename: &str) -> PathBuf {
let session_tlib =
filesearch::make_target_lib_path(&sess.sysroot, sess.opts.target_triple.triple());
let path = session_tlib.join(filename);
if path.exists() {
return session_tlib;
} else {
let default_sysroot = filesearch::get_or_default_sysroot();
let default_tlib = filesearch::make_target_lib_path(
&default_sysroot,
sess.opts.target_triple.triple(),
);
return default_tlib;
}
fn add_profiler_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) {
let needs_runtime = match crate_type {
CrateType::Executable => true,
CrateType::Dylib
| CrateType::Cdylib
| CrateType::ProcMacro
| CrateType::Rlib
| CrateType::Staticlib => false,
};

if !needs_runtime {
return;
}

if !sess.opts.unstable_opts.no_profiler_runtime
&& (sess.instrument_coverage()
|| sess.opts.unstable_opts.profile
|| sess.opts.cg.profile_generate.enabled())
// If user doesn't provide custom profiler runtime, link default llvm profiler.
&& sess.opts.unstable_opts.profiler_runtime.is_none()
{
link_profiler_runtime(sess, linker);
}
}

fn find_compiler_rt(sess: &Session, filename: &str) -> PathBuf {
let session_tlib =
filesearch::make_target_lib_path(&sess.sysroot, sess.opts.target_triple.triple());
let path = session_tlib.join(filename);
if path.exists() {
return session_tlib;
} else {
let default_sysroot = filesearch::get_or_default_sysroot();
let default_tlib =
filesearch::make_target_lib_path(&default_sysroot, sess.opts.target_triple.triple());
return default_tlib;
}
}

fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
let channel = option_env!("CFG_RELEASE_CHANNEL")
.map(|channel| format!("-{}", channel))
.unwrap_or_default();
@@ -1171,17 +1194,27 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
// rpath to the library as well (the rpath should be absolute, see
// PR #41352 for details).
let filename = format!("rustc{}_rt.{}", channel, name);
let path = find_sanitizer_runtime(&sess, &filename);
let path = find_compiler_rt(&sess, &filename);
let rpath = path.to_str().expect("non-utf8 component in path");
linker.args(&["-Wl,-rpath", "-Xlinker", rpath]);
linker.link_dylib(&filename, false, true);
} else {
let filename = format!("librustc{}_rt.{}.a", channel, name);
let path = find_sanitizer_runtime(&sess, &filename).join(&filename);
let path = find_compiler_rt(&sess, &filename).join(&filename);
linker.link_whole_rlib(&path);
}
}

fn link_profiler_runtime(sess: &Session, linker: &mut dyn Linker) {
let channel = option_env!("CFG_RELEASE_CHANNEL")
.map(|channel| format!("-{}", channel))
.unwrap_or_default();

let filename = format!("librustc{}_rt.profile.a", channel);
let path = find_compiler_rt(&sess, &filename).join(&filename);
linker.link_whole_rlib(&path);
}

/// Returns a boolean indicating whether the specified crate should be ignored
/// during LTO.
///
@@ -1997,6 +2030,9 @@ fn linker_with_args<'a>(
// Sanitizer libraries.
add_sanitizer_libraries(sess, crate_type, cmd);

// Profiler libraries.
add_profiler_libraries(sess, crate_type, cmd);

// Object code from the current crate.
// Take careful note of the ordering of the arguments we pass to the linker
// here. Linkers will assume that things on the left depend on things to the
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
@@ -578,7 +578,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),
gated!(
profiler_runtime, Normal, template!(Word), WarnFollowing,
"the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
"the `#[profiler_runtime]` attribute is used to identify the crate \
which contains the profiler runtime and will never be stable",
),

2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
@@ -770,7 +770,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(profile, true);
tracked!(profile_emit, Some(PathBuf::from("abc")));
tracked!(profile_sample_use, Some(PathBuf::from("abc")));
tracked!(profiler_runtime, "abc".to_string());
tracked!(profiler_runtime, Some("abc".to_string()));
tracked!(relax_elf_relocations, Some(true));
tracked!(relro_level, Some(RelroLevel::Full));
tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));
26 changes: 13 additions & 13 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

use crate::errors::{
ConflictingGlobalAlloc, CrateNotPanicRuntime, GlobalAllocRequired, NoMultipleGlobalAlloc,
NoPanicStrategy, NoTransitiveNeedsDep, NotProfilerRuntime, ProfilerBuiltinsNeedsCore,
NoPanicStrategy, NoTransitiveNeedsDep, NotProfilerRuntime,
};
use crate::locator::{CrateError, CrateLocator, CratePaths};
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
@@ -759,7 +759,7 @@ impl<'a> CrateLoader<'a> {
self.inject_dependency_if(cnum, "a panic runtime", &|data| data.needs_panic_runtime());
}

fn inject_profiler_runtime(&mut self, krate: &ast::Crate) {
fn inject_profiler_runtime(&mut self) {
if self.sess.opts.unstable_opts.no_profiler_runtime
|| !(self.sess.instrument_coverage()
|| self.sess.opts.unstable_opts.profile
@@ -768,19 +768,19 @@ impl<'a> CrateLoader<'a> {
return;
}

info!("loading profiler");
// If user doesn't provide custom profiler runtime, skip injection.
if let Some(profiler_runtime) = &self.sess.opts.unstable_opts.profiler_runtime {
info!("loading profiler: {}", profiler_runtime);

let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime);
if name == sym::profiler_builtins && self.sess.contains_name(&krate.attrs, sym::no_core) {
self.sess.emit_err(ProfilerBuiltinsNeedsCore);
}
let name = Symbol::intern(profiler_runtime);

let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; };
let data = self.cstore.get_crate_data(cnum);
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; };
let data = self.cstore.get_crate_data(cnum);

// Sanity check the loaded crate to ensure it is indeed a profiler runtime
if !data.is_profiler_runtime() {
self.sess.emit_err(NotProfilerRuntime { crate_name: name });
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
if !data.is_profiler_runtime() {
self.sess.emit_err(NotProfilerRuntime { crate_name: name });
}
}
}

@@ -927,7 +927,7 @@ impl<'a> CrateLoader<'a> {
}

pub fn postprocess(&mut self, krate: &ast::Crate) {
self.inject_profiler_runtime(krate);
self.inject_profiler_runtime();
self.inject_allocator_crate(krate);
self.inject_panic_runtime(krate);

4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/errors.rs
Original file line number Diff line number Diff line change
@@ -601,7 +601,7 @@ pub struct CannotFindCrate {
pub missing_core: bool,
pub current_crate: String,
pub is_nightly_build: bool,
pub profiler_runtime: Symbol,
pub profiler_runtime: Option<Symbol>,
pub locator_triple: TargetTriple,
}

@@ -641,7 +641,7 @@ impl IntoDiagnostic<'_> for CannotFindCrate {
if self.is_nightly_build {
diag.help(rustc_errors::fluent::metadata_consider_building_std);
}
} else if self.crate_name == self.profiler_runtime {
} else if Some(self.crate_name) == self.profiler_runtime {
diag.note(rustc_errors::fluent::metadata_compiler_missing_profiler);
} else if self.crate_name.as_str().starts_with("rustc_") {
diag.help(rustc_errors::fluent::metadata_install_missing_components);
7 changes: 6 additions & 1 deletion compiler/rustc_metadata/src/locator.rs
Original file line number Diff line number Diff line change
@@ -1124,7 +1124,12 @@ impl CrateError {
.clone()
.unwrap_or("<unknown>".to_string()),
is_nightly_build: sess.is_nightly_build(),
profiler_runtime: Symbol::intern(&sess.opts.unstable_opts.profiler_runtime),
profiler_runtime: sess
.opts
.unstable_opts
.profiler_runtime
.as_ref()
.map(|x| Symbol::intern(x)),
locator_triple: locator.triple,
});
}
1 change: 0 additions & 1 deletion compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
@@ -1509,7 +1509,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
"proc_macro",
"panic_abort",
"panic_unwind",
"profiler_builtins",
"rtstartup",
"rustc-std-workspace-core",
"rustc-std-workspace-alloc",
6 changes: 3 additions & 3 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
@@ -1423,7 +1423,7 @@ options! {
no_parallel_llvm: bool = (false, parse_no_flag, [UNTRACKED],
"run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"),
no_profiler_runtime: bool = (false, parse_no_flag, [TRACKED],
"prevent automatic injection of the profiler_builtins crate"),
"prevent automatic injection of the profiler runtime"),
no_unique_section_names: bool = (false, parse_bool, [TRACKED],
"do not use unique names for text and data sections when -Z function-sections is used"),
normalize_docs: bool = (false, parse_bool, [TRACKED],
@@ -1483,8 +1483,8 @@ options! {
(default based on relative source path)"),
profile_sample_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
"use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"),
profiler_runtime: String = (String::from("profiler_builtins"), parse_string, [TRACKED],
"name of the profiler runtime crate to automatically inject (default: `profiler_builtins`)"),
profiler_runtime: Option<String> = (None, parse_opt_string, [TRACKED],
"name of the profiler runtime crate to automatically inject"),
query_dep_graph: bool = (false, parse_bool, [UNTRACKED],
"enable queries of the dependency graph for regression testing (default: no)"),
randomize_layout: bool = (false, parse_bool, [TRACKED],
16 changes: 0 additions & 16 deletions library/profiler_builtins/Cargo.toml

This file was deleted.

89 changes: 0 additions & 89 deletions library/profiler_builtins/build.rs

This file was deleted.

10 changes: 0 additions & 10 deletions library/profiler_builtins/src/lib.rs

This file was deleted.

3 changes: 1 addition & 2 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@ panic_abort = { path = "../panic_abort" }
core = { path = "../core" }
libc = { version = "0.2.126", default-features = false, features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "0.1.73" }
profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" }
hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep-of-std'] }
std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = ['rustc-dep-of-std'] }
@@ -57,7 +56,7 @@ backtrace = [
gimli-symbolize = []

panic-unwind = ["panic_unwind"]
profiler = ["profiler_builtins"]
profiler = []
compiler-builtins-c = ["alloc/compiler-builtins-c"]
compiler-builtins-mem = ["alloc/compiler-builtins-mem"]
compiler-builtins-no-asm = ["alloc/compiler-builtins-no-asm"]
Loading