@@ -98,6 +98,10 @@ enum EnvironmentCmd {
98
98
/// Perform tests after final build if it's not a fast try build
99
99
#[ arg( long) ]
100
100
run_tests : bool ,
101
+
102
+ /// Will be LLVM built during the run?
103
+ #[ arg( long, default_value_t = true , action( clap:: ArgAction :: Set ) ) ]
104
+ build_llvm : bool ,
101
105
} ,
102
106
/// Perform an optimized build on Linux CI, from inside Docker.
103
107
LinuxCi {
@@ -133,6 +137,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
133
137
benchmark_cargo_config,
134
138
shared,
135
139
run_tests,
140
+ build_llvm,
136
141
} => {
137
142
let env = EnvironmentBuilder :: default ( )
138
143
. host_tuple ( target_triple)
@@ -148,6 +153,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
148
153
. benchmark_cargo_config ( benchmark_cargo_config)
149
154
. run_tests ( run_tests)
150
155
. fast_try_build ( is_fast_try_build)
156
+ . build_llvm ( build_llvm)
151
157
. build ( ) ?;
152
158
153
159
( env, shared. build_args )
@@ -172,6 +178,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
172
178
. skipped_tests ( vec ! [ ] )
173
179
. run_tests ( true )
174
180
. fast_try_build ( is_fast_try_build)
181
+ . build_llvm ( true )
175
182
. build ( ) ?;
176
183
177
184
( env, shared. build_args )
@@ -193,6 +200,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
193
200
. skipped_tests ( vec ! [ ] )
194
201
. run_tests ( true )
195
202
. fast_try_build ( is_fast_try_build)
203
+ . build_llvm ( true )
196
204
. build ( ) ?;
197
205
198
206
( env, shared. build_args )
@@ -255,30 +263,35 @@ fn execute_pipeline(
255
263
// Stage 2: Gather LLVM PGO profiles
256
264
// Here we build a PGO instrumented LLVM, reusing the previously PGO optimized rustc.
257
265
// Then we use the instrumented LLVM to gather LLVM PGO profiles.
258
- let llvm_pgo_profile = timer. section ( "Stage 2 (LLVM PGO)" , |stage| {
259
- // Remove the previous, uninstrumented build of LLVM.
260
- clear_llvm_files ( env) ?;
266
+ let llvm_pgo_profile = if env. build_llvm ( ) {
267
+ timer. section ( "Stage 2 (LLVM PGO)" , |stage| {
268
+ // Remove the previous, uninstrumented build of LLVM.
269
+ clear_llvm_files ( env) ?;
261
270
262
- let llvm_profile_dir_root = env. artifact_dir ( ) . join ( "llvm-pgo" ) ;
271
+ let llvm_profile_dir_root = env. artifact_dir ( ) . join ( "llvm-pgo" ) ;
263
272
264
- stage. section ( "Build PGO instrumented LLVM" , |section| {
265
- Bootstrap :: build ( env)
266
- . llvm_pgo_instrument ( & llvm_profile_dir_root)
267
- . avoid_rustc_rebuild ( )
268
- . run ( section)
269
- } ) ?;
273
+ stage. section ( "Build PGO instrumented LLVM" , |section| {
274
+ Bootstrap :: build ( env)
275
+ . llvm_pgo_instrument ( & llvm_profile_dir_root)
276
+ . avoid_rustc_rebuild ( )
277
+ . run ( section)
278
+ } ) ?;
270
279
271
- let profile = stage
272
- . section ( "Gather profiles" , |_| gather_llvm_profiles ( env, & llvm_profile_dir_root) ) ?;
280
+ let profile = stage. section ( "Gather profiles" , |_| {
281
+ gather_llvm_profiles ( env, & llvm_profile_dir_root)
282
+ } ) ?;
273
283
274
- print_free_disk_space ( ) ?;
284
+ print_free_disk_space ( ) ?;
275
285
276
- // Proactively delete the instrumented artifacts, to avoid using them by accident in
277
- // follow-up stages.
278
- clear_llvm_files ( env) ?;
286
+ // Proactively delete the instrumented artifacts, to avoid using them by accident in
287
+ // follow-up stages.
288
+ clear_llvm_files ( env) ?;
279
289
280
- Ok ( profile)
281
- } ) ?;
290
+ Ok ( Some ( profile) )
291
+ } ) ?
292
+ } else {
293
+ None
294
+ } ;
282
295
283
296
let bolt_profiles = if env. use_bolt ( ) {
284
297
// Stage 3: Build BOLT instrumented LLVM
@@ -287,38 +300,48 @@ fn execute_pipeline(
287
300
// BOLT instrumentation is performed "on-the-fly" when the LLVM library is copied to the sysroot of rustc,
288
301
// therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
289
302
timer. section ( "Stage 3 (BOLT)" , |stage| {
290
- stage. section ( "Build PGO optimized LLVM" , |stage| {
291
- Bootstrap :: build ( env)
292
- . with_llvm_bolt_ldflags ( )
293
- . llvm_pgo_optimize ( & llvm_pgo_profile)
294
- . avoid_rustc_rebuild ( )
295
- . run ( stage)
296
- } ) ?;
297
-
298
- let libdir = env. build_artifacts ( ) . join ( "stage2" ) . join ( "lib" ) ;
299
- // The actual name will be something like libLLVM.so.18.1-rust-dev.
300
- let llvm_lib = io:: find_file_in_dir ( & libdir, "libLLVM.so" , "" ) ?;
301
-
302
- log:: info!( "Optimizing {llvm_lib} with BOLT" ) ;
303
-
304
- // FIXME(kobzol): try gather profiles together, at once for LLVM and rustc
305
- // Instrument the libraries and gather profiles
306
- let llvm_profile = with_bolt_instrumented ( & llvm_lib, |llvm_profile_dir| {
307
- stage. section ( "Gather profiles" , |_| {
308
- gather_bolt_profiles ( env, "LLVM" , llvm_benchmarks ( env) , llvm_profile_dir)
309
- } )
310
- } ) ?;
311
- print_free_disk_space ( ) ?;
312
-
313
- // Now optimize the library with BOLT. The `libLLVM-XXX.so` library is actually hard-linked
314
- // from several places, and this specific path (`llvm_lib`) will *not* be packaged into
315
- // the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
316
- // therefore it will actually optimize all the hard links, which means that the final
317
- // packaged `libLLVM.so` file *will* be BOLT optimized.
318
- bolt_optimize ( & llvm_lib, & llvm_profile, env)
319
- . context ( "Could not optimize LLVM with BOLT" ) ?;
320
-
321
- let rustc_lib = io:: find_file_in_dir ( & libdir, "librustc_driver" , ".so" ) ?;
303
+ let llvm_profile = if env. build_llvm ( ) {
304
+ stage. section ( "Build PGO optimized LLVM" , |stage| {
305
+ Bootstrap :: build ( env)
306
+ . with_llvm_bolt_ldflags ( )
307
+ . llvm_pgo_optimize ( llvm_pgo_profile. as_ref ( ) )
308
+ . avoid_rustc_rebuild ( )
309
+ . run ( stage)
310
+ } ) ?;
311
+
312
+ let libdir = env. build_artifacts ( ) . join ( "stage2" ) . join ( "lib" ) ;
313
+ // The actual name will be something like libLLVM.so.18.1-rust-dev.
314
+ let llvm_lib = io:: find_file_in_dir ( & libdir, "libLLVM.so" , "" ) ?;
315
+
316
+ log:: info!( "Optimizing {llvm_lib} with BOLT" ) ;
317
+
318
+ // FIXME(kobzol): try gather profiles together, at once for LLVM and rustc
319
+ // Instrument the libraries and gather profiles
320
+ let llvm_profile = with_bolt_instrumented ( & llvm_lib, |llvm_profile_dir| {
321
+ stage. section ( "Gather profiles" , |_| {
322
+ gather_bolt_profiles ( env, "LLVM" , llvm_benchmarks ( env) , llvm_profile_dir)
323
+ } )
324
+ } ) ?;
325
+ print_free_disk_space ( ) ?;
326
+
327
+ // Now optimize the library with BOLT. The `libLLVM-XXX.so` library is actually hard-linked
328
+ // from several places, and this specific path (`llvm_lib`) will *not* be packaged into
329
+ // the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
330
+ // therefore it will actually optimize all the hard links, which means that the final
331
+ // packaged `libLLVM.so` file *will* be BOLT optimized.
332
+ bolt_optimize ( & llvm_lib, & llvm_profile, env)
333
+ . context ( "Could not optimize LLVM with BOLT" ) ?;
334
+
335
+ Some ( llvm_profile)
336
+ } else {
337
+ None
338
+ } ;
339
+
340
+ let rustc_lib = io:: find_file_in_dir (
341
+ & env. build_artifacts ( ) . join ( "stage2" ) . join ( "lib" ) ,
342
+ "librustc_driver" ,
343
+ ".so" ,
344
+ ) ?;
322
345
323
346
log:: info!( "Optimizing {rustc_lib} with BOLT" ) ;
324
347
@@ -335,14 +358,14 @@ fn execute_pipeline(
335
358
. context ( "Could not optimize rustc with BOLT" ) ?;
336
359
337
360
// LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
338
- Ok ( vec ! [ llvm_profile, rustc_profile] )
361
+ Ok ( vec ! [ llvm_profile, Some ( rustc_profile) ] )
339
362
} ) ?
340
363
} else {
341
364
vec ! [ ]
342
365
} ;
343
366
344
367
let mut dist = Bootstrap :: dist ( env, & dist_args)
345
- . llvm_pgo_optimize ( & llvm_pgo_profile)
368
+ . llvm_pgo_optimize ( llvm_pgo_profile. as_ref ( ) )
346
369
. rustc_pgo_optimize ( & rustc_pgo_profile)
347
370
. avoid_rustc_rebuild ( ) ;
348
371
0 commit comments