@@ -277,7 +277,7 @@ impl Benchmark {
277277
278278 struct BenchmarkDir {
279279 dir : TempDir ,
280- scenarios : HashSet < Scenario > ,
280+ scenarios : Vec < Scenario > ,
281281 profile : Profile ,
282282 backend : CodegenBackend ,
283283 target : Target ,
@@ -293,14 +293,17 @@ impl Benchmark {
293293 // Do we have any scenarios left to compute?
294294 let remaining_scenarios = scenarios
295295 . iter ( )
296- . flat_map ( |scenario| {
297- self . create_test_cases ( scenario, profile, backend, target)
298- . into_iter ( )
299- . map ( |test_case| ( * scenario, test_case) )
296+ . filter ( |scenario| {
297+ self . should_run_scenario (
298+ scenario,
299+ profile,
300+ backend,
301+ target,
302+ already_computed,
303+ )
300304 } )
301- . filter ( |( _, test_case) | !already_computed. contains ( test_case) )
302- . map ( |( scenario, _) | scenario)
303- . collect :: < HashSet < Scenario > > ( ) ;
305+ . copied ( )
306+ . collect :: < Vec < Scenario > > ( ) ;
304307 if remaining_scenarios. is_empty ( ) {
305308 continue ;
306309 }
@@ -505,40 +508,65 @@ impl Benchmark {
505508 Ok ( ( ) )
506509 }
507510
508- fn create_test_cases (
511+ /// Return true if the given `scenario` should be computed.
512+ fn should_run_scenario (
509513 & self ,
510514 scenario : & Scenario ,
511515 profile : & Profile ,
512516 backend : & CodegenBackend ,
513517 target : & Target ,
514- ) -> Vec < CompileTestCase > {
515- self . patches
516- . iter ( )
517- . map ( |patch| CompileTestCase {
518- benchmark : database:: Benchmark :: from ( self . name . 0 . as_str ( ) ) ,
519- profile : match profile {
520- Profile :: Check => database:: Profile :: Check ,
521- Profile :: Debug => database:: Profile :: Debug ,
522- Profile :: Doc => database:: Profile :: Doc ,
523- Profile :: DocJson => database:: Profile :: DocJson ,
524- Profile :: Opt => database:: Profile :: Opt ,
525- Profile :: Clippy => database:: Profile :: Clippy ,
526- } ,
527- scenario : match scenario {
528- Scenario :: Full => database:: Scenario :: Empty ,
529- Scenario :: IncrFull => database:: Scenario :: IncrementalEmpty ,
530- Scenario :: IncrUnchanged => database:: Scenario :: IncrementalFresh ,
531- Scenario :: IncrPatched => database:: Scenario :: IncrementalPatch ( patch. name ) ,
532- } ,
533- backend : match backend {
534- CodegenBackend :: Llvm => database:: CodegenBackend :: Llvm ,
535- CodegenBackend :: Cranelift => database:: CodegenBackend :: Cranelift ,
536- } ,
537- target : match target {
538- Target :: X86_64UnknownLinuxGnu => database:: Target :: X86_64UnknownLinuxGnu ,
539- } ,
540- } )
541- . collect ( )
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+ }
542570 }
543571}
544572
0 commit comments