@@ -327,7 +327,7 @@ fn execute_pipeline(
327327 // therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
328328 let libdir = env. build_artifacts ( ) . join ( "stage2" ) . join ( "lib" ) ;
329329 timer. section ( "Stage 3 (BOLT)" , |stage| {
330- let llvm_profile = if env. build_llvm ( ) {
330+ let llvm_data = if env. build_llvm ( ) {
331331 stage. section ( "Build PGO optimized LLVM" , |stage| {
332332 Bootstrap :: build ( env)
333333 . with_llvm_bolt_ldflags ( )
@@ -356,17 +356,7 @@ fn execute_pipeline(
356356 } )
357357 } ) ?;
358358 print_free_disk_space ( ) ?;
359-
360- // Now optimize the library with BOLT. The `libLLVM-XXX.so` library is actually hard-linked
361- // from several places, and this specific path (`llvm_lib`) will *not* be packaged into
362- // the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
363- // therefore it will actually optimize all the hard links, which means that the final
364- // packaged `libLLVM.so` file *will* be BOLT optimized.
365- stage. section ( "Optimize" , |_| {
366- bolt_optimize ( & llvm_lib, & llvm_profile, env)
367- . context ( "Could not optimize LLVM with BOLT" )
368- } ) ?;
369- Some ( llvm_profile)
359+ Some ( ( llvm_lib, llvm_profile) )
370360 } else {
371361 None
372362 } ;
@@ -385,14 +375,40 @@ fn execute_pipeline(
385375 } ) ?;
386376 print_free_disk_space ( ) ?;
387377
388- // Now optimize the library with BOLT.
389- stage. section ( "Optimize" , |_| {
390- bolt_optimize ( & rustc_lib, & rustc_profile, env)
391- . context ( "Could not optimize rustc with BOLT" )
378+ stage. section ( "Optimize LLVM and rustc with BOLT" , |_| {
379+ std:: thread:: scope ( |scope| {
380+ let mut handles = vec ! [ ] ;
381+ // Now optimize the libLLVM library with BOLT. The `libLLVM-XXX.so` library is actually hard-linked
382+ // from several places, and this specific path (`llvm_lib`) will *not* be packaged into
383+ // the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
384+ // therefore it will actually optimize all the hard links, which means that the final
385+ // packaged `libLLVM.so` file *will* be BOLT optimized.
386+ if let Some ( ( llvm_lib, llvm_profile) ) = & llvm_data {
387+ handles. push ( scope. spawn ( move || {
388+ bolt_optimize ( & llvm_lib, & llvm_profile, env)
389+ . context ( "Could not optimize LLVM with BOLT" ) ?;
390+ anyhow:: Ok ( ( ) )
391+ } ) ) ;
392+ }
393+
394+ handles. push ( scope. spawn ( || {
395+ // Now optimize the librustc_driver library with BOLT.
396+ bolt_optimize ( & rustc_lib, & rustc_profile, env)
397+ . context ( "Could not optimize rustc with BOLT" ) ?;
398+ Ok ( ( ) )
399+ } ) ) ;
400+
401+ for handle in handles {
402+ handle. join ( ) . unwrap ( ) ?;
403+ }
404+
405+ anyhow:: Ok ( ( ) )
406+ } ) ?;
407+ Ok ( ( ) )
392408 } ) ?;
393409 // LLVM is not being cleared here. Either we built it and we want to use the BOLT-optimized LLVM, or we
394410 // didn't build it, so we don't want to remove it.
395- Ok ( vec ! [ llvm_profile , Some ( rustc_profile) ] )
411+ Ok ( vec ! [ llvm_data . map ( | ( _ , profile ) | profile ) , Some ( rustc_profile) ] )
396412 } ) ?
397413 } else {
398414 vec ! [ ]
0 commit comments