Pass BOLT profile to bootstrap to be included in the reproducible artifacts archive

This commit is contained in:
Jakub Beránek 2023-07-29 17:29:54 +02:00
parent 78403f4e13
commit 142995f15f
No known key found for this signature in database
GPG Key ID: 909CD0D26483516B
8 changed files with 36 additions and 32 deletions

View File

@ -232,8 +232,8 @@ pub struct Config {
pub llvm_profile_use: Option<String>,
pub llvm_profile_generate: bool,
pub llvm_libunwind_default: Option<LlvmLibunwind>,
pub llvm_bolt_profile_generate: bool,
pub llvm_bolt_profile_use: Option<String>,
pub reproducible_artifacts: Vec<String>,
pub build: TargetSelection,
pub hosts: Vec<TargetSelection>,
@ -1462,6 +1462,8 @@ impl Config {
config.rust_profile_generate = flags.rust_profile_generate;
}
config.reproducible_artifacts = flags.reproducible_artifact;
// rust_info must be set before is_ci_llvm_available() is called.
let default = config.channel == "dev";
config.omit_git_hash = omit_git_hash.unwrap_or(default);

View File

@ -2265,8 +2265,8 @@ impl Step for ReproducibleArtifacts {
tarball.add_file(path, ".", 0o644);
added_anything = true;
}
if let Some(path) = builder.config.llvm_bolt_profile_use.as_ref() {
tarball.add_file(path, ".", 0o644);
for profile in &builder.config.reproducible_artifacts {
tarball.add_file(profile, ".", 0o644);
added_anything = true;
}
if added_anything { Some(tarball.generate()) } else { None }

View File

@ -149,12 +149,9 @@ pub struct Flags {
/// generate PGO profile with llvm built for rustc
#[arg(global(true), long)]
pub llvm_profile_generate: bool,
/// generate BOLT profile for LLVM build
/// Additional reproducible artifacts that should be added to the reproducible artifacts archive.
#[arg(global(true), long)]
pub llvm_bolt_profile_generate: bool,
/// use BOLT profile for LLVM build
#[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
pub llvm_bolt_profile_use: Option<String>,
pub reproducible_artifact: Vec<String>,
#[arg(global(true))]
/// paths for the subcommand
pub paths: Vec<PathBuf>,

View File

@ -40,7 +40,7 @@ pub fn with_bolt_instrumented<F: FnOnce() -> anyhow::Result<R>, R>(
}
/// 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: &LlvmBoltProfile) -> 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::{LlvmPGOProfile, RustcPGOProfile};
use crate::training::{LlvmBoltProfile, LlvmPGOProfile, RustcPGOProfile};
use camino::{Utf8Path, Utf8PathBuf};
use std::collections::BTreeMap;
use std::fs::File;
@ -159,6 +159,11 @@ impl Bootstrap {
self
}
pub fn with_bolt_profile(mut self, profile: LlvmBoltProfile) -> Self {
self.cmd = self.cmd.arg("--reproducible-artifact").arg(profile.0.as_str());
self
}
/// Do not rebuild rustc, and use a previously built rustc sysroot instead.
pub fn avoid_rustc_rebuild(mut self) -> Self {
self.cmd = self.cmd.arg("--keep-stage").arg("0").arg("--keep-stage").arg("1");

View File

@ -95,7 +95,7 @@ fn execute_pipeline(
Ok(profile)
})?;
if env.supports_bolt() {
let llvm_bolt_profile = if env.supports_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.
@ -128,18 +128,24 @@ 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, &profile).context("Could not optimize LLVM with BOLT")?;
// LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
Ok(())
})?;
}
Ok(Some(profile))
})?
} else {
None
};
let dist = Bootstrap::dist(env, &dist_args)
let mut dist = Bootstrap::dist(env, &dist_args)
.llvm_pgo_optimize(&llvm_pgo_profile)
.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);
}
// 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))?;

View File

@ -175,7 +175,7 @@ pub fn gather_llvm_bolt_profiles(env: &dyn Environment) -> anyhow::Result<LlvmBo
.context("Cannot gather LLVM BOLT profiles")
})?;
let merged_profile = env.opt_artifacts().join("bolt.profdata");
let merged_profile = env.opt_artifacts().join("llvm-bolt.profdata");
let profile_root = Utf8PathBuf::from("/tmp/prof.fdata");
log::info!("Merging LLVM BOLT profiles to {merged_profile}");

View File

@ -74,21 +74,15 @@ pub fn find_file_in_dir(
prefix: &str,
suffix: &str,
) -> anyhow::Result<Utf8PathBuf> {
let mut files = glob::glob(&format!("{directory}/{prefix}*{suffix}"))?
let files = glob::glob(&format!("{directory}/{prefix}*{suffix}"))?
.into_iter()
.collect::<Result<Vec<_>, _>>()?;
match files.pop() {
Some(file) => {
if !files.is_empty() {
files.push(file);
Err(anyhow::anyhow!(
"More than one file with prefix {prefix} found in {directory}: {:?}",
files
))
} else {
Ok(Utf8PathBuf::from_path_buf(file).unwrap())
}
}
None => Err(anyhow::anyhow!("No file with prefix {prefix} found in {directory}")),
match files.len() {
0 => Err(anyhow::anyhow!("No file with prefix {prefix} found in {directory}")),
1 => Ok(Utf8PathBuf::from_path_buf(files[0].clone()).unwrap()),
_ => Err(anyhow::anyhow!(
"More than one file with prefix {prefix} found in {directory}: {:?}",
files
)),
}
}