mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Pass BOLT profile to bootstrap to be included in the reproducible artifacts archive
This commit is contained in:
parent
78403f4e13
commit
142995f15f
@ -232,8 +232,8 @@ pub struct Config {
|
|||||||
pub llvm_profile_use: Option<String>,
|
pub llvm_profile_use: Option<String>,
|
||||||
pub llvm_profile_generate: bool,
|
pub llvm_profile_generate: bool,
|
||||||
pub llvm_libunwind_default: Option<LlvmLibunwind>,
|
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 build: TargetSelection,
|
||||||
pub hosts: Vec<TargetSelection>,
|
pub hosts: Vec<TargetSelection>,
|
||||||
@ -1462,6 +1462,8 @@ impl Config {
|
|||||||
config.rust_profile_generate = flags.rust_profile_generate;
|
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.
|
// rust_info must be set before is_ci_llvm_available() is called.
|
||||||
let default = config.channel == "dev";
|
let default = config.channel == "dev";
|
||||||
config.omit_git_hash = omit_git_hash.unwrap_or(default);
|
config.omit_git_hash = omit_git_hash.unwrap_or(default);
|
||||||
|
@ -2265,8 +2265,8 @@ impl Step for ReproducibleArtifacts {
|
|||||||
tarball.add_file(path, ".", 0o644);
|
tarball.add_file(path, ".", 0o644);
|
||||||
added_anything = true;
|
added_anything = true;
|
||||||
}
|
}
|
||||||
if let Some(path) = builder.config.llvm_bolt_profile_use.as_ref() {
|
for profile in &builder.config.reproducible_artifacts {
|
||||||
tarball.add_file(path, ".", 0o644);
|
tarball.add_file(profile, ".", 0o644);
|
||||||
added_anything = true;
|
added_anything = true;
|
||||||
}
|
}
|
||||||
if added_anything { Some(tarball.generate()) } else { None }
|
if added_anything { Some(tarball.generate()) } else { None }
|
||||||
|
@ -149,12 +149,9 @@ pub struct Flags {
|
|||||||
/// generate PGO profile with llvm built for rustc
|
/// generate PGO profile with llvm built for rustc
|
||||||
#[arg(global(true), long)]
|
#[arg(global(true), long)]
|
||||||
pub llvm_profile_generate: bool,
|
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)]
|
#[arg(global(true), long)]
|
||||||
pub llvm_bolt_profile_generate: bool,
|
pub reproducible_artifact: Vec<String>,
|
||||||
/// 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>,
|
|
||||||
#[arg(global(true))]
|
#[arg(global(true))]
|
||||||
/// paths for the subcommand
|
/// paths for the subcommand
|
||||||
pub paths: Vec<PathBuf>,
|
pub paths: Vec<PathBuf>,
|
||||||
|
@ -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`.
|
/// 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.
|
// 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
|
// BOLT cannot handle optimizing when the input and output is the same file, because it performs
|
||||||
// in-place patching.
|
// in-place patching.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::environment::Environment;
|
use crate::environment::Environment;
|
||||||
use crate::metrics::{load_metrics, record_metrics};
|
use crate::metrics::{load_metrics, record_metrics};
|
||||||
use crate::timer::TimerSection;
|
use crate::timer::TimerSection;
|
||||||
use crate::training::{LlvmPGOProfile, RustcPGOProfile};
|
use crate::training::{LlvmBoltProfile, LlvmPGOProfile, RustcPGOProfile};
|
||||||
use camino::{Utf8Path, Utf8PathBuf};
|
use camino::{Utf8Path, Utf8PathBuf};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
@ -159,6 +159,11 @@ impl Bootstrap {
|
|||||||
self
|
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.
|
/// Do not rebuild rustc, and use a previously built rustc sysroot instead.
|
||||||
pub fn avoid_rustc_rebuild(mut self) -> Self {
|
pub fn avoid_rustc_rebuild(mut self) -> Self {
|
||||||
self.cmd = self.cmd.arg("--keep-stage").arg("0").arg("--keep-stage").arg("1");
|
self.cmd = self.cmd.arg("--keep-stage").arg("0").arg("--keep-stage").arg("1");
|
||||||
|
@ -95,7 +95,7 @@ fn execute_pipeline(
|
|||||||
Ok(profile)
|
Ok(profile)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if env.supports_bolt() {
|
let llvm_bolt_profile = if env.supports_bolt() {
|
||||||
// Stage 3: Build BOLT instrumented LLVM
|
// Stage 3: Build BOLT instrumented LLVM
|
||||||
// We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
|
// 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.
|
// 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*,
|
// 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
|
// therefore it will actually optimize all the hard links, which means that the final
|
||||||
// packaged `libLLVM.so` file *will* be BOLT optimized.
|
// 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
|
// 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)
|
.llvm_pgo_optimize(&llvm_pgo_profile)
|
||||||
.rustc_pgo_optimize(&rustc_pgo_profile)
|
.rustc_pgo_optimize(&rustc_pgo_profile)
|
||||||
.avoid_rustc_rebuild();
|
.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
|
// Final stage: Assemble the dist artifacts
|
||||||
// The previous PGO optimized rustc build and PGO optimized LLVM builds should be reused.
|
// 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 4 (final build)", |stage| dist.run(stage))?;
|
||||||
|
@ -175,7 +175,7 @@ pub fn gather_llvm_bolt_profiles(env: &dyn Environment) -> anyhow::Result<LlvmBo
|
|||||||
.context("Cannot gather LLVM BOLT profiles")
|
.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");
|
let profile_root = Utf8PathBuf::from("/tmp/prof.fdata");
|
||||||
log::info!("Merging LLVM BOLT profiles to {merged_profile}");
|
log::info!("Merging LLVM BOLT profiles to {merged_profile}");
|
||||||
|
|
||||||
|
@ -74,21 +74,15 @@ pub fn find_file_in_dir(
|
|||||||
prefix: &str,
|
prefix: &str,
|
||||||
suffix: &str,
|
suffix: &str,
|
||||||
) -> anyhow::Result<Utf8PathBuf> {
|
) -> anyhow::Result<Utf8PathBuf> {
|
||||||
let mut files = glob::glob(&format!("{directory}/{prefix}*{suffix}"))?
|
let files = glob::glob(&format!("{directory}/{prefix}*{suffix}"))?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
match files.pop() {
|
match files.len() {
|
||||||
Some(file) => {
|
0 => Err(anyhow::anyhow!("No file with prefix {prefix} found in {directory}")),
|
||||||
if !files.is_empty() {
|
1 => Ok(Utf8PathBuf::from_path_buf(files[0].clone()).unwrap()),
|
||||||
files.push(file);
|
_ => Err(anyhow::anyhow!(
|
||||||
Err(anyhow::anyhow!(
|
"More than one file with prefix {prefix} found in {directory}: {:?}",
|
||||||
"More than one file with prefix {prefix} found in {directory}: {:?}",
|
files
|
||||||
files
|
)),
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Ok(Utf8PathBuf::from_path_buf(file).unwrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => Err(anyhow::anyhow!("No file with prefix {prefix} found in {directory}")),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user