Skip to content
/ rust Public
forked from rust-lang/rust

Commit 142995f

Browse files
committed
Pass BOLT profile to bootstrap to be included in the reproducible artifacts archive
1 parent 78403f4 commit 142995f

File tree

8 files changed

+36
-32
lines changed

8 files changed

+36
-32
lines changed

Diff for: src/bootstrap/config.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,8 @@ pub struct Config {
232232
pub llvm_profile_use: Option<String>,
233233
pub llvm_profile_generate: bool,
234234
pub llvm_libunwind_default: Option<LlvmLibunwind>,
235-
pub llvm_bolt_profile_generate: bool,
236-
pub llvm_bolt_profile_use: Option<String>,
235+
236+
pub reproducible_artifacts: Vec<String>,
237237

238238
pub build: TargetSelection,
239239
pub hosts: Vec<TargetSelection>,
@@ -1462,6 +1462,8 @@ impl Config {
14621462
config.rust_profile_generate = flags.rust_profile_generate;
14631463
}
14641464

1465+
config.reproducible_artifacts = flags.reproducible_artifact;
1466+
14651467
// rust_info must be set before is_ci_llvm_available() is called.
14661468
let default = config.channel == "dev";
14671469
config.omit_git_hash = omit_git_hash.unwrap_or(default);

Diff for: src/bootstrap/dist.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2265,8 +2265,8 @@ impl Step for ReproducibleArtifacts {
22652265
tarball.add_file(path, ".", 0o644);
22662266
added_anything = true;
22672267
}
2268-
if let Some(path) = builder.config.llvm_bolt_profile_use.as_ref() {
2269-
tarball.add_file(path, ".", 0o644);
2268+
for profile in &builder.config.reproducible_artifacts {
2269+
tarball.add_file(profile, ".", 0o644);
22702270
added_anything = true;
22712271
}
22722272
if added_anything { Some(tarball.generate()) } else { None }

Diff for: src/bootstrap/flags.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,9 @@ pub struct Flags {
149149
/// generate PGO profile with llvm built for rustc
150150
#[arg(global(true), long)]
151151
pub llvm_profile_generate: bool,
152-
/// generate BOLT profile for LLVM build
152+
/// Additional reproducible artifacts that should be added to the reproducible artifacts archive.
153153
#[arg(global(true), long)]
154-
pub llvm_bolt_profile_generate: bool,
155-
/// use BOLT profile for LLVM build
156-
#[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
157-
pub llvm_bolt_profile_use: Option<String>,
154+
pub reproducible_artifact: Vec<String>,
158155
#[arg(global(true))]
159156
/// paths for the subcommand
160157
pub paths: Vec<PathBuf>,

Diff for: src/tools/opt-dist/src/bolt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub fn with_bolt_instrumented<F: FnOnce() -> anyhow::Result<R>, R>(
4040
}
4141

4242
/// Optimizes the file at `path` with BOLT in-place using the given `profile`.
43-
pub fn bolt_optimize(path: &Utf8Path, profile: LlvmBoltProfile) -> anyhow::Result<()> {
43+
pub fn bolt_optimize(path: &Utf8Path, profile: &LlvmBoltProfile) -> anyhow::Result<()> {
4444
// Copy the artifact to a new location, so that we do not use the same input and output file.
4545
// BOLT cannot handle optimizing when the input and output is the same file, because it performs
4646
// in-place patching.

Diff for: src/tools/opt-dist/src/exec.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::environment::Environment;
22
use crate::metrics::{load_metrics, record_metrics};
33
use crate::timer::TimerSection;
4-
use crate::training::{LlvmPGOProfile, RustcPGOProfile};
4+
use crate::training::{LlvmBoltProfile, LlvmPGOProfile, RustcPGOProfile};
55
use camino::{Utf8Path, Utf8PathBuf};
66
use std::collections::BTreeMap;
77
use std::fs::File;
@@ -159,6 +159,11 @@ impl Bootstrap {
159159
self
160160
}
161161

162+
pub fn with_bolt_profile(mut self, profile: LlvmBoltProfile) -> Self {
163+
self.cmd = self.cmd.arg("--reproducible-artifact").arg(profile.0.as_str());
164+
self
165+
}
166+
162167
/// Do not rebuild rustc, and use a previously built rustc sysroot instead.
163168
pub fn avoid_rustc_rebuild(mut self) -> Self {
164169
self.cmd = self.cmd.arg("--keep-stage").arg("0").arg("--keep-stage").arg("1");

Diff for: src/tools/opt-dist/src/main.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ fn execute_pipeline(
9595
Ok(profile)
9696
})?;
9797

98-
if env.supports_bolt() {
98+
let llvm_bolt_profile = if env.supports_bolt() {
9999
// Stage 3: Build BOLT instrumented LLVM
100100
// We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
101101
// 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(
128128
// the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
129129
// therefore it will actually optimize all the hard links, which means that the final
130130
// packaged `libLLVM.so` file *will* be BOLT optimized.
131-
bolt_optimize(&llvm_lib, profile).context("Could not optimize LLVM with BOLT")?;
131+
bolt_optimize(&llvm_lib, &profile).context("Could not optimize LLVM with BOLT")?;
132132

133133
// LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
134-
Ok(())
135-
})?;
136-
}
134+
Ok(Some(profile))
135+
})?
136+
} else {
137+
None
138+
};
137139

138-
let dist = Bootstrap::dist(env, &dist_args)
140+
let mut dist = Bootstrap::dist(env, &dist_args)
139141
.llvm_pgo_optimize(&llvm_pgo_profile)
140142
.rustc_pgo_optimize(&rustc_pgo_profile)
141143
.avoid_rustc_rebuild();
142144

145+
if let Some(llvm_bolt_profile) = llvm_bolt_profile {
146+
dist = dist.with_bolt_profile(llvm_bolt_profile);
147+
}
148+
143149
// Final stage: Assemble the dist artifacts
144150
// The previous PGO optimized rustc build and PGO optimized LLVM builds should be reused.
145151
timer.section("Stage 4 (final build)", |stage| dist.run(stage))?;

Diff for: src/tools/opt-dist/src/training.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ pub fn gather_llvm_bolt_profiles(env: &dyn Environment) -> anyhow::Result<LlvmBo
175175
.context("Cannot gather LLVM BOLT profiles")
176176
})?;
177177

