Skip to content

Commit 8d13015

Browse files
committed
Optimize librustc_driver with BOLT
1 parent 8bffefa commit 8d13015

File tree

1 file changed

+29
-47
lines changed

1 file changed

+29
-47
lines changed

src/tools/opt-dist/src/main.rs

+29-47
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::tests::run_tests;
1414
use crate::timer::Timer;
1515
use crate::training::{
1616
gather_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles, llvm_benchmarks,
17+
rustc_benchmarks,
1718
};
1819
use crate::utils::io::{copy_directory, move_directory, reset_directory};
1920
use crate::utils::{
@@ -247,13 +248,13 @@ fn execute_pipeline(
247248
Ok(profile)
248249
})?;
249250

250-
let llvm_bolt_profile = if env.use_bolt() {
251+
let bolt_profiles = if env.use_bolt() {
251252
// Stage 3: Build BOLT instrumented LLVM
252253
// We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
253254
// Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build.
254255
// BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc,
255256
// therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
256-
timer.section("Stage 3 (LLVM BOLT)", |stage| {
257+
timer.section("Stage 3 (BOLT)", |stage| {
257258
stage.section("Build PGO optimized LLVM", |stage| {
258259
Bootstrap::build(env)
259260
.with_llvm_bolt_ldflags()
@@ -262,17 +263,14 @@ fn execute_pipeline(
262263
.run(stage)
263264
})?;
264265

265-
// Find the path to the `libLLVM.so` file
266-
let llvm_lib = io::find_file_in_dir(
267-
&env.build_artifacts().join("stage2").join("lib"),
268-
"libLLVM",
269-
".so",
270-
)?;
266+
let libdir = env.build_artifacts().join("stage2").join("lib");
267+
let llvm_lib = io::find_file_in_dir(&libdir, "libLLVM", ".so")?;
271268

272269
log::info!("Optimizing {llvm_lib} with BOLT");
273270

274-
// Instrument it and gather profiles
275-
let profile = with_bolt_instrumented(&llvm_lib, |llvm_profile_dir| {
271+
// FIXME(kobzol: try gather profiles together, at once for LLVM and rustc
272+
// Instrument the libraries and gather profiles
273+
let llvm_profile = with_bolt_instrumented(&llvm_lib, |llvm_profile_dir| {
276274
stage.section("Gather profiles", |_| {
277275
gather_bolt_profiles(env, "LLVM", llvm_benchmarks(env), llvm_profile_dir)
278276
})
@@ -284,55 +282,39 @@ fn execute_pipeline(
284282
// the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
285283
// therefore it will actually optimize all the hard links, which means that the final
286284
// packaged `libLLVM.so` file *will* be BOLT optimized.
287-
bolt_optimize(&llvm_lib, &profile).context("Could not optimize LLVM with BOLT")?;
285+
bolt_optimize(&llvm_lib, &llvm_profile).context("Could not optimize LLVM with BOLT")?;
286+
287+
let rustc_lib = io::find_file_in_dir(&libdir, "librustc_driver", ".so")?;
288+
289+
log::info!("Optimizing {rustc_lib} with BOLT");
290+
291+
// Instrument it and gather profiles
292+
let rustc_profile = with_bolt_instrumented(&rustc_lib, |rustc_profile_dir| {
293+
stage.section("Gather profiles", |_| {
294+
gather_bolt_profiles(env, "rustc", rustc_benchmarks(env), rustc_profile_dir)
295+
})
296+
})?;
297+
print_free_disk_space()?;
298+
299+
// Now optimize the library with BOLT.
300+
bolt_optimize(&rustc_lib, &rustc_profile)
301+
.context("Could not optimize rustc with BOLT")?;
288302

289303
// LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
290-
Ok(Some(profile))
304+
Ok(vec![llvm_profile, rustc_profile])
291305
})?
292306
} else {
293-
None
307+
vec![]
294308
};
295309

296-
// let rustc_bolt_profile = if env.use_bolt() {
297-
// // Stage 4: Build BOLT instrumented rustc
298-
// timer.section("Stage 4 (Rustc BOLT)", |stage| {
299-
// // Find the path to the `librustc_driver.so` file
300-
// let rustc_lib = io::find_file_in_dir(
301-
// &env.build_artifacts().join("stage2").join("lib"),
302-
// "librustc_driver",
303-
// ".so",
304-
// )?;
305-
//
306-
// log::info!("Optimizing {rustc_lib} with BOLT");
307-
//
308-
// // Instrument it and gather profiles
309-
// let profile = with_bolt_instrumented(&rustc_lib, || {
310-
// stage.section("Gather profiles", |_| {
311-
// gather_bolt_profiles(env, "rustc", rustc_benchmarks(env))
312-
// })
313-
// })?;
314-
// print_free_disk_space()?;
315-
//
316-
// // Now optimize the library with BOLT.
317-
// bolt_optimize(&rustc_lib, &profile).context("Could not optimize rustc with BOLT")?;
318-
//
319-
// Ok(Some(profile))
320-
// })?
321-
// } else {
322-
// None
323-
// };
324-
325310
let mut dist = Bootstrap::dist(env, &dist_args)
326311
.llvm_pgo_optimize(&llvm_pgo_profile)
327312
.rustc_pgo_optimize(&rustc_pgo_profile)
328313
.avoid_rustc_rebuild();
329314

330-
if let Some(llvm_bolt_profile) = llvm_bolt_profile {
331-
dist = dist.with_bolt_profile(llvm_bolt_profile);
315+
for bolt_profile in bolt_profiles {
316+
dist = dist.with_bolt_profile(bolt_profile);
332317
}
333-
// if let Some(rustc_bolt_profile) = rustc_bolt_profile {
334-
// dist = dist.with_bolt_profile(rustc_bolt_profile);
335-
// }
336318

337319
// Final stage: Assemble the dist artifacts
338320
// The previous PGO optimized rustc build and PGO optimized LLVM builds should be reused.

0 commit comments

Comments
 (0)