@@ -283,7 +283,7 @@ impl Benchmark {
283283
284284 struct BenchmarkDir {
285285 dir : TempDir ,
286- scenarios : HashSet < Scenario > ,
286+ scenarios : Vec < Scenario > ,
287287 profile : Profile ,
288288 backend : CodegenBackend ,
289289 target : Target ,
@@ -299,14 +299,17 @@ impl Benchmark {
299299 // Do we have any scenarios left to compute?
300300 let remaining_scenarios = scenarios
301301 . iter ( )
302- . flat_map ( |scenario| {
303- self . create_test_cases ( scenario, profile, backend, target)
304- . into_iter ( )
305- . map ( |test_case| ( * scenario, test_case) )
302+ . filter ( |scenario| {
303+ self . should_run_scenario (
304+ scenario,
305+ profile,
306+ backend,
307+ target,
308+ already_computed,
309+ )
306310 } )
307- . filter ( |( _, test_case) | !already_computed. contains ( test_case) )
308- . map ( |( scenario, _) | scenario)
309- . collect :: < HashSet < Scenario > > ( ) ;
311+ . copied ( )
312+ . collect :: < Vec < Scenario > > ( ) ;
310313 if remaining_scenarios. is_empty ( ) {
311314 continue ;
312315 }
@@ -511,40 +514,65 @@ impl Benchmark {
511514 Ok ( ( ) )
512515 }
513516
514- fn create_test_cases (
517+ /// Return true if the given `scenario` should be computed.
518+ fn should_run_scenario (
515519 & self ,
516520 scenario : & Scenario ,
517521 profile : & Profile ,
518522 backend : & CodegenBackend ,
519523 target : & Target ,
520- ) -> Vec < CompileTestCase > {
521- self . patches
522- . iter ( )
523- . map ( |patch| CompileTestCase {
524- benchmark : database:: Benchmark :: from ( self . name . 0 . as_str ( ) ) ,
525- profile : match profile {
526- Profile :: Check => database:: Profile :: Check ,
527- Profile :: Debug => database:: Profile :: Debug ,
528- Profile :: Doc => database:: Profile :: Doc ,
529- Profile :: DocJson => database:: Profile :: DocJson ,
530- Profile :: Opt => database:: Profile :: Opt ,
531- Profile :: Clippy => database:: Profile :: Clippy ,
532- } ,
533- scenario : match scenario {
534- Scenario :: Full => database:: Scenario :: Empty ,
535- Scenario :: IncrFull => database:: Scenario :: IncrementalEmpty ,
536- Scenario :: IncrUnchanged => database:: Scenario :: IncrementalFresh ,
537- Scenario :: IncrPatched => database:: Scenario :: IncrementalPatch ( patch. name ) ,
538- } ,
539- backend : match backend {
540- CodegenBackend :: Llvm => database:: CodegenBackend :: Llvm ,
541- CodegenBackend :: Cranelift => database:: CodegenBackend :: Cranelift ,
542- } ,
543- target : match target {
544- Target :: X86_64UnknownLinuxGnu => database:: Target :: X86_64UnknownLinuxGnu ,
545- } ,
546- } )
547- . collect ( )
524+ already_computed : & hashbrown:: HashSet < CompileTestCase > ,
525+ ) -> bool {
526+ let benchmark = database:: Benchmark :: from ( self . name . 0 . as_str ( ) ) ;
527+ let profile = match profile {
528+ Profile :: Check => database:: Profile :: Check ,
529+ Profile :: Debug => database:: Profile :: Debug ,
530+ Profile :: Doc => database:: Profile :: Doc ,
531+ Profile :: DocJson => database:: Profile :: DocJson ,
532+ Profile :: Opt => database:: Profile :: Opt ,
533+ Profile :: Clippy => database:: Profile :: Clippy ,
534+ } ;
535+ let backend = match backend {
536+ CodegenBackend :: Llvm => database:: CodegenBackend :: Llvm ,
537+ CodegenBackend :: Cranelift => database:: CodegenBackend :: Cranelift ,
538+ } ;
539+ let target = match target {
540+ Target :: X86_64UnknownLinuxGnu => database:: Target :: X86_64UnknownLinuxGnu ,
541+ } ;
542+
543+ match scenario {
544+ // For these scenarios, we can simply check if they were benchmarked or not
545+ Scenario :: Full | Scenario :: IncrFull | Scenario :: IncrUnchanged => {
546+ let test_case = CompileTestCase {
547+ benchmark,
548+ profile,
549+ backend,
550+ target,
551+ scenario : match scenario {
552+ Scenario :: Full => database:: Scenario :: Empty ,
553+ Scenario :: IncrFull => database:: Scenario :: IncrementalEmpty ,
554+ Scenario :: IncrUnchanged => database:: Scenario :: IncrementalFresh ,
555+ Scenario :: IncrPatched => unreachable ! ( ) ,
556+ } ,
557+ } ;
558+ !already_computed. contains ( & test_case)
559+ }
560+ // For incr-patched, it is a bit more complicated.
561+ // If there is at least a single uncomputed `IncrPatched`, we need to rerun
562+ // all of them, because they stack on top of one another.
563+ // Note that we don't need to explicitly include `IncrFull` if `IncrPatched`
564+ // is selected, as the benchmark code will always run `IncrFull` before `IncrPatched`.
565+ Scenario :: IncrPatched => self . patches . iter ( ) . any ( |patch| {
566+ let test_case = CompileTestCase {
567+ benchmark,
568+ profile,
569+ scenario : database:: Scenario :: IncrementalPatch ( patch. name ) ,
570+ backend,
571+ target,
572+ } ;
573+ !already_computed. contains ( & test_case)
574+ } ) ,
575+ }
548576 }
549577}
550578
0 commit comments