Auto merge of #116352 - Kobzol:rustc-driver-bolt, r=Mark-Simulacrum

Optimize `librustc_driver.so` with BOLT

This PR optimizes `librustc_driver.so` on 64-bit Linux CI with BOLT.

### Code
One thing that's not clear yet to me how to resolve is how to best pass a linker flag that we need for BOLT (the second commit). It is currently passed unconditionally, which is not a good idea. We somehow have to:
1) Only pass it when we actually plan to use BOLT. How to best do that? `config.toml` entry? Environment variable? CLI flag for bootstrap? BOLT optimization is done by `opt-dist`, therefore bootstrap doesn't know about it by default.
2) Only pass it to `librustc_driver.so` (see performance below).

Some discussion of this flag already happened on [Zulip](https://rust-lang.zulipchat.com/#narrow/stream/326414-t-infra.2Fbootstrap/topic/Adding.20a.20one-off.20linker.20flag).

### Performance
Latest perf. results can be found [here](https://github.com/rust-lang/rust/pull/102487#issuecomment-1743469053). Note that instruction counts are not very interesting here, there are only regressions on hello world programs. Probably caused by a larger C++ libstd (?).

Summary:
- ✔️ `-1.8%` mean improvement in cycle counts across many primary benchmarks.
- ✔️ `-1.8%` mean Max-RSS improvement.
- ✖️ 34 MiB (+48%) artifact size regression of `librustc_driver.so`.
  - This is caused by building `librustc_driver.so` with relocations (which are required for BOLT). Hopefully, it will be [fixed](https://discourse.llvm.org/t/bolt-rfc-a-new-mode-to-rewrite-entire-binary/68674) in the future with BOLT improvements, but now trying to reduce this size increase is [tricky](https://github.com/rust-lang/rust/pull/114649).
  - Note that the size of this file was recently reduced in https://github.com/rust-lang/rust/pull/115554 by pretty much the same amount (33 MiB). So the size after this PR is basically the same as it was for the last ~year.
- ✖️ 1.4 MiB (+53%) artifact size regression of `rustc`.
  - This is annoying and pretty much unnecessary. It is caused by the way relocations are currently applied in this PR, because they are applied both to `librustc_driver.so` (where they are needed) and for `rustc` (where they aren't needed), since both are built with a single cargo invocation. We might need e.g. some tricks in the bootstrap `rustc` shim to only apply the relocation flag for the shared library and not for `rustc`.

### CI time
CI (try build) got slower by ~5 minutes, which is fine, IMO. It can be further reduced by running LLVM and `librustc_driver` BOLT profile gathering at the same time (now they are gathered separately for LLVM and `librustc_driver`).

r? `@Mark-Simulacrum`

Also CC `@onur-ozkan,` primarily for the bootstrap linker flag issue.
This commit is contained in:
bors 2023-10-14 20:34:38 +00:00
commit c543b6f351
12 changed files with 162 additions and 60 deletions

View File

@ -193,6 +193,12 @@ fn main() {
eprintln!("{prefix} libdir: {libdir:?}");
}
if env::var_os("RUSTC_BOLT_LINK_FLAGS").is_some() {
if let Some("rustc_driver") = crate_name {
cmd.arg("-Clink-args=-Wl,-q");
}
}
let start = Instant::now();
let (child, status) = {
let errmsg = format!("\nFailed to run:\n{cmd:?}\n-------------");

View File

@ -906,6 +906,11 @@ impl Step for Rustc {
cargo.arg("-p").arg(krate);
}
if builder.build.config.enable_bolt_settings && compiler.stage == 1 {
// Relocations are required for BOLT to work.
cargo.env("RUSTC_BOLT_LINK_FLAGS", "1");
}
let _guard = builder.msg_sysroot_tool(
Kind::Build,
compiler.stage,

View File

@ -234,6 +234,7 @@ pub struct Config {
pub llvm_profile_use: Option<String>,
pub llvm_profile_generate: bool,
pub llvm_libunwind_default: Option<LlvmLibunwind>,
pub enable_bolt_settings: bool,
pub reproducible_artifacts: Vec<String>,
@ -1128,6 +1129,7 @@ impl Config {
config.free_args = std::mem::take(&mut flags.free_args);
config.llvm_profile_use = flags.llvm_profile_use;
config.llvm_profile_generate = flags.llvm_profile_generate;
config.enable_bolt_settings = flags.enable_bolt_settings;
// Infer the rest of the configuration.

View File

@ -152,6 +152,9 @@ pub struct Flags {
/// generate PGO profile with llvm built for rustc
#[arg(global(true), long)]
pub llvm_profile_generate: bool,
/// Enable BOLT link flags
#[arg(global(true), long)]
pub enable_bolt_settings: bool,
/// Additional reproducible artifacts that should be added to the reproducible artifacts archive.
#[arg(global(true), long)]
pub reproducible_artifact: Vec<String>,

View File

@ -27,10 +27,15 @@ sed -i'' 's|ftp://gcc\.gnu\.org/|https://gcc.gnu.org/|g' ./contrib/download_prer
./contrib/download_prerequisites
mkdir ../gcc-build
cd ../gcc-build
# '-fno-reorder-blocks-and-partition' is required to
# enable BOLT optimization of the C++ standard library,
# which is included in librustc_driver.so
hide_output ../gcc-$GCC/configure \
--prefix=/rustroot \
--enable-languages=c,c++ \
--disable-gnu-unique-object
--disable-gnu-unique-object \
--enable-cxx-flags='-fno-reorder-blocks-and-partition'
hide_output make -j$(nproc)
hide_output make install
ln -s gcc /rustroot/bin/cc

View File

@ -27,6 +27,7 @@ complete -c x.py -n "__fish_use_subcommand" -l include-default-paths -d 'include
complete -c x.py -n "__fish_use_subcommand" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_use_subcommand" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_use_subcommand" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_use_subcommand" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_use_subcommand" -s h -l help -d 'Print help'
complete -c x.py -n "__fish_use_subcommand" -f -a "build" -d 'Compile either the compiler or libraries'
complete -c x.py -n "__fish_use_subcommand" -f -a "check" -d 'Compile either the compiler or libraries, using cargo check'
@ -71,6 +72,7 @@ complete -c x.py -n "__fish_seen_subcommand_from build" -l include-default-paths
complete -c x.py -n "__fish_seen_subcommand_from build" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from build" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from build" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from build" -s h -l help -d 'Print help (see more with \'--help\')'
complete -c x.py -n "__fish_seen_subcommand_from check" -l config -d 'TOML configuration file for build' -r -F
complete -c x.py -n "__fish_seen_subcommand_from check" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
@ -102,6 +104,7 @@ complete -c x.py -n "__fish_seen_subcommand_from check" -l include-default-paths
complete -c x.py -n "__fish_seen_subcommand_from check" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from check" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from check" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from check" -s h -l help -d 'Print help (see more with \'--help\')'
complete -c x.py -n "__fish_seen_subcommand_from clippy" -s A -d 'clippy lints to allow' -r
complete -c x.py -n "__fish_seen_subcommand_from clippy" -s D -d 'clippy lints to deny' -r
@ -137,6 +140,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clippy" -l include-default-path
complete -c x.py -n "__fish_seen_subcommand_from clippy" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from clippy" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from clippy" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from clippy" -s h -l help -d 'Print help (see more with \'--help\')'
complete -c x.py -n "__fish_seen_subcommand_from fix" -l config -d 'TOML configuration file for build' -r -F
complete -c x.py -n "__fish_seen_subcommand_from fix" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
@ -167,6 +171,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fix" -l include-default-paths -
complete -c x.py -n "__fish_seen_subcommand_from fix" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from fix" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from fix" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from fix" -s h -l help -d 'Print help (see more with \'--help\')'
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l config -d 'TOML configuration file for build' -r -F
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
@ -198,6 +203,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fmt" -l include-default-paths -
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from fmt" -s h -l help -d 'Print help (see more with \'--help\')'
complete -c x.py -n "__fish_seen_subcommand_from doc" -l config -d 'TOML configuration file for build' -r -F
complete -c x.py -n "__fish_seen_subcommand_from doc" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
@ -230,6 +236,7 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l include-default-paths -
complete -c x.py -n "__fish_seen_subcommand_from doc" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from doc" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from doc" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from doc" -s h -l help -d 'Print help (see more with \'--help\')'
complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times' -r -F
complete -c x.py -n "__fish_seen_subcommand_from test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
@ -273,6 +280,7 @@ complete -c x.py -n "__fish_seen_subcommand_from test" -l include-default-paths
complete -c x.py -n "__fish_seen_subcommand_from test" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from test" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from test" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help (see more with \'--help\')'
complete -c x.py -n "__fish_seen_subcommand_from bench" -l test-args -r
complete -c x.py -n "__fish_seen_subcommand_from bench" -l config -d 'TOML configuration file for build' -r -F
@ -304,6 +312,7 @@ complete -c x.py -n "__fish_seen_subcommand_from bench" -l include-default-paths
complete -c x.py -n "__fish_seen_subcommand_from bench" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from bench" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from bench" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from bench" -s h -l help -d 'Print help'
complete -c x.py -n "__fish_seen_subcommand_from clean" -l stage -d 'Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used' -r
complete -c x.py -n "__fish_seen_subcommand_from clean" -l config -d 'TOML configuration file for build' -r -F
@ -335,6 +344,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clean" -l include-default-paths
complete -c x.py -n "__fish_seen_subcommand_from clean" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from clean" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from clean" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from clean" -s h -l help -d 'Print help'
complete -c x.py -n "__fish_seen_subcommand_from dist" -l config -d 'TOML configuration file for build' -r -F
complete -c x.py -n "__fish_seen_subcommand_from dist" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
@ -365,6 +375,7 @@ complete -c x.py -n "__fish_seen_subcommand_from dist" -l include-default-paths
complete -c x.py -n "__fish_seen_subcommand_from dist" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from dist" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from dist" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from dist" -s h -l help -d 'Print help'
complete -c x.py -n "__fish_seen_subcommand_from install" -l config -d 'TOML configuration file for build' -r -F
complete -c x.py -n "__fish_seen_subcommand_from install" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
@ -395,6 +406,7 @@ complete -c x.py -n "__fish_seen_subcommand_from install" -l include-default-pat
complete -c x.py -n "__fish_seen_subcommand_from install" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from install" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from install" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from install" -s h -l help -d 'Print help'
complete -c x.py -n "__fish_seen_subcommand_from run" -l args -d 'arguments for the tool' -r
complete -c x.py -n "__fish_seen_subcommand_from run" -l config -d 'TOML configuration file for build' -r -F
@ -426,6 +438,7 @@ complete -c x.py -n "__fish_seen_subcommand_from run" -l include-default-paths -
complete -c x.py -n "__fish_seen_subcommand_from run" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from run" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from run" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from run" -s h -l help -d 'Print help (see more with \'--help\')'
complete -c x.py -n "__fish_seen_subcommand_from setup" -l config -d 'TOML configuration file for build' -r -F
complete -c x.py -n "__fish_seen_subcommand_from setup" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
@ -456,6 +469,7 @@ complete -c x.py -n "__fish_seen_subcommand_from setup" -l include-default-paths
complete -c x.py -n "__fish_seen_subcommand_from setup" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from setup" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from setup" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from setup" -s h -l help -d 'Print help (see more with \'--help\')'
complete -c x.py -n "__fish_seen_subcommand_from suggest" -l config -d 'TOML configuration file for build' -r -F
complete -c x.py -n "__fish_seen_subcommand_from suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
@ -487,4 +501,5 @@ complete -c x.py -n "__fish_seen_subcommand_from suggest" -l include-default-pat
complete -c x.py -n "__fish_seen_subcommand_from suggest" -l dry-run -d 'dry run; don\'t build anything'
complete -c x.py -n "__fish_seen_subcommand_from suggest" -l json-output -d 'use message-format=json'
complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
complete -c x.py -n "__fish_seen_subcommand_from suggest" -l enable-bolt-settings -d 'Enable BOLT link flags'
complete -c x.py -n "__fish_seen_subcommand_from suggest" -s h -l help -d 'Print help (see more with \'--help\')'

View File

@ -53,6 +53,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('build', 'build', [CompletionResultType]::ParameterValue, 'Compile either the compiler or libraries')
@ -104,6 +105,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break
@ -142,6 +144,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break
@ -184,6 +187,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break
@ -221,6 +225,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break
@ -259,6 +264,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break
@ -298,6 +304,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break
@ -348,6 +355,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break
@ -386,6 +394,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
break
@ -424,6 +433,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
break
@ -461,6 +471,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
break
@ -498,6 +509,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
break
@ -536,6 +548,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break
@ -573,6 +586,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break
@ -611,6 +625,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
[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('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
break

View File

@ -61,7 +61,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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest"
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -171,7 +171,7 @@ _x.py() {
return 0
;;
x.py__bench)
opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -285,7 +285,7 @@ _x.py() {
return 0
;;
x.py__build)
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -395,7 +395,7 @@ _x.py() {
return 0
;;
x.py__check)
opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -505,7 +505,7 @@ _x.py() {
return 0
;;
x.py__clean)
opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -615,7 +615,7 @@ _x.py() {
return 0
;;
x.py__clippy)
opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -741,7 +741,7 @@ _x.py() {
return 0
;;
x.py__dist)
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -851,7 +851,7 @@ _x.py() {
return 0
;;
x.py__doc)
opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -961,7 +961,7 @@ _x.py() {
return 0
;;
x.py__fix)
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -1071,7 +1071,7 @@ _x.py() {
return 0
;;
x.py__fmt)
opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -1181,7 +1181,7 @@ _x.py() {
return 0
;;
x.py__install)
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -1291,7 +1291,7 @@ _x.py() {
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -1405,7 +1405,7 @@ _x.py() {
return 0
;;
x.py__setup)
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..."
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 --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -1515,7 +1515,7 @@ _x.py() {
return 0
;;
x.py__suggest)
opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
@ -1625,7 +1625,7 @@ _x.py() {
return 0
;;
x.py__test)
opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0

View File

@ -1,14 +1,14 @@
use anyhow::Context;
use crate::exec::cmd;
use crate::training::LlvmBoltProfile;
use crate::training::BoltProfile;
use camino::{Utf8Path, Utf8PathBuf};
use crate::utils::io::copy_file;
/// Instruments an artifact at the given `path` (in-place) with BOLT and then calls `func`.
/// After this function finishes, the original file will be restored.
pub fn with_bolt_instrumented<F: FnOnce() -> anyhow::Result<R>, R>(
pub fn with_bolt_instrumented<F: FnOnce(&Utf8Path) -> anyhow::Result<R>, R>(
path: &Utf8Path,
func: F,
) -> anyhow::Result<R> {
@ -20,10 +20,16 @@ pub fn with_bolt_instrumented<F: FnOnce() -> anyhow::Result<R>, R>(
let instrumented_path = tempfile::NamedTempFile::new()?.into_temp_path();
let profile_dir =
tempfile::TempDir::new().context("Could not create directory for BOLT profiles")?;
let profile_prefix = profile_dir.path().join("prof.fdata");
let profile_prefix = Utf8Path::from_path(&profile_prefix).unwrap();
// Instrument the original file with BOLT, saving the result into `instrumented_path`
cmd(&["llvm-bolt"])
.arg("-instrument")
.arg(path)
.arg(&format!("--instrumentation-file={profile_prefix}"))
// Make sure that each process will write its profiles into a separate file
.arg("--instrumentation-file-append-pid")
.arg("-o")
@ -36,11 +42,11 @@ pub fn with_bolt_instrumented<F: FnOnce() -> anyhow::Result<R>, R>(
// Run the function that will make use of the instrumented artifact.
// The original file will be restored when `_backup_file` is dropped.
func()
func(profile_prefix)
}
/// Optimizes the file at `path` with BOLT in-place using the given `profile`.
pub fn bolt_optimize(path: &Utf8Path, profile: &LlvmBoltProfile) -> anyhow::Result<()> {
pub fn bolt_optimize(path: &Utf8Path, profile: &BoltProfile) -> anyhow::Result<()> {
// Copy the artifact to a new location, so that we do not use the same input and output file.
// BOLT cannot handle optimizing when the input and output is the same file, because it performs
// in-place patching.

View File

@ -1,7 +1,7 @@
use crate::environment::Environment;
use crate::metrics::{load_metrics, record_metrics};
use crate::timer::TimerSection;
use crate::training::{LlvmBoltProfile, LlvmPGOProfile, RustcPGOProfile};
use crate::training::{BoltProfile, LlvmPGOProfile, RustcPGOProfile};
use camino::{Utf8Path, Utf8PathBuf};
use std::collections::BTreeMap;
use std::fs::File;
@ -159,7 +159,12 @@ impl Bootstrap {
self
}
pub fn with_bolt_profile(mut self, profile: LlvmBoltProfile) -> Self {
pub fn with_rustc_bolt_ldflags(mut self) -> Self {
self.cmd = self.cmd.arg("--enable-bolt-settings");
self
}
pub fn with_bolt_profile(mut self, profile: BoltProfile) -> Self {
self.cmd = self.cmd.arg("--reproducible-artifact").arg(profile.0.as_str());
self
}

View File

@ -12,7 +12,10 @@ use crate::environment::{Environment, EnvironmentBuilder};
use crate::exec::{cmd, Bootstrap};
use crate::tests::run_tests;
use crate::timer::Timer;
use crate::training::{gather_llvm_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles};
use crate::training::{
gather_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles, llvm_benchmarks,
rustc_benchmarks,
};
use crate::utils::artifact_size::print_binary_sizes;
use crate::utils::io::{copy_directory, move_directory, reset_directory};
use crate::utils::{
@ -212,7 +215,12 @@ fn execute_pipeline(
print_free_disk_space()?;
stage.section("Build PGO optimized rustc", |section| {
Bootstrap::build(env).rustc_pgo_optimize(&profile).run(section)
let mut cmd = Bootstrap::build(env).rustc_pgo_optimize(&profile);
if env.use_bolt() {
cmd = cmd.with_rustc_bolt_ldflags();
}
cmd.run(section)
})?;
Ok(profile)
@ -246,13 +254,13 @@ fn execute_pipeline(
Ok(profile)
})?;
let llvm_bolt_profile = if env.use_bolt() {
let bolt_profiles = if env.use_bolt() {
// Stage 3: Build BOLT instrumented LLVM
// We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
// Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build.
// BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc,
// therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
timer.section("Stage 3 (LLVM BOLT)", |stage| {
timer.section("Stage 3 (BOLT)", |stage| {
stage.section("Build PGO optimized LLVM", |stage| {
Bootstrap::build(env)
.with_llvm_bolt_ldflags()
@ -261,16 +269,17 @@ fn execute_pipeline(
.run(stage)
})?;
// Find the path to the `libLLVM.so` file
let llvm_lib = io::find_file_in_dir(
&env.build_artifacts().join("stage2").join("lib"),
"libLLVM",
".so",
)?;
let libdir = env.build_artifacts().join("stage2").join("lib");
let llvm_lib = io::find_file_in_dir(&libdir, "libLLVM", ".so")?;
// Instrument it and gather profiles
let profile = with_bolt_instrumented(&llvm_lib, || {
stage.section("Gather profiles", |_| gather_llvm_bolt_profiles(env))
log::info!("Optimizing {llvm_lib} with BOLT");
// FIXME(kobzol): try gather profiles together, at once for LLVM and rustc
// Instrument the libraries and gather profiles
let llvm_profile = with_bolt_instrumented(&llvm_lib, |llvm_profile_dir| {
stage.section("Gather profiles", |_| {
gather_bolt_profiles(env, "LLVM", llvm_benchmarks(env), llvm_profile_dir)
})
})?;
print_free_disk_space()?;
@ -279,13 +288,29 @@ fn execute_pipeline(
// the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
// therefore it will actually optimize all the hard links, which means that the final
// packaged `libLLVM.so` file *will* be BOLT optimized.
bolt_optimize(&llvm_lib, &profile).context("Could not optimize LLVM with BOLT")?;
bolt_optimize(&llvm_lib, &llvm_profile).context("Could not optimize LLVM with BOLT")?;
let rustc_lib = io::find_file_in_dir(&libdir, "librustc_driver", ".so")?;
log::info!("Optimizing {rustc_lib} with BOLT");
// Instrument it and gather profiles
let rustc_profile = with_bolt_instrumented(&rustc_lib, |rustc_profile_dir| {
stage.section("Gather profiles", |_| {
gather_bolt_profiles(env, "rustc", rustc_benchmarks(env), rustc_profile_dir)
})
})?;
print_free_disk_space()?;
// Now optimize the library with BOLT.
bolt_optimize(&rustc_lib, &rustc_profile)
.context("Could not optimize rustc with BOLT")?;
// LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
Ok(Some(profile))
Ok(vec![llvm_profile, rustc_profile])
})?
} else {
None
vec![]
};
let mut dist = Bootstrap::dist(env, &dist_args)
@ -293,13 +318,13 @@ fn execute_pipeline(
.rustc_pgo_optimize(&rustc_pgo_profile)
.avoid_rustc_rebuild();
if let Some(llvm_bolt_profile) = llvm_bolt_profile {
dist = dist.with_bolt_profile(llvm_bolt_profile);
for bolt_profile in bolt_profiles {
dist = dist.with_bolt_profile(bolt_profile);
}
// Final stage: Assemble the dist artifacts
// The previous PGO optimized rustc build and PGO optimized LLVM builds should be reused.
timer.section("Stage 4 (final build)", |stage| dist.run(stage))?;
timer.section("Stage 5 (final build)", |stage| dist.run(stage))?;
// After dist has finished, run a subset of the test suite on the optimized artifacts to discover
// possible regressions.

View File

@ -27,8 +27,6 @@ const RUSTC_PGO_CRATES: &[&str] = &[
"bitmaps-3.1.0",
];
const LLVM_BOLT_CRATES: &[&str] = LLVM_PGO_CRATES;
fn init_compiler_benchmarks(
env: &Environment,
profiles: &[&str],
@ -113,6 +111,14 @@ fn log_profile_stats(
Ok(())
}
pub fn llvm_benchmarks(env: &Environment) -> CmdBuilder {
init_compiler_benchmarks(env, &["Debug", "Opt"], &["Full"], LLVM_PGO_CRATES)
}
pub fn rustc_benchmarks(env: &Environment) -> CmdBuilder {
init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["All"], RUSTC_PGO_CRATES)
}
pub struct LlvmPGOProfile(pub Utf8PathBuf);
pub fn gather_llvm_profiles(
@ -122,9 +128,7 @@ pub fn gather_llvm_profiles(
log::info!("Running benchmarks with PGO instrumented LLVM");
with_log_group("Running benchmarks", || {
init_compiler_benchmarks(env, &["Debug", "Opt"], &["Full"], LLVM_PGO_CRATES)
.run()
.context("Cannot gather LLVM PGO profiles")
llvm_benchmarks(env).run().context("Cannot gather LLVM PGO profiles")
})?;
let merged_profile = env.artifact_dir().join("llvm-pgo.profdata");
@ -157,7 +161,7 @@ pub fn gather_rustc_profiles(
// Here we're profiling the `rustc` frontend, so we also include `Check`.
// The benchmark set includes various stress tests that put the frontend under pressure.
with_log_group("Running benchmarks", || {
init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["All"], RUSTC_PGO_CRATES)
rustc_benchmarks(env)
.env("LLVM_PROFILE_FILE", profile_template.as_str())
.run()
.context("Cannot gather rustc PGO profiles")
@ -176,23 +180,25 @@ pub fn gather_rustc_profiles(
Ok(RustcPGOProfile(merged_profile))
}
pub struct LlvmBoltProfile(pub Utf8PathBuf);
pub struct BoltProfile(pub Utf8PathBuf);
pub fn gather_llvm_bolt_profiles(env: &Environment) -> anyhow::Result<LlvmBoltProfile> {
log::info!("Running benchmarks with BOLT instrumented LLVM");
pub fn gather_bolt_profiles(
env: &Environment,
name: &str,
benchmarks: CmdBuilder,
profile_prefix: &Utf8Path,
) -> anyhow::Result<BoltProfile> {
log::info!("Running benchmarks with BOLT instrumented {name}");
with_log_group("Running benchmarks", || {
init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["Full"], LLVM_BOLT_CRATES)
.run()
.context("Cannot gather LLVM BOLT profiles")
benchmarks.run().with_context(|| "Cannot gather {name} BOLT profiles")
})?;
let merged_profile = env.artifact_dir().join("llvm-bolt.profdata");
let profile_root = Utf8PathBuf::from("/tmp/prof.fdata");
log::info!("Merging LLVM BOLT profiles to {merged_profile}");
let merged_profile = env.artifact_dir().join(format!("{name}-bolt.profdata"));
log::info!("Merging {name} BOLT profiles from {profile_prefix} to {merged_profile}");
let profiles: Vec<_> =
glob::glob(&format!("{profile_root}*"))?.collect::<Result<Vec<_>, _>>()?;
glob::glob(&format!("{profile_prefix}*"))?.collect::<Result<Vec<_>, _>>()?;
let mut merge_args = vec!["merge-fdata"];
merge_args.extend(profiles.iter().map(|p| p.to_str().unwrap()));
@ -204,7 +210,7 @@ pub fn gather_llvm_bolt_profiles(env: &Environment) -> anyhow::Result<LlvmBoltPr
.context("Cannot merge BOLT profiles")
})?;
log::info!("LLVM BOLT statistics");
log::info!("{name} BOLT statistics");
log::info!(
"{merged_profile}: {}",
humansize::format_size(std::fs::metadata(merged_profile.as_std_path())?.len(), BINARY)
@ -216,8 +222,17 @@ pub fn gather_llvm_bolt_profiles(env: &Environment) -> anyhow::Result<LlvmBoltPr
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.sum::<u64>();
log::info!("{profile_root}: {}", humansize::format_size(size, BINARY));
log::info!("{profile_prefix}: {}", humansize::format_size(size, BINARY));
log::info!("Profile file count: {}", profiles.len());
Ok(LlvmBoltProfile(merged_profile))
// Delete the gathered profiles
for profile in glob::glob(&format!("{profile_prefix}*"))?.into_iter() {
if let Ok(profile) = profile {
if let Err(error) = std::fs::remove_file(&profile) {
log::error!("Cannot delete BOLT profile {}: {error:?}", profile.display());
}
}
}
Ok(BoltProfile(merged_profile))
}