@@ -8,7 +8,6 @@ use crate::compile::execute::{CargoProcess, Processor};
88use crate :: toolchain:: Toolchain ;
99use crate :: utils:: wait_for_future;
1010use anyhow:: { bail, Context } ;
11- use database:: selector:: CompileTestCase ;
1211use log:: debug;
1312use std:: collections:: { HashMap , HashSet } ;
1413use std:: fmt:: { Display , Formatter } ;
@@ -244,7 +243,6 @@ impl Benchmark {
244243 toolchain : & Toolchain ,
245244 iterations : Option < usize > ,
246245 targets : & [ Target ] ,
247- already_computed : & hashbrown:: HashSet < CompileTestCase > ,
248246 ) -> anyhow:: Result < ( ) > {
249247 if self . config . disabled {
250248 eprintln ! ( "Skipping {}: disabled" , self . name) ;
@@ -275,65 +273,19 @@ impl Benchmark {
275273 return Ok ( ( ) ) ;
276274 }
277275
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 ! [ ] ;
290278 for backend in backends {
291279 for profile in & profiles {
292280 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+ ) ) ;
319285 }
320286 }
321287 }
322288
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-
337289 // In parallel (but with a limit to the number of CPUs), prepare all
338290 // profiles. This is done in parallel vs. sequentially because:
339291 // * We don't record any measurements during this phase, so the
@@ -367,18 +319,18 @@ impl Benchmark {
367319 . get ( ) ,
368320 )
369321 . 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 {
372324 let server = server. clone ( ) ;
373325 let thread = s. spawn :: < _ , anyhow:: Result < ( ) > > ( move || {
374326 wait_for_future ( async move {
375327 let server = server. clone ( ) ;
376328 self . mk_cargo_process (
377329 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,
382334 )
383335 . jobserver ( server)
384336 . run_rustc ( false )
@@ -413,11 +365,10 @@ impl Benchmark {
413365 let mut timing_dirs: Vec < ManuallyDrop < TempDir > > = vec ! [ ] ;
414366
415367 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;
421372 eprintln ! (
422373 "Running {}: {:?} + {:?} + {:?} + {:?}" ,
423374 self . name, profile, scenarios, backend, target,
@@ -437,7 +388,7 @@ impl Benchmark {
437388 }
438389 log:: debug!( "Benchmark iteration {}/{}" , i + 1 , iterations) ;
439390 // 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 ( ) ) ?) ;
441392 let cwd = timing_dir. path ( ) ;
442393
443394 // A full non-incremental build.
@@ -507,67 +458,6 @@ impl Benchmark {
507458
508459 Ok ( ( ) )
509460 }
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- }
571461}
572462
573463/// Directory containing compile-time benchmarks.
0 commit comments