@@ -12,7 +12,10 @@ use crate::environment::{Environment, EnvironmentBuilder};
1212use crate :: exec:: { cmd, Bootstrap } ;
1313use crate :: tests:: run_tests;
1414use crate :: timer:: Timer ;
15- use crate :: training:: { gather_llvm_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles} ;
15+ use crate :: training:: {
16+ gather_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles, llvm_benchmarks,
17+ rustc_benchmarks,
18+ } ;
1619use crate :: utils:: artifact_size:: print_binary_sizes;
1720use crate :: utils:: io:: { copy_directory, move_directory, reset_directory} ;
1821use crate :: utils:: {
@@ -246,13 +249,13 @@ fn execute_pipeline(
246249 Ok ( profile)
247250 } ) ?;
248251
249- let llvm_bolt_profile = if env. use_bolt ( ) {
252+ let bolt_profiles = if env. use_bolt ( ) {
250253 // Stage 3: Build BOLT instrumented LLVM
251254 // We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
252255 // Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build.
253256 // BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc,
254257 // therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
255- timer. section ( "Stage 3 (LLVM BOLT)" , |stage| {
258+ timer. section ( "Stage 3 (BOLT)" , |stage| {
256259 stage. section ( "Build PGO optimized LLVM" , |stage| {
257260 Bootstrap :: build ( env)
258261 . with_llvm_bolt_ldflags ( )
@@ -261,16 +264,17 @@ fn execute_pipeline(
261264 . run ( stage)
262265 } ) ?;
263266
264- // Find the path to the `libLLVM.so` file
265- let llvm_lib = io:: find_file_in_dir (
266- & env. build_artifacts ( ) . join ( "stage2" ) . join ( "lib" ) ,
267- "libLLVM" ,
268- ".so" ,
269- ) ?;
267+ let libdir = env. build_artifacts ( ) . join ( "stage2" ) . join ( "lib" ) ;
268+ let llvm_lib = io:: find_file_in_dir ( & libdir, "libLLVM" , ".so" ) ?;
270269
271- // Instrument it and gather profiles
272- let profile = with_bolt_instrumented ( & llvm_lib, || {
273- stage. section ( "Gather profiles" , |_| gather_llvm_bolt_profiles ( env) )
270+ log:: info!( "Optimizing {llvm_lib} with BOLT" ) ;
271+
272+ // FIXME(kobzol: try gather profiles together, at once for LLVM and rustc
273+ // Instrument the libraries and gather profiles
274+ let llvm_profile = with_bolt_instrumented ( & llvm_lib, |llvm_profile_dir| {
275+ stage. section ( "Gather profiles" , |_| {
276+ gather_bolt_profiles ( env, "LLVM" , llvm_benchmarks ( env) , llvm_profile_dir)
277+ } )
274278 } ) ?;
275279 print_free_disk_space ( ) ?;
276280
@@ -279,27 +283,43 @@ fn execute_pipeline(
279283 // the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
280284 // therefore it will actually optimize all the hard links, which means that the final
281285 // packaged `libLLVM.so` file *will* be BOLT optimized.
282- bolt_optimize ( & llvm_lib, & profile) . context ( "Could not optimize LLVM with BOLT" ) ?;
286+ bolt_optimize ( & llvm_lib, & llvm_profile) . context ( "Could not optimize LLVM with BOLT" ) ?;
287+
288+ let rustc_lib = io:: find_file_in_dir ( & libdir, "librustc_driver" , ".so" ) ?;
289+
290+ log:: info!( "Optimizing {rustc_lib} with BOLT" ) ;
291+
292+ // Instrument it and gather profiles
293+ let rustc_profile = with_bolt_instrumented ( & rustc_lib, |rustc_profile_dir| {
294+ stage. section ( "Gather profiles" , |_| {
295+ gather_bolt_profiles ( env, "rustc" , rustc_benchmarks ( env) , rustc_profile_dir)
296+ } )
297+ } ) ?;
298+ print_free_disk_space ( ) ?;
299+
300+ // Now optimize the library with BOLT.
301+ bolt_optimize ( & rustc_lib, & rustc_profile)
302+ . context ( "Could not optimize rustc with BOLT" ) ?;
283303
284304 // LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
285- Ok ( Some ( profile ) )
305+ Ok ( vec ! [ llvm_profile , rustc_profile ] )
286306 } ) ?
287307 } else {
288- None
308+ vec ! [ ]
289309 } ;
290310
291311 let mut dist = Bootstrap :: dist ( env, & dist_args)
292312 . llvm_pgo_optimize ( & llvm_pgo_profile)
293313 . rustc_pgo_optimize ( & rustc_pgo_profile)
294314 . avoid_rustc_rebuild ( ) ;
295315
296- if let Some ( llvm_bolt_profile ) = llvm_bolt_profile {
297- dist = dist. with_bolt_profile ( llvm_bolt_profile ) ;
316+ for bolt_profile in bolt_profiles {
317+ dist = dist. with_bolt_profile ( bolt_profile ) ;
298318 }
299319
300320 // Final stage: Assemble the dist artifacts
301321 // The previous PGO optimized rustc build and PGO optimized LLVM builds should be reused.
302- timer. section ( "Stage 4 (final build)" , |stage| dist. run ( stage) ) ?;
322+ timer. section ( "Stage 5 (final build)" , |stage| dist. run ( stage) ) ?;
303323
304324 // After dist has finished, run a subset of the test suite on the optimized artifacts to discover
305325 // possible regressions.
0 commit comments