Skip to content

opt-dist: make llvm builds optional #143928

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/tools/opt-dist/src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct Environment {
shared_llvm: bool,
run_tests: bool,
fast_try_build: bool,
build_llvm: bool,
}

impl Environment {
Expand Down Expand Up @@ -111,6 +112,10 @@ impl Environment {
pub fn is_fast_try_build(&self) -> bool {
self.fast_try_build
}

pub fn build_llvm(&self) -> bool {
self.build_llvm
}
}

/// What is the extension of binary executables on this platform?
Expand Down
11 changes: 7 additions & 4 deletions src/tools/opt-dist/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,13 @@ impl Bootstrap {
}

pub fn llvm_pgo_instrument(mut self, profile_dir: &Utf8Path) -> Self {
self.cmd = self
.cmd
.arg("--llvm-profile-generate")
.env("LLVM_PROFILE_DIR", profile_dir.join("prof-%p").as_str());
// if env.build_llvm is false, then unexistent (empty) path is passed
if let Ok(true) = profile_dir.try_exists() {
self.cmd = self
.cmd
.arg("--llvm-profile-generate")
.env("LLVM_PROFILE_DIR", profile_dir.join("prof-%p").as_str());
}
self
}

Expand Down
55 changes: 34 additions & 21 deletions src/tools/opt-dist/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::exec::{Bootstrap, cmd};
use crate::tests::run_tests;
use crate::timer::Timer;
use crate::training::{
gather_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles, llvm_benchmarks,
rustc_benchmarks,
LlvmPGOProfile, 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, reset_directory};
Expand Down Expand Up @@ -98,6 +98,10 @@ enum EnvironmentCmd {
/// Perform tests after final build if it's not a fast try build
#[arg(long)]
run_tests: bool,

/// Will be LLVM built during the run?
#[arg(long, default_value_t = true, action(clap::ArgAction::Set))]
build_llvm: bool,
},
/// Perform an optimized build on Linux CI, from inside Docker.
LinuxCi {
Expand Down Expand Up @@ -133,6 +137,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
benchmark_cargo_config,
shared,
run_tests,
build_llvm,
} => {
let env = EnvironmentBuilder::default()
.host_tuple(target_triple)
Expand All @@ -148,6 +153,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
.benchmark_cargo_config(benchmark_cargo_config)
.run_tests(run_tests)
.fast_try_build(is_fast_try_build)
.build_llvm(build_llvm)
.build()?;

(env, shared.build_args)
Expand All @@ -172,6 +178,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
.skipped_tests(vec![])
.run_tests(true)
.fast_try_build(is_fast_try_build)
.build_llvm(true)
.build()?;

(env, shared.build_args)
Expand All @@ -193,6 +200,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
.skipped_tests(vec![])
.run_tests(true)
.fast_try_build(is_fast_try_build)
.build_llvm(true)
.build()?;

(env, shared.build_args)
Expand Down Expand Up @@ -255,32 +263,37 @@ fn execute_pipeline(
// Stage 2: Gather LLVM PGO profiles
// Here we build a PGO instrumented LLVM, reusing the previously PGO optimized rustc.
// Then we use the instrumented LLVM to gather LLVM PGO profiles.
let llvm_pgo_profile = timer.section("Stage 2 (LLVM PGO)", |stage| {
// Remove the previous, uninstrumented build of LLVM.
clear_llvm_files(env)?;
let llvm_pgo_profile = if env.build_llvm() {
timer.section("Stage 2 (LLVM PGO)", |stage| {
// Remove the previous, uninstrumented build of LLVM.
clear_llvm_files(env)?;

let llvm_profile_dir_root = env.artifact_dir().join("llvm-pgo");
let llvm_profile_dir_root = env.artifact_dir().join("llvm-pgo");

stage.section("Build PGO instrumented LLVM", |section| {
Bootstrap::build(env)
.llvm_pgo_instrument(&llvm_profile_dir_root)
.avoid_rustc_rebuild()
.run(section)
})?;
stage.section("Build PGO instrumented LLVM", |section| {
Bootstrap::build(env)
.llvm_pgo_instrument(&llvm_profile_dir_root)
.avoid_rustc_rebuild()
.run(section)
})?;

let profile = stage
.section("Gather profiles", |_| gather_llvm_profiles(env, &llvm_profile_dir_root))?;
let profile = stage.section("Gather profiles", |_| {
gather_llvm_profiles(env, &llvm_profile_dir_root)
})?;

print_free_disk_space()?;
print_free_disk_space()?;

// Proactively delete the instrumented artifacts, to avoid using them by accident in
// follow-up stages.
clear_llvm_files(env)?;
// Proactively delete the instrumented artifacts, to avoid using them by accident in
// follow-up stages.
clear_llvm_files(env)?;

Ok(profile)
})?;
Ok(profile)
})?
} else {
LlvmPGOProfile(Utf8PathBuf::new())
};

let bolt_profiles = if env.use_bolt() {
let bolt_profiles = if env.build_llvm() && 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.
Expand Down
4 changes: 3 additions & 1 deletion src/tools/opt-dist/src/training.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ pub fn gather_rustc_profiles(
let merged_profile = env.artifact_dir().join("rustc-pgo.profdata");
log::info!("Merging Rustc PGO profiles to {merged_profile}");

merge_llvm_profiles(env, &merged_profile, profile_root, LlvmProfdata::Target)?;
let llvm_profdata = if env.build_llvm() { LlvmProfdata::Target } else { LlvmProfdata::Host };

merge_llvm_profiles(env, &merged_profile, profile_root, llvm_profdata)?;
log_profile_stats("Rustc", &merged_profile, profile_root)?;

// We don't need the individual .profraw files now that they have been merged
Expand Down
Loading