1
1
#![ recursion_limit = "1024" ]
2
2
3
3
use anyhow:: Context ;
4
- use clap:: builder:: { PossibleValue , TypedValueParser } ;
5
- use clap:: { Arg , Parser , ValueEnum } ;
4
+ use clap:: builder:: TypedValueParser ;
5
+ use clap:: { Arg , Parser } ;
6
6
use collector:: api:: next_artifact:: NextArtifact ;
7
7
use collector:: codegen:: { codegen_diff, CodegenType } ;
8
8
use collector:: compile:: benchmark:: category:: Category ;
9
+ use collector:: compile:: benchmark:: codegen_backend:: CodegenBackend ;
9
10
use collector:: compile:: benchmark:: profile:: Profile ;
10
11
use collector:: compile:: benchmark:: scenario:: Scenario ;
11
12
use collector:: compile:: benchmark:: {
@@ -22,6 +23,7 @@ use std::fs::File;
22
23
use std:: future:: Future ;
23
24
use std:: io:: BufWriter ;
24
25
use std:: io:: Write ;
26
+ use std:: marker:: PhantomData ;
25
27
use std:: path:: { Path , PathBuf } ;
26
28
use std:: process;
27
29
use std:: process:: Command ;
@@ -82,6 +84,7 @@ struct CompileBenchmarkConfig {
82
84
benchmarks : Vec < Benchmark > ,
83
85
profiles : Vec < Profile > ,
84
86
scenarios : Vec < Scenario > ,
87
+ backends : Vec < CodegenBackend > ,
85
88
iterations : Option < usize > ,
86
89
is_self_profile : bool ,
87
90
bench_rustc : bool ,
@@ -183,6 +186,7 @@ fn profile_compile(
183
186
benchmarks : & [ Benchmark ] ,
184
187
profiles : & [ Profile ] ,
185
188
scenarios : & [ Scenario ] ,
189
+ backends : & [ CodegenBackend ] ,
186
190
errors : & mut BenchmarkErrors ,
187
191
) {
188
192
eprintln ! ( "Profiling {} with {:?}" , toolchain. id, profiler) ;
@@ -201,6 +205,7 @@ fn profile_compile(
201
205
& mut processor,
202
206
profiles,
203
207
scenarios,
208
+ backends,
204
209
toolchain,
205
210
Some ( 1 ) ,
206
211
) ) ;
@@ -230,55 +235,24 @@ fn main() {
230
235
}
231
236
}
232
237
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 > ) ;
235
242
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.
236
245
#[ derive( Clone ) ]
237
- struct ProfileArgParser ;
246
+ struct EnumArgParser < T > ( PhantomData < T > ) ;
238
247
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 ( ) )
271
251
}
272
252
}
273
253
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 > ;
282
256
283
257
fn parse_ref (
284
258
& self ,
@@ -287,26 +261,18 @@ impl TypedValueParser for ScenarioArgParser {
287
261
value : & OsStr ,
288
262
) -> Result < Self :: Value , clap:: Error > {
289
263
if value == "All" {
290
- Ok ( ScenarioArg ( Scenario :: all ( ) ) )
264
+ Ok ( MultiEnumValue ( T :: value_variants ( ) . to_vec ( ) ) )
291
265
} else {
292
- let scenarios : Result < Vec < Scenario > , _ > = value
266
+ let values : Result < Vec < T > , _ > = value
293
267
. to_str ( )
294
268
. unwrap ( )
295
269
. 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) ) )
297
271
. collect ( ) ;
298
272
299
- Ok ( ScenarioArg ( scenarios ?) )
273
+ Ok ( MultiEnumValue ( values ?) )
300
274
}
301
275
}
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
- }
310
276
}
311
277
312
278
#[ derive( Debug , clap:: Parser ) ]
@@ -358,20 +324,24 @@ struct CompileTimeOptions {
358
324
#[ arg(
359
325
long = "profiles" ,
360
326
alias = "builds" , // the old name, for backward compatibility
361
- value_parser = ProfileArgParser ,
327
+ value_parser = EnumArgParser :: < Profile > :: default ( ) ,
362
328
// Don't run rustdoc by default
363
329
default_value = "Check,Debug,Opt" ,
364
330
) ]
365
- profiles : ProfileArg ,
331
+ profiles : MultiEnumValue < Profile > ,
366
332
367
333
/// Measure the scenarios in this comma-separated list
368
334
#[ arg(
369
335
long = "scenarios" ,
370
336
alias = "runs" , // the old name, for backward compatibility
371
- value_parser = ScenarioArgParser ,
337
+ value_parser = EnumArgParser :: < Scenario > :: default ( ) ,
372
338
default_value = "All"
373
339
) ]
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 > ,
375
345
376
346
/// The path to the local rustdoc to measure
377
347
#[ arg( long) ]
@@ -785,6 +755,7 @@ fn main_result() -> anyhow::Result<i32> {
785
755
log_db ( & db) ;
786
756
let profiles = opts. profiles . 0 ;
787
757
let scenarios = opts. scenarios . 0 ;
758
+ let backends = opts. codegen_backends . 0 ;
788
759
789
760
let pool = database:: Pool :: open ( & db. db ) ;
790
761
@@ -820,6 +791,7 @@ fn main_result() -> anyhow::Result<i32> {
820
791
benchmarks,
821
792
profiles,
822
793
scenarios,
794
+ backends,
823
795
iterations : Some ( iterations) ,
824
796
is_self_profile : self_profile. self_profile ,
825
797
bench_rustc : bench_rustc. bench_rustc ,
@@ -896,8 +868,9 @@ fn main_result() -> anyhow::Result<i32> {
896
868
897
869
let compile_config = CompileBenchmarkConfig {
898
870
benchmarks,
899
- profiles : Profile :: all ( ) ,
871
+ profiles : vec ! [ Profile :: Check , Profile :: Debug , Profile :: Doc , Profile :: Opt ] ,
900
872
scenarios : Scenario :: all ( ) ,
873
+ backends : vec ! [ CodegenBackend :: Llvm ] ,
901
874
iterations : runs. map ( |v| v as usize ) ,
902
875
is_self_profile : self_profile. self_profile ,
903
876
bench_rustc : bench_rustc. bench_rustc ,
@@ -965,6 +938,7 @@ fn main_result() -> anyhow::Result<i32> {
965
938
966
939
let profiles = & opts. profiles . 0 ;
967
940
let scenarios = & opts. scenarios . 0 ;
941
+ let backends = & opts. codegen_backends . 0 ;
968
942
969
943
let mut benchmarks = get_compile_benchmarks (
970
944
& compile_benchmark_dir,
@@ -1003,6 +977,7 @@ fn main_result() -> anyhow::Result<i32> {
1003
977
& benchmarks,
1004
978
profiles,
1005
979
scenarios,
980
+ backends,
1006
981
& mut errors,
1007
982
) ;
1008
983
Ok ( id)
@@ -1299,6 +1274,7 @@ fn bench_published_artifact(
1299
1274
benchmarks : compile_benchmarks,
1300
1275
profiles,
1301
1276
scenarios,
1277
+ backends : vec ! [ CodegenBackend :: Llvm ] ,
1302
1278
iterations : Some ( 3 ) ,
1303
1279
is_self_profile : false ,
1304
1280
bench_rustc : false ,
@@ -1406,6 +1382,7 @@ fn bench_compile(
1406
1382
processor,
1407
1383
& config. profiles ,
1408
1384
& config. scenarios ,
1385
+ & config. backends ,
1409
1386
& shared. toolchain ,
1410
1387
config. iterations ,
1411
1388
) ) )
0 commit comments