From 9ec178df0b7f0aa7f1f6e9ca80237933f1230dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 12 Jun 2024 09:53:42 +0200 Subject: [PATCH 1/5] Add `cargo_args` to `ToolBuild` --- src/bootstrap/src/core/build_steps/tool.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 9df4698f21f3a..20b17863bef86 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -32,6 +32,8 @@ struct ToolBuild { extra_features: Vec, /// Nightly-only features that are allowed (comma-separated list). allow_features: &'static str, + /// Additional arguments to pass to the `cargo` invocation. + cargo_args: Vec, } impl Builder<'_> { @@ -100,6 +102,7 @@ impl Step for ToolBuild { if !self.allow_features.is_empty() { cargo.allow_features(self.allow_features); } + cargo.args(self.cargo_args); let _guard = builder.msg_tool( Kind::Build, self.mode, @@ -283,6 +286,7 @@ macro_rules! bootstrap_tool { }, extra_features: vec![], allow_features: concat!($($allow_features)*), + cargo_args: vec![] }) } } @@ -349,6 +353,7 @@ impl Step for OptimizedDist { source_type: SourceType::InTree, extra_features: Vec::new(), allow_features: "", + cargo_args: Vec::new(), }) } } @@ -403,6 +408,7 @@ impl Step for ErrorIndex { source_type: SourceType::InTree, extra_features: Vec::new(), allow_features: "", + cargo_args: Vec::new(), }) } } @@ -437,6 +443,7 @@ impl Step for RemoteTestServer { source_type: SourceType::InTree, extra_features: Vec::new(), allow_features: "", + cargo_args: Vec::new(), }) } } @@ -598,6 +605,7 @@ impl Step for Cargo { source_type: SourceType::Submodule, extra_features: Vec::new(), allow_features: "", + cargo_args: Vec::new(), }) } } @@ -625,6 +633,7 @@ impl Step for LldWrapper { source_type: SourceType::InTree, extra_features: Vec::new(), allow_features: "", + cargo_args: Vec::new(), }) } } @@ -673,6 +682,7 @@ impl Step for RustAnalyzer { extra_features: vec!["in-rust-tree".to_owned()], source_type: SourceType::InTree, allow_features: RustAnalyzer::ALLOW_FEATURES, + cargo_args: Vec::new(), }) } } @@ -720,6 +730,7 @@ impl Step for RustAnalyzerProcMacroSrv { extra_features: vec!["in-rust-tree".to_owned()], source_type: SourceType::InTree, allow_features: RustAnalyzer::ALLOW_FEATURES, + cargo_args: Vec::new(), }); // Copy `rust-analyzer-proc-macro-srv` to `/libexec/` @@ -916,6 +927,7 @@ macro_rules! tool_extended { extra_features: $sel.extra_features, source_type: SourceType::InTree, allow_features: concat!($($allow_features)*), + cargo_args: vec![] }); if (false $(|| !$add_bins_to_sysroot.is_empty())?) && $sel.compiler.stage > 0 { From 9e0b76201bce536d19cf4e5190b3ac0341838b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 12 Jun 2024 09:54:08 +0200 Subject: [PATCH 2/5] Add `RustcPerf` bootstrap tool So that it is easier to use `rustc-perf` with `rustc` directly. --- src/bootstrap/src/core/build_steps/tool.rs | 44 ++++++++++++++++++++++ src/bootstrap/src/core/builder.rs | 3 +- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 20b17863bef86..ab79166367e0a 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -358,6 +358,50 @@ impl Step for OptimizedDist { } } +/// The [rustc-perf](https://github.com/rust-lang/rustc-perf) benchmark suite, which is added +/// as a submodule at `src/tools/rustc-perf`. +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub struct RustcPerf { + pub compiler: Compiler, + pub target: TargetSelection, +} + +impl Step for RustcPerf { + /// Path to the built `collector` binary. + type Output = PathBuf; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/rustc-perf") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(RustcPerf { + compiler: run.builder.compiler(0, run.builder.config.build), + target: run.target, + }); + } + + fn run(self, builder: &Builder<'_>) -> PathBuf { + // We need to ensure the rustc-perf submodule is initialized. + builder.update_submodule(Path::new("src/tools/rustc-perf")); + + let target = builder.ensure(ToolBuild { + compiler: self.compiler, + target: self.target, + tool: "collector", + mode: Mode::ToolBootstrap, + path: "src/tools/rustc-perf", + source_type: SourceType::Submodule, + extra_features: Vec::new(), + allow_features: "", + // Only build the collector package, which is used for benchmarking through + // a CLI. + cargo_args: vec!["-p".to_string(), "collector".to_string()], + }); + target + } +} + #[derive(Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] pub struct ErrorIndex { pub compiler: Compiler, diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 12d2bb18ab7ca..55d998dc83c18 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -750,7 +750,8 @@ impl<'a> Builder<'a> { tool::RustdocGUITest, tool::OptimizedDist, tool::CoverageDump, - tool::LlvmBitcodeLinker + tool::LlvmBitcodeLinker, + tool::RustcPerf, ), Kind::Clippy => describe!( clippy::Std, From fd44aca2aa37fb95d337a61cf733996cb05e9bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 12 Jun 2024 11:10:50 +0200 Subject: [PATCH 3/5] Copy `rustc-fake` binary when building the `rustc-perf` tool --- src/bootstrap/src/core/build_steps/tool.rs | 31 +++++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index ab79166367e0a..03e77c46b6047 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -129,10 +129,7 @@ impl Step for ToolBuild { if tool == "tidy" { tool = "rust-tidy"; } - let cargo_out = builder.cargo_out(compiler, self.mode, target).join(exe(tool, target)); - let bin = builder.tools_dir(compiler).join(exe(tool, target)); - builder.copy_link(&cargo_out, &bin); - bin + copy_tool_bin(builder, self.compiler, self.target, self.mode, tool) } } } @@ -217,6 +214,21 @@ pub fn prepare_tool_cargo( cargo } +/// Copies a built tool binary with the given `name` from the build directory to the +/// tools directory. +fn copy_tool_bin( + builder: &Builder<'_>, + compiler: Compiler, + target: TargetSelection, + mode: Mode, + name: &str, +) -> PathBuf { + let cargo_out = builder.cargo_out(compiler, mode, target).join(exe(name, target)); + let bin = builder.tools_dir(compiler).join(exe(name, target)); + builder.copy_link(&cargo_out, &bin); + bin +} + macro_rules! bootstrap_tool { ($( $name:ident, $path:expr, $tool_name:expr @@ -385,7 +397,7 @@ impl Step for RustcPerf { // We need to ensure the rustc-perf submodule is initialized. builder.update_submodule(Path::new("src/tools/rustc-perf")); - let target = builder.ensure(ToolBuild { + let tool = ToolBuild { compiler: self.compiler, target: self.target, tool: "collector", @@ -397,8 +409,13 @@ impl Step for RustcPerf { // Only build the collector package, which is used for benchmarking through // a CLI. cargo_args: vec!["-p".to_string(), "collector".to_string()], - }); - target + }; + let collector_bin = builder.ensure(tool.clone()); + // We also need to symlink the `rustc-fake` binary to the corresponding directory, + // because `collector` expects it in the same directory. + copy_tool_bin(builder, tool.compiler, tool.target, tool.mode, "rustc-fake"); + + collector_bin } } From 87d2e61428fb5db0781ab008714a7b52d022a082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 12 Jun 2024 12:39:30 +0200 Subject: [PATCH 4/5] Add `x perf` command for profiling the compiler using `rustc-perf` --- src/bootstrap/src/core/build_steps/mod.rs | 1 + src/bootstrap/src/core/build_steps/perf.rs | 45 ++++++++ src/bootstrap/src/core/builder.rs | 6 +- src/bootstrap/src/core/config/config.rs | 4 +- src/bootstrap/src/core/config/flags.rs | 4 + src/bootstrap/src/lib.rs | 3 + src/etc/completions/x.py.fish | 35 +++++++ src/etc/completions/x.py.ps1 | 42 ++++++++ src/etc/completions/x.py.sh | 115 ++++++++++++++++++++- src/etc/completions/x.py.zsh | 49 +++++++++ 10 files changed, 301 insertions(+), 3 deletions(-) create mode 100644 src/bootstrap/src/core/build_steps/perf.rs diff --git a/src/bootstrap/src/core/build_steps/mod.rs b/src/bootstrap/src/core/build_steps/mod.rs index 381ee7ef53b4c..004174e35e1d1 100644 --- a/src/bootstrap/src/core/build_steps/mod.rs +++ b/src/bootstrap/src/core/build_steps/mod.rs @@ -7,6 +7,7 @@ pub(crate) mod doc; pub(crate) mod format; pub(crate) mod install; pub(crate) mod llvm; +pub(crate) mod perf; pub(crate) mod run; pub(crate) mod setup; pub(crate) mod suggest; diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs new file mode 100644 index 0000000000000..16d71808bd8b6 --- /dev/null +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -0,0 +1,45 @@ +use std::process::Command; + +use crate::core::build_steps::compile::{Std, Sysroot}; +use crate::core::build_steps::tool::RustcPerf; +use crate::core::builder::Builder; +use crate::core::config::DebuginfoLevel; + +/// Performs profiling using `rustc-perf` on a built version of the compiler. +pub fn perf(builder: &Builder<'_>) { + let collector = builder.ensure(RustcPerf { + compiler: builder.compiler(0, builder.config.build), + target: builder.config.build, + }); + + if builder.build.config.rust_debuginfo_level_rustc == DebuginfoLevel::None { + builder.info(r#"WARNING: You are compiling rustc without debuginfo, this will make profiling less useful. +Consider setting `rust.debuginfo-level = 1` in `config.toml`."#); + } + + let compiler = builder.compiler(builder.top_stage, builder.config.build); + builder.ensure(Std::new(compiler, builder.config.build)); + let sysroot = builder.ensure(Sysroot::new(compiler)); + let rustc = sysroot.join("bin/rustc"); + + let results_dir = builder.build.out.join("rustc-perf"); + + let mut cmd = Command::new(collector); + let cmd = cmd + .arg("profile_local") + .arg("eprintln") + .arg("--out-dir") + .arg(&results_dir) + .arg("--include") + .arg("helloworld") + .arg(&rustc); + + builder.info(&format!("Running `rustc-perf` using `{}`", rustc.display())); + + // We need to set the working directory to `src/tools/perf`, so that it can find the directory + // with compile-time benchmarks. + let cmd = cmd.current_dir(builder.src.join("src/tools/rustc-perf")); + builder.build.run(cmd); + + builder.info(&format!("You can find the results at `{}`", results_dir.display())); +} diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 55d998dc83c18..769a5d6ae4af2 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -666,6 +666,7 @@ pub enum Kind { Setup, Suggest, Vendor, + Perf, } impl Kind { @@ -687,6 +688,7 @@ impl Kind { Kind::Setup => "setup", Kind::Suggest => "suggest", Kind::Vendor => "vendor", + Kind::Perf => "perf", } } @@ -698,6 +700,7 @@ impl Kind { Kind::Run => "Running", Kind::Suggest => "Suggesting", Kind::Clippy => "Linting", + Kind::Perf => "Profiling & benchmarking", _ => { let title_letter = self.as_str()[0..1].to_ascii_uppercase(); return format!("{title_letter}{}ing", &self.as_str()[1..]); @@ -951,7 +954,7 @@ impl<'a> Builder<'a> { Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std), Kind::Vendor => describe!(vendor::Vendor), // special-cased in Build::build() - Kind::Format | Kind::Suggest => vec![], + Kind::Format | Kind::Suggest | Kind::Perf => vec![], } } @@ -1023,6 +1026,7 @@ impl<'a> Builder<'a> { path.as_ref().map_or([].as_slice(), |path| std::slice::from_ref(path)), ), Subcommand::Vendor { .. } => (Kind::Vendor, &paths[..]), + Subcommand::Perf { .. } => (Kind::Perf, &paths[..]), }; Self::new_internal(build, kind, paths.to_owned()) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 36b44d0169c9c..e82e105be10c2 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2027,6 +2027,7 @@ impl Config { Subcommand::Bench { .. } => flags.stage.or(bench_stage).unwrap_or(2), Subcommand::Dist { .. } => flags.stage.or(dist_stage).unwrap_or(2), Subcommand::Install { .. } => flags.stage.or(install_stage).unwrap_or(2), + Subcommand::Perf { .. } => flags.stage.unwrap_or(1), // These are all bootstrap tools, which don't depend on the compiler. // The stage we pass shouldn't matter, but use 0 just in case. Subcommand::Clean { .. } @@ -2064,7 +2065,8 @@ impl Config { | Subcommand::Setup { .. } | Subcommand::Format { .. } | Subcommand::Suggest { .. } - | Subcommand::Vendor { .. } => {} + | Subcommand::Vendor { .. } + | Subcommand::Perf { .. } => {} } } diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index 83def0c6df0c5..eb5152a38312b 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -469,6 +469,9 @@ Arguments: #[arg(long)] versioned_dirs: bool, }, + /// Perform profiling and benchmarking of the compiler using the + /// `rustc-perf` benchmark suite. + Perf {}, } impl Subcommand { @@ -490,6 +493,7 @@ impl Subcommand { Subcommand::Setup { .. } => Kind::Setup, Subcommand::Suggest { .. } => Kind::Suggest, Subcommand::Vendor { .. } => Kind::Vendor, + Subcommand::Perf { .. } => Kind::Perf, } } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index cde090637e01c..4d67ba897b17b 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -672,6 +672,9 @@ impl Build { Subcommand::Suggest { run } => { return core::build_steps::suggest::suggest(&builder::Builder::new(self), *run); } + Subcommand::Perf { .. } => { + return core::build_steps::perf::perf(&builder::Builder::new(self)); + } _ => (), } diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 7343f3147eed3..2072f76a48181 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -48,6 +48,7 @@ complete -c x.py -n "__fish_use_subcommand" -f -a "run" -d 'Run tools contained complete -c x.py -n "__fish_use_subcommand" -f -a "setup" -d 'Set up the environment for development' complete -c x.py -n "__fish_use_subcommand" -f -a "suggest" -d 'Suggest a subset of tests to run, based on modified files' complete -c x.py -n "__fish_use_subcommand" -f -a "vendor" -d 'Vendor dependencies' +complete -c x.py -n "__fish_use_subcommand" -f -a "perf" -d 'Perform profiling and benchmarking of the compiler using the `rustc-perf` benchmark suite' complete -c x.py -n "__fish_seen_subcommand_from build" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from build" -l build -d 'build target of the stage0 compiler' -r -f @@ -628,3 +629,37 @@ complete -c x.py -n "__fish_seen_subcommand_from vendor" -l llvm-profile-generat complete -c x.py -n "__fish_seen_subcommand_from vendor" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from vendor" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_seen_subcommand_from vendor" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from perf" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from perf" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from perf" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from perf" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from perf" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from perf" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from perf" -l skip -d 'build paths to skip' -r -F +complete -c x.py -n "__fish_seen_subcommand_from perf" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from perf" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from perf" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from perf" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from perf" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from perf" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from perf" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from perf" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" +complete -c x.py -n "__fish_seen_subcommand_from perf" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from perf" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from perf" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" +complete -c x.py -n "__fish_seen_subcommand_from perf" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from perf" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from perf" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from perf" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r +complete -c x.py -n "__fish_seen_subcommand_from perf" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_seen_subcommand_from perf" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from perf" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from perf" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from perf" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from perf" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' +complete -c x.py -n "__fish_seen_subcommand_from perf" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from perf" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' +complete -c x.py -n "__fish_seen_subcommand_from perf" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from perf" -l enable-bolt-settings -d 'Enable BOLT link flags' +complete -c x.py -n "__fish_seen_subcommand_from perf" -l skip-stage0-validation -d 'Skip stage0 compiler validation' +complete -c x.py -n "__fish_seen_subcommand_from perf" -s h -l help -d 'Print help (see more with \'--help\')' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index d9adb1778f2f8..919382d441ffc 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -75,6 +75,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development') [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files') [CompletionResult]::new('vendor', 'vendor', [CompletionResultType]::ParameterValue, 'Vendor dependencies') + [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using the `rustc-perf` benchmark suite') break } 'x.py;build' { @@ -769,6 +770,47 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } + 'x.py;perf' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--reproducible-artifact', 'reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') + [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--dump-bootstrap-shims', 'dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--bypass-bootstrap-lock', 'bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') + [CompletionResult]::new('--skip-stage0-validation', 'skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } }) $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index 6cb9e95c8c102..a4234905476ad 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -45,6 +45,9 @@ _x.py() { bootstrap,miri) cmd="bootstrap__miri" ;; + bootstrap,perf) + cmd="bootstrap__perf" + ;; bootstrap,run) cmd="bootstrap__run" ;; @@ -67,7 +70,7 @@ _x.py() { case "${cmd}" in x.py) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor" + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1414,6 +1417,116 @@ _x.py() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + x.py__perf) + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --reproducible-artifact) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --set) + COMPREPLY=("${cur}") + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; x.py__run) opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index 24ddd1c4b7ccb..bbebf8b892d1f 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -788,6 +788,49 @@ _arguments "${_arguments_options[@]}" \ '--help[Print help (see more with '\''--help'\'')]' \ '*::paths -- paths for the subcommand:_files' \ && ret=0 +;; +(perf) +_arguments "${_arguments_options[@]}" \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ +'--json-output[use message-format=json]' \ +'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'--skip-stage0-validation[Skip stage0 compiler validation]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 ;; esac ;; @@ -813,6 +856,7 @@ _x.py_commands() { 'setup:Set up the environment for development' \ 'suggest:Suggest a subset of tests to run, based on modified files' \ 'vendor:Vendor dependencies' \ +'perf:Perform profiling and benchmarking of the compiler using the \`rustc-perf\` benchmark suite' \ ) _describe -t commands 'x.py commands' commands "$@" } @@ -871,6 +915,11 @@ _x.py__miri_commands() { local commands; commands=() _describe -t commands 'x.py miri commands' commands "$@" } +(( $+functions[_x.py__perf_commands] )) || +_x.py__perf_commands() { + local commands; commands=() + _describe -t commands 'x.py perf commands' commands "$@" +} (( $+functions[_x.py__run_commands] )) || _x.py__run_commands() { local commands; commands=() From 0bd58d8122aa6b6a1ed0a2db6c6a4c5f55ae75c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 09:35:39 +0200 Subject: [PATCH 5/5] Apply review comments. --- src/bootstrap/src/core/build_steps/perf.rs | 2 +- src/bootstrap/src/core/build_steps/tool.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index 16d71808bd8b6..9d70ca6bd71fd 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -22,7 +22,7 @@ Consider setting `rust.debuginfo-level = 1` in `config.toml`."#); let sysroot = builder.ensure(Sysroot::new(compiler)); let rustc = sysroot.join("bin/rustc"); - let results_dir = builder.build.out.join("rustc-perf"); + let results_dir = builder.build.tempdir().join("rustc-perf"); let mut cmd = Command::new(collector); let cmd = cmd diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 03e77c46b6047..7e99de9d477c0 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -129,7 +129,7 @@ impl Step for ToolBuild { if tool == "tidy" { tool = "rust-tidy"; } - copy_tool_bin(builder, self.compiler, self.target, self.mode, tool) + copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool) } } } @@ -214,9 +214,9 @@ pub fn prepare_tool_cargo( cargo } -/// Copies a built tool binary with the given `name` from the build directory to the +/// Links a built tool binary with the given `name` from the build directory to the /// tools directory. -fn copy_tool_bin( +fn copy_link_tool_bin( builder: &Builder<'_>, compiler: Compiler, target: TargetSelection, @@ -413,7 +413,7 @@ impl Step for RustcPerf { let collector_bin = builder.ensure(tool.clone()); // We also need to symlink the `rustc-fake` binary to the corresponding directory, // because `collector` expects it in the same directory. - copy_tool_bin(builder, tool.compiler, tool.target, tool.mode, "rustc-fake"); + copy_link_tool_bin(builder, tool.compiler, tool.target, tool.mode, "rustc-fake"); collector_bin }