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