11#![ recursion_limit = "1024" ]
22
33use anyhow:: Context ;
4- use clap:: builder:: { PossibleValue , TypedValueParser } ;
5- use clap:: { Arg , Parser , ValueEnum } ;
4+ use clap:: builder:: TypedValueParser ;
5+ use clap:: { Arg , Parser } ;
66use collector:: api:: next_artifact:: NextArtifact ;
77use collector:: codegen:: { codegen_diff, CodegenType } ;
88use collector:: compile:: benchmark:: category:: Category ;
9+ use collector:: compile:: benchmark:: codegen_backend:: CodegenBackend ;
910use collector:: compile:: benchmark:: profile:: Profile ;
1011use collector:: compile:: benchmark:: scenario:: Scenario ;
1112use collector:: compile:: benchmark:: {
@@ -22,6 +23,7 @@ use std::fs::File;
2223use std:: future:: Future ;
2324use std:: io:: BufWriter ;
2425use std:: io:: Write ;
26+ use std:: marker:: PhantomData ;
2527use std:: path:: { Path , PathBuf } ;
2628use std:: process;
2729use std:: process:: Command ;
@@ -82,6 +84,7 @@ struct CompileBenchmarkConfig {
8284 benchmarks : Vec < Benchmark > ,
8385 profiles : Vec < Profile > ,
8486 scenarios : Vec < Scenario > ,
87+ backends : Vec < CodegenBackend > ,
8588 iterations : Option < usize > ,
8689 is_self_profile : bool ,
8790 bench_rustc : bool ,
@@ -183,6 +186,7 @@ fn profile_compile(
183186 benchmarks : & [ Benchmark ] ,
184187 profiles : & [ Profile ] ,
185188 scenarios : & [ Scenario ] ,
189+ backends : & [ CodegenBackend ] ,
186190 errors : & mut BenchmarkErrors ,
187191) {
188192 eprintln ! ( "Profiling {} with {:?}" , toolchain. id, profiler) ;
@@ -201,6 +205,7 @@ fn profile_compile(
201205 & mut processor,
202206 profiles,
203207 scenarios,
208+ backends,
204209 toolchain,
205210 Some ( 1 ) ,
206211 ) ) ;
@@ -230,55 +235,24 @@ fn main() {
230235 }
231236}
232237
233- #[ derive( Debug , Clone ) ]
234- struct ProfileArg ( Vec < Profile > ) ;
238+ /// We need to have a separate wrapper over a Vec<T>, otherwise Clap would incorrectly
239+ /// assume that `EnumArgParser` parses a single item, rather than a list of items.
240+ #[ derive( Clone , Debug ) ]
241+ struct MultiEnumValue < T > ( Vec < T > ) ;
235242
243+ /// Parser for enums (like profile or scenario) which can be passed either as a comma-delimited
244+ /// string or as the "All" string, which selects all variants.
236245#[ derive( Clone ) ]
237- struct ProfileArgParser ;
246+ struct EnumArgParser < T > ( PhantomData < T > ) ;
238247
239- /// We need to use a TypedValueParser to provide possible values help.
240- /// If we just use `FromStr` + `#[arg(possible_values = [...])]`, `clap` will not allow passing
241- /// multiple values.
242- impl TypedValueParser for ProfileArgParser {
243- type Value = ProfileArg ;
244-
245- fn parse_ref (
246- & self ,
247- cmd : & clap:: Command ,
248- arg : Option < & Arg > ,
249- value : & OsStr ,
250- ) -> Result < Self :: Value , clap:: Error > {
251- if value == "All" {
252- Ok ( ProfileArg ( Profile :: all ( ) ) )
253- } else {
254- let profiles: Result < Vec < Profile > , _ > = value
255- . to_str ( )
256- . unwrap ( )
257- . split ( ',' )
258- . map ( |item| clap:: value_parser!( Profile ) . parse_ref ( cmd, arg, OsStr :: new ( item) ) )
259- . collect ( ) ;
260-
261- Ok ( ProfileArg ( profiles?) )
262- }
263- }
264-
265- fn possible_values ( & self ) -> Option < Box < dyn Iterator < Item = PossibleValue > + ' _ > > {
266- let values = Profile :: value_variants ( )
267- . iter ( )
268- . filter_map ( |item| item. to_possible_value ( ) )
269- . chain ( [ PossibleValue :: new ( "All" ) ] ) ;
270- Some ( Box :: new ( values) )
248+ impl < T > Default for EnumArgParser < T > {
249+ fn default ( ) -> Self {
250+ Self ( Default :: default ( ) )
271251 }
272252}
273253
274- #[ derive( Debug , Clone ) ]
275- struct ScenarioArg ( Vec < Scenario > ) ;
276-
277- #[ derive( Clone ) ]
278- struct ScenarioArgParser ;
279-
280- impl TypedValueParser for ScenarioArgParser {
281- type Value = ScenarioArg ;
254+ impl < T : clap:: ValueEnum + Sync + Send + ' static > TypedValueParser for EnumArgParser < T > {
255+ type Value = MultiEnumValue < T > ;
282256
283257 fn parse_ref (
284258 & self ,
@@ -287,26 +261,18 @@ impl TypedValueParser for ScenarioArgParser {
287261 value : & OsStr ,
288262 ) -> Result < Self :: Value , clap:: Error > {
289263 if value == "All" {
290- Ok ( ScenarioArg ( Scenario :: all ( ) ) )
264+ Ok ( MultiEnumValue ( T :: value_variants ( ) . to_vec ( ) ) )
291265 } else {
292- let scenarios : Result < Vec < Scenario > , _ > = value
266+ let values : Result < Vec < T > , _ > = value
293267 . to_str ( )
294268 . unwrap ( )
295269 . split ( ',' )
296- . map ( |item| clap:: value_parser!( Scenario ) . parse_ref ( cmd, arg, OsStr :: new ( item) ) )
270+ . map ( |item| clap:: value_parser!( T ) . parse_ref ( cmd, arg, OsStr :: new ( item) ) )
297271 . collect ( ) ;
298272
299- Ok ( ScenarioArg ( scenarios ?) )
273+ Ok ( MultiEnumValue ( values ?) )
300274 }
301275 }
302-
303- fn possible_values ( & self ) -> Option < Box < dyn Iterator < Item = PossibleValue > + ' _ > > {
304- let values = Scenario :: value_variants ( )
305- . iter ( )
306- . filter_map ( |item| item. to_possible_value ( ) )
307- . chain ( [ PossibleValue :: new ( "All" ) ] ) ;
308- Some ( Box :: new ( values) )
309- }
310276}
311277
312278#[ derive( Debug , clap:: Parser ) ]
@@ -358,20 +324,24 @@ struct CompileTimeOptions {
358324 #[ arg(
359325 long = "profiles" ,
360326 alias = "builds" , // the old name, for backward compatibility
361- value_parser = ProfileArgParser ,
327+ value_parser = EnumArgParser :: < Profile > :: default ( ) ,
362328 // Don't run rustdoc by default
363329 default_value = "Check,Debug,Opt" ,
364330 ) ]
365- profiles : ProfileArg ,
331+ profiles : MultiEnumValue < Profile > ,
366332
367333 /// Measure the scenarios in this comma-separated list
368334 #[ arg(
369335 long = "scenarios" ,
370336 alias = "runs" , // the old name, for backward compatibility
371- value_parser = ScenarioArgParser ,
337+ value_parser = EnumArgParser :: < Scenario > :: default ( ) ,
372338 default_value = "All"
373339 ) ]
374- scenarios : ScenarioArg ,
340+ scenarios : MultiEnumValue < Scenario > ,
341+
342+ /// Measure the codegen backends in this comma-separated list
343+ #[ arg( long = "backends" , value_parser = EnumArgParser :: <CodegenBackend >:: default ( ) , default_value = "Llvm" ) ]
344+ codegen_backends : MultiEnumValue < CodegenBackend > ,
375345
376346 /// The path to the local rustdoc to measure
377347 #[ arg( long) ]
@@ -785,6 +755,7 @@ fn main_result() -> anyhow::Result<i32> {
785755 log_db ( & db) ;
786756 let profiles = opts. profiles . 0 ;
787757 let scenarios = opts. scenarios . 0 ;
758+ let backends = opts. codegen_backends . 0 ;
788759
789760 let pool = database:: Pool :: open ( & db. db ) ;
790761
@@ -820,6 +791,7 @@ fn main_result() -> anyhow::Result<i32> {
820791 benchmarks,
821792 profiles,
822793 scenarios,
794+ backends,
823795 iterations : Some ( iterations) ,
824796 is_self_profile : self_profile. self_profile ,
825797 bench_rustc : bench_rustc. bench_rustc ,
@@ -896,8 +868,9 @@ fn main_result() -> anyhow::Result<i32> {
896868
897869 let compile_config = CompileBenchmarkConfig {
898870 benchmarks,
899- profiles : Profile :: all ( ) ,
871+ profiles : vec ! [ Profile :: Check , Profile :: Debug , Profile :: Doc , Profile :: Opt ] ,
900872 scenarios : Scenario :: all ( ) ,
873+ backends : vec ! [ CodegenBackend :: Llvm ] ,
901874 iterations : runs. map ( |v| v as usize ) ,
902875 is_self_profile : self_profile. self_profile ,
903876 bench_rustc : bench_rustc. bench_rustc ,
@@ -965,6 +938,7 @@ fn main_result() -> anyhow::Result<i32> {
965938
966939 let profiles = & opts. profiles . 0 ;
967940 let scenarios = & opts. scenarios . 0 ;
941+ let backends = & opts. codegen_backends . 0 ;
968942
969943 let mut benchmarks = get_compile_benchmarks (
970944 & compile_benchmark_dir,
@@ -1003,6 +977,7 @@ fn main_result() -> anyhow::Result<i32> {
1003977 & benchmarks,
1004978 profiles,
1005979 scenarios,
980+ backends,
1006981 & mut errors,
1007982 ) ;
1008983 Ok ( id)
@@ -1299,6 +1274,7 @@ fn bench_published_artifact(
12991274 benchmarks : compile_benchmarks,
13001275 profiles,
13011276 scenarios,
1277+ backends : vec ! [ CodegenBackend :: Llvm ] ,
13021278 iterations : Some ( 3 ) ,
13031279 is_self_profile : false ,
13041280 bench_rustc : false ,
@@ -1406,6 +1382,7 @@ fn bench_compile(
14061382 processor,
14071383 & config. profiles ,
14081384 & config. scenarios ,
1385+ & config. backends ,
14091386 & shared. toolchain ,
14101387 config. iterations ,
14111388 ) ) )
0 commit comments