@@ -8,7 +8,6 @@ use crate::compile::execute::{CargoProcess, Processor};
8
8
use crate :: toolchain:: Toolchain ;
9
9
use crate :: utils:: wait_for_future;
10
10
use anyhow:: { bail, Context } ;
11
- use database:: selector:: CompileTestCase ;
12
11
use log:: debug;
13
12
use std:: collections:: { HashMap , HashSet } ;
14
13
use std:: fmt:: { Display , Formatter } ;
@@ -244,7 +243,6 @@ impl Benchmark {
244
243
toolchain : & Toolchain ,
245
244
iterations : Option < usize > ,
246
245
targets : & [ Target ] ,
247
- already_computed : & hashbrown:: HashSet < CompileTestCase > ,
248
246
) -> anyhow:: Result < ( ) > {
249
247
if self . config . disabled {
250
248
eprintln ! ( "Skipping {}: disabled" , self . name) ;
@@ -275,65 +273,19 @@ impl Benchmark {
275
273
return Ok ( ( ) ) ;
276
274
}
277
275
278
- struct BenchmarkDir {
279
- dir : TempDir ,
280
- scenarios : Vec < Scenario > ,
281
- profile : Profile ,
282
- backend : CodegenBackend ,
283
- target : Target ,
284
- }
285
-
286
- // Materialize the test cases that we want to benchmark
287
- // We need to handle scenarios a bit specially, because they share the target directory
288
- let mut benchmark_dirs: Vec < BenchmarkDir > = vec ! [ ] ;
289
-
276
+ eprintln ! ( "Preparing {}" , self . name) ;
277
+ let mut target_dirs: Vec < ( ( CodegenBackend , Profile , Target ) , TempDir ) > = vec ! [ ] ;
290
278
for backend in backends {
291
279
for profile in & profiles {
292
280
for target in targets {
293
- // Do we have any scenarios left to compute?
294
- let remaining_scenarios = scenarios
295
- . iter ( )
296
- . filter ( |scenario| {
297
- self . should_run_scenario (
298
- scenario,
299
- profile,
300
- backend,
301
- target,
302
- already_computed,
303
- )
304
- } )
305
- . copied ( )
306
- . collect :: < Vec < Scenario > > ( ) ;
307
- if remaining_scenarios. is_empty ( ) {
308
- continue ;
309
- }
310
-
311
- let temp_dir = self . make_temp_dir ( & self . path ) ?;
312
- benchmark_dirs. push ( BenchmarkDir {
313
- dir : temp_dir,
314
- scenarios : remaining_scenarios,
315
- profile : * profile,
316
- backend : * backend,
317
- target : * target,
318
- } ) ;
281
+ target_dirs. push ( (
282
+ ( * backend, * profile, * target) ,
283
+ self . make_temp_dir ( & self . path ) ?,
284
+ ) ) ;
319
285
}
320
286
}
321
287
}
322
288
323
- if benchmark_dirs. is_empty ( ) {
324
- eprintln ! (
325
- "Skipping {}: all test cases were previously computed" ,
326
- self . name
327
- ) ;
328
- return Ok ( ( ) ) ;
329
- }
330
-
331
- eprintln ! (
332
- "Preparing {} (test cases: {})" ,
333
- self . name,
334
- benchmark_dirs. len( )
335
- ) ;
336
-
337
289
// In parallel (but with a limit to the number of CPUs), prepare all
338
290
// profiles. This is done in parallel vs. sequentially because:
339
291
// * We don't record any measurements during this phase, so the
@@ -367,18 +319,18 @@ impl Benchmark {
367
319
. get ( ) ,
368
320
)
369
321
. context ( "jobserver::new" ) ?;
370
- let mut threads = Vec :: with_capacity ( benchmark_dirs . len ( ) ) ;
371
- for benchmark_dir in & benchmark_dirs {
322
+ let mut threads = Vec :: with_capacity ( target_dirs . len ( ) ) ;
323
+ for ( ( backend , profile , target ) , prep_dir ) in & target_dirs {
372
324
let server = server. clone ( ) ;
373
325
let thread = s. spawn :: < _ , anyhow:: Result < ( ) > > ( move || {
374
326
wait_for_future ( async move {
375
327
let server = server. clone ( ) ;
376
328
self . mk_cargo_process (
377
329
toolchain,
378
- benchmark_dir . dir . path ( ) ,
379
- benchmark_dir . profile ,
380
- benchmark_dir . backend ,
381
- benchmark_dir . target ,
330
+ prep_dir . path ( ) ,
331
+ * profile,
332
+ * backend,
333
+ * target,
382
334
)
383
335
. jobserver ( server)
384
336
. run_rustc ( false )
@@ -413,11 +365,10 @@ impl Benchmark {
413
365
let mut timing_dirs: Vec < ManuallyDrop < TempDir > > = vec ! [ ] ;
414
366
415
367
let benchmark_start = std:: time:: Instant :: now ( ) ;
416
- for benchmark_dir in & benchmark_dirs {
417
- let backend = benchmark_dir. backend ;
418
- let profile = benchmark_dir. profile ;
419
- let target = benchmark_dir. target ;
420
- let scenarios = & benchmark_dir. scenarios ;
368
+ for ( ( backend, profile, target) , prep_dir) in & target_dirs {
369
+ let backend = * backend;
370
+ let profile = * profile;
371
+ let target = * target;
421
372
eprintln ! (
422
373
"Running {}: {:?} + {:?} + {:?} + {:?}" ,
423
374
self . name, profile, scenarios, backend, target,
@@ -437,7 +388,7 @@ impl Benchmark {
437
388
}
438
389
log:: debug!( "Benchmark iteration {}/{}" , i + 1 , iterations) ;
439
390
// Don't delete the directory on error.
440
- let timing_dir = ManuallyDrop :: new ( self . make_temp_dir ( benchmark_dir . dir . path ( ) ) ?) ;
391
+ let timing_dir = ManuallyDrop :: new ( self . make_temp_dir ( prep_dir . path ( ) ) ?) ;
441
392
let cwd = timing_dir. path ( ) ;
442
393
443
394
// A full non-incremental build.
@@ -507,67 +458,6 @@ impl Benchmark {
507
458
508
459
Ok ( ( ) )
509
460
}
510
-
511
- /// Return true if the given `scenario` should be computed.
512
- fn should_run_scenario (
513
- & self ,
514
- scenario : & Scenario ,
515
- profile : & Profile ,
516
- backend : & CodegenBackend ,
517
- target : & Target ,
518
- already_computed : & hashbrown:: HashSet < CompileTestCase > ,
519
- ) -> bool {
520
- let benchmark = database:: Benchmark :: from ( self . name . 0 . as_str ( ) ) ;
521
- let profile = match profile {
522
- Profile :: Check => database:: Profile :: Check ,
523
- Profile :: Debug => database:: Profile :: Debug ,
524
- Profile :: Doc => database:: Profile :: Doc ,
525
- Profile :: DocJson => database:: Profile :: DocJson ,
526
- Profile :: Opt => database:: Profile :: Opt ,
527
- Profile :: Clippy => database:: Profile :: Clippy ,
528
- } ;
529
- let backend = match backend {
530
- CodegenBackend :: Llvm => database:: CodegenBackend :: Llvm ,
531
- CodegenBackend :: Cranelift => database:: CodegenBackend :: Cranelift ,
532
- } ;
533
- let target = match target {
534
- Target :: X86_64UnknownLinuxGnu => database:: Target :: X86_64UnknownLinuxGnu ,
535
- } ;
536
-
537
- match scenario {
538
- // For these scenarios, we can simply check if they were benchmarked or not
539
- Scenario :: Full | Scenario :: IncrFull | Scenario :: IncrUnchanged => {
540
- let test_case = CompileTestCase {
541
- benchmark,
542
- profile,
543
- backend,
544
- target,
545
- scenario : match scenario {
546
- Scenario :: Full => database:: Scenario :: Empty ,
547
- Scenario :: IncrFull => database:: Scenario :: IncrementalEmpty ,
548
- Scenario :: IncrUnchanged => database:: Scenario :: IncrementalFresh ,
549
- Scenario :: IncrPatched => unreachable ! ( ) ,
550
- } ,
551
- } ;
552
- !already_computed. contains ( & test_case)
553
- }
554
- // For incr-patched, it is a bit more complicated.
555
- // If there is at least a single uncomputed `IncrPatched`, we need to rerun
556
- // all of them, because they stack on top of one another.
557
- // Note that we don't need to explicitly include `IncrFull` if `IncrPatched`
558
- // is selected, as the benchmark code will always run `IncrFull` before `IncrPatched`.
559
- Scenario :: IncrPatched => self . patches . iter ( ) . any ( |patch| {
560
- let test_case = CompileTestCase {
561
- benchmark,
562
- profile,
563
- scenario : database:: Scenario :: IncrementalPatch ( patch. name ) ,
564
- backend,
565
- target,
566
- } ;
567
- !already_computed. contains ( & test_case)
568
- } ) ,
569
- }
570
- }
571
461
}
572
462
573
463
/// Directory containing compile-time benchmarks.
0 commit comments