178-
let merged_profile = env.opt_artifacts().join("bolt.profdata");
178+
let merged_profile = env.opt_artifacts().join("llvm-bolt.profdata");
179179
let profile_root = Utf8PathBuf::from("/tmp/prof.fdata");
180180
log::info!("Merging LLVM BOLT profiles to {merged_profile}");
181181

Diff for: src/tools/opt-dist/src/utils/io.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,15 @@ pub fn find_file_in_dir(
7474
prefix: &str,
7575
suffix: &str,
7676
) -> anyhow::Result<Utf8PathBuf> {
77-
let mut files = glob::glob(&format!("{directory}/{prefix}*{suffix}"))?
77+
let files = glob::glob(&format!("{directory}/{prefix}*{suffix}"))?
7878
.into_iter()
7979
.collect::<Result<Vec<_>, _>>()?;
80-
match files.pop() {
81-
Some(file) => {
82-
if !files.is_empty() {
83-
files.push(file);
84-
Err(anyhow::anyhow!(
85-
"More than one file with prefix {prefix} found in {directory}: {:?}",
86-
files
87-
))
88-
} else {
89-
Ok(Utf8PathBuf::from_path_buf(file).unwrap())
90-
}
91-
}
92-
None => Err(anyhow::anyhow!("No file with prefix {prefix} found in {directory}")),
80+
match files.len() {
81+
0 => Err(anyhow::anyhow!("No file with prefix {prefix} found in {directory}")),
82+
1 => Ok(Utf8PathBuf::from_path_buf(files[0].clone()).unwrap()),
83+
_ => Err(anyhow::anyhow!(
84+
"More than one file with prefix {prefix} found in {directory}: {:?}",
85+
files
86+
)),
9387
}
9488
}

0 commit comments

Comments
 (0)