@@ -12,7 +12,10 @@ use crate::environment::{Environment, EnvironmentBuilder};
12
12
use crate :: exec:: { cmd, Bootstrap } ;
13
13
use crate :: tests:: run_tests;
14
14
use 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
+ } ;
16
19
use crate :: utils:: artifact_size:: print_binary_sizes;
17
20
use crate :: utils:: io:: { copy_directory, move_directory, reset_directory} ;
18
21
use crate :: utils:: {
@@ -246,13 +249,13 @@ fn execute_pipeline(
246
249
Ok ( profile)
247
250
} ) ?;
248
251
249
- let llvm_bolt_profile = if env. use_bolt ( ) {
252
+ let bolt_profiles = if env. use_bolt ( ) {
250
253
// Stage 3: Build BOLT instrumented LLVM
251
254
// We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
252
255
// Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build.
253
256
// BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc,
254
257
// 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| {
256
259
stage. section ( "Build PGO optimized LLVM" , |stage| {
257
260
Bootstrap :: build ( env)
258
261
. with_llvm_bolt_ldflags ( )
@@ -261,16 +264,17 @@ fn execute_pipeline(
261
264
. run ( stage)
262
265
} ) ?;
263
266
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" ) ?;
270
269
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
+ } )
274
278
} ) ?;
275
279
print_free_disk_space ( ) ?;
276
280
@@ -279,27 +283,43 @@ fn execute_pipeline(
279
283
// the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
280
284
// therefore it will actually optimize all the hard links, which means that the final
281
285
// 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" ) ?;
283
303
284
304
// 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 ] )
286
306
} ) ?
287
307
} else {
288
- None
308
+ vec ! [ ]
289
309
} ;
290
310
291
311
let mut dist = Bootstrap :: dist ( env, & dist_args)
292
312
. llvm_pgo_optimize ( & llvm_pgo_profile)
293
313
. rustc_pgo_optimize ( & rustc_pgo_profile)
294
314
. avoid_rustc_rebuild ( ) ;
295
315
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 ) ;
298
318
}
299
319
300
320
// Final stage: Assemble the dist artifacts
301
321
// 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) ) ?;
303
323
304
324
// After dist has finished, run a subset of the test suite on the optimized artifacts to discover
305
325
// possible regressions.
0 commit comments