Skip to content

Commit

Permalink
Unrolled build for rust-lang#125816
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#125816 - Zalathar:demangler, r=oli-obk

Don't build the `rust-demangler` binary for coverage tests

The coverage-run tests invoke `llvm-cov`, which requires us to specify a command-line demangler that it can use to demangle Rust symbol names.

Historically this used `src/tools/rust-demangler`, which means that we currently build two different command-line tools to help with the coverage tests (`rust-demangler` and `coverage-dump`).

However, it occurred to me that if we add a demangler mode to `coverage-dump` (which is only a handful of lines and no extra dependencies), then we only need to build one helper binary for the coverage tests, and there is no need for tests to build `rust-demangler` at all.

---

Note that the `rust-demangler` binary is separate from the `rustc-demangle` crate (which both `rust-demangler` and `coverage-dump` use as a dependency to do the actual demangling).

---

So the main benefits/motivations here are:
- Slightly faster builds after a fresh checkout or bootstrap bump.
- Making it clear that currently no tests actually need the `rust-demangler` binary, since the coverage tests can use their own tool instead.
  • Loading branch information
rust-timer authored May 31, 2024
2 parents 2a2c29a + 54b6849 commit 9dedc63
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 31 deletions.
18 changes: 2 additions & 16 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1781,25 +1781,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
.arg(builder.ensure(tool::JsonDocLint { compiler: json_compiler, target }));
}

if mode == "coverage-map" {
let coverage_dump = builder.ensure(tool::CoverageDump {
compiler: compiler.with_stage(0),
target: compiler.host,
});
if matches!(mode, "coverage-map" | "coverage-run") {
let coverage_dump = builder.tool_exe(Tool::CoverageDump);
cmd.arg("--coverage-dump-path").arg(coverage_dump);
}

if mode == "coverage-run" {
// The demangler doesn't need the current compiler, so we can avoid
// unnecessary rebuilds by using the bootstrap compiler instead.
let rust_demangler = builder.ensure(tool::RustDemangler {
compiler: compiler.with_stage(0),
target: compiler.host,
extra_features: Vec::new(),
});
cmd.arg("--rust-demangler-path").arg(rust_demangler);
}

cmd.arg("--src-base").arg(builder.src.join("tests").join(suite));
cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite));

Expand Down
3 changes: 0 additions & 3 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,6 @@ pub struct Config {
/// The rustdoc executable.
pub rustdoc_path: Option<PathBuf>,

/// The rust-demangler executable.
pub rust_demangler_path: Option<PathBuf>,

/// The coverage-dump executable.
pub coverage_dump_path: Option<PathBuf>,

Expand Down
3 changes: 0 additions & 3 deletions src/tools/compiletest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
.reqopt("", "run-lib-path", "path to target shared libraries", "PATH")
.reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH")
.optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH")
.optopt("", "rust-demangler-path", "path to rust-demangler to use in tests", "PATH")
.optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH")
.reqopt("", "python", "path to python to use for doc tests", "PATH")
.optopt("", "jsondocck-path", "path to jsondocck to use for doc tests", "PATH")
Expand Down Expand Up @@ -232,7 +231,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
run_lib_path: make_absolute(opt_path(matches, "run-lib-path")),
rustc_path: opt_path(matches, "rustc-path"),
rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from),
rust_demangler_path: matches.opt_str("rust-demangler-path").map(PathBuf::from),
coverage_dump_path: matches.opt_str("coverage-dump-path").map(PathBuf::from),
python: matches.opt_str("python").unwrap(),
jsondocck_path: matches.opt_str("jsondocck-path"),
Expand Down Expand Up @@ -337,7 +335,6 @@ pub fn log_config(config: &Config) {
logv(c, format!("run_lib_path: {:?}", config.run_lib_path));
logv(c, format!("rustc_path: {:?}", config.rustc_path.display()));
logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path));
logv(c, format!("rust_demangler_path: {:?}", config.rust_demangler_path));
logv(c, format!("src_base: {:?}", config.src_base.display()));
logv(c, format!("build_base: {:?}", config.build_base.display()));
logv(c, format!("stage_id: {}", config.stage_id));
Expand Down
4 changes: 0 additions & 4 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3561,10 +3561,6 @@ impl<'test> TestCx<'test> {
cmd.env("RUSTDOC", cwd.join(rustdoc));
}

if let Some(ref rust_demangler) = self.config.rust_demangler_path {
cmd.env("RUST_DEMANGLER", cwd.join(rust_demangler));
}

if let Some(ref node) = self.config.nodejs {
cmd.env("NODE", node);
}
Expand Down
17 changes: 12 additions & 5 deletions src/tools/compiletest/src/runtest/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ use crate::common::{UI_COVERAGE, UI_COVERAGE_MAP};
use crate::runtest::{static_regex, Emit, ProcRes, TestCx, WillExecute};

impl<'test> TestCx<'test> {
fn coverage_dump_path(&self) -> &Path {
self.config
.coverage_dump_path
.as_deref()
.unwrap_or_else(|| self.fatal("missing --coverage-dump"))
}

pub(crate) fn run_coverage_map_test(&self) {
let Some(coverage_dump_path) = &self.config.coverage_dump_path else {
self.fatal("missing --coverage-dump");
};
let coverage_dump_path = self.coverage_dump_path();

let (proc_res, llvm_ir_path) = self.compile_test_and_save_ir();
if !proc_res.status.success() {
Expand Down Expand Up @@ -102,8 +107,10 @@ impl<'test> TestCx<'test> {
let proc_res = self.run_llvm_tool("llvm-cov", |cmd| {
cmd.args(["show", "--format=text", "--show-line-counts-or-regions"]);

cmd.arg("--Xdemangler");
cmd.arg(self.config.rust_demangler_path.as_ref().unwrap());
// Specify the demangler binary and its arguments.
let coverage_dump_path = self.coverage_dump_path();
cmd.arg("--Xdemangler").arg(coverage_dump_path);
cmd.arg("--Xdemangler").arg("--demangle");

cmd.arg("--instr-profile");
cmd.arg(&profdata_path);
Expand Down
5 changes: 5 additions & 0 deletions src/tools/coverage-dump/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ The output format is mostly arbitrary, so it's OK to change the output as long
as any affected tests are also re-blessed. However, the output should be
consistent across different executions on different platforms, so avoid
printing any information that is platform-specific or non-deterministic.

## Demangle mode

When run as `coverage-dump --demangle`, this tool instead functions as a
command-line demangler that can be invoked by `llvm-cov`.
19 changes: 19 additions & 0 deletions src/tools/coverage-dump/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ fn main() -> anyhow::Result<()> {

let args = std::env::args().collect::<Vec<_>>();

// The coverage-dump tool already needs `rustc_demangle` in order to read
// coverage metadata, so it's very easy to also have a separate mode that
// turns it into a command-line demangler for use by coverage-run tests.
if &args[1..] == &["--demangle"] {
return demangle();
}

let llvm_ir_path = args.get(1).context("LLVM IR file not specified")?;
let llvm_ir = std::fs::read_to_string(llvm_ir_path).context("couldn't read LLVM IR file")?;

Expand All @@ -15,3 +22,15 @@ fn main() -> anyhow::Result<()> {

Ok(())
}

fn demangle() -> anyhow::Result<()> {
use std::fmt::Write as _;

let stdin = std::io::read_to_string(std::io::stdin())?;
let mut output = String::with_capacity(stdin.len());
for line in stdin.lines() {
writeln!(output, "{:#}", rustc_demangle::demangle(line))?;
}
print!("{output}");
Ok(())
}

0 comments on commit 9dedc63

Please sign in to comment.