@@ -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:: io:: { copy_directory, move_directory, reset_directory} ;
1720use crate :: utils:: {
1821 clear_llvm_files, format_env_variables, print_binary_sizes, print_free_disk_space,
@@ -245,13 +248,13 @@ fn execute_pipeline(
245248 Ok ( profile)
246249 } ) ?;
247250
248- let llvm_bolt_profile = if env. use_bolt ( ) {
251+ let bolt_profiles = if env. use_bolt ( ) {
249252 // Stage 3: Build BOLT instrumented LLVM
250253 // We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
251254 // Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build.
252255 // BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc,
253256 // therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
254- timer. section ( "Stage 3 (LLVM BOLT)" , |stage| {
257+ timer. section ( "Stage 3 (BOLT)" , |stage| {
255258 stage. section ( "Build PGO optimized LLVM" , |stage| {
256259 Bootstrap :: build ( env)
257260 . with_llvm_bolt_ldflags ( )
@@ -260,16 +263,17 @@ fn execute_pipeline(
260263 . run ( stage)
261264 } ) ?;
262265
263- // Find the path to the `libLLVM.so` file
264- let llvm_lib = io:: find_file_in_dir (
265- & env. build_artifacts ( ) . join ( "stage2" ) . join ( "lib" ) ,
266- "libLLVM" ,
267- ".so" ,
268- ) ?;
266+ let libdir = env. build_artifacts ( ) . join ( "stage2" ) . join ( "lib" ) ;
267+ let llvm_lib = io:: find_file_in_dir ( & libdir, "libLLVM" , ".so" ) ?;
269268
270- // Instrument it and gather profiles
271- let profile = with_bolt_instrumented ( & llvm_lib, || {
272- stage. section ( "Gather profiles" , |_| gather_llvm_bolt_profiles ( env) )
269+ log:: info!( "Optimizing {llvm_lib} with BOLT" ) ;
270+
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| {
274+ stage. section ( "Gather profiles" , |_| {
275+ gather_bolt_profiles ( env, "LLVM" , llvm_benchmarks ( env) , llvm_profile_dir)
276+ } )
273277 } ) ?;
274278 print_free_disk_space ( ) ?;
275279
@@ -278,27 +282,43 @@ fn execute_pipeline(
278282 // the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
279283 // therefore it will actually optimize all the hard links, which means that the final
280284 // packaged `libLLVM.so` file *will* be BOLT optimized.
281- 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" ) ?;
282302
283303 // LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
284- Ok ( Some ( profile ) )
304+ Ok ( vec ! [ llvm_profile , rustc_profile ] )
285305 } ) ?
286306 } else {
287- None
307+ vec ! [ ]
288308 } ;
289309
290310 let mut dist = Bootstrap :: dist ( env, & dist_args)
291311 . llvm_pgo_optimize ( & llvm_pgo_profile)
292312 . rustc_pgo_optimize ( & rustc_pgo_profile)
293313 . avoid_rustc_rebuild ( ) ;
294314
295- if let Some ( llvm_bolt_profile ) = llvm_bolt_profile {
296- dist = dist. with_bolt_profile ( llvm_bolt_profile ) ;
315+ for bolt_profile in bolt_profiles {
316+ dist = dist. with_bolt_profile ( bolt_profile ) ;
297317 }
298318
299319 // Final stage: Assemble the dist artifacts
300320 // The previous PGO optimized rustc build and PGO optimized LLVM builds should be reused.
301- timer. section ( "Stage 4 (final build)" , |stage| dist. run ( stage) ) ?;
321+ timer. section ( "Stage 5 (final build)" , |stage| dist. run ( stage) ) ?;
302322
303323 // After dist has finished, run a subset of the test suite on the optimized artifacts to discover
304324 // possible regressions.
0 commit comments