@@ -408,39 +408,52 @@ struct PurgeOption {
408408 purge : Option < PurgeMode > ,
409409}
410410
411- // For each subcommand we list the mandatory arguments in the required
412- // order, followed by the options in alphabetical order.
413- #[ derive( Debug , clap:: Subcommand ) ]
411+ #[ derive( Debug , clap:: Args ) ]
414412#[ command( rename_all = "snake_case" ) ]
415- enum Commands {
416- /// Show binary (executable or library) section (and optionally symbol) size statistics of the
417- /// selected compile benchmark(s).
418- /// Optionally compares sizes between two compiler toolchains, if `--rustc2` is provided.
419- BinaryStats {
420- #[ command( flatten) ]
421- local : LocalOptions ,
413+ struct BinaryStatsCompile {
414+ #[ command( flatten) ]
415+ local : LocalOptions ,
422416
423- /// Cargo profile to use.
424- #[ arg( long, default_value = "Debug" ) ]
425- profile : Profile ,
417+ /// Cargo profile to use.
418+ #[ arg( long, default_value = "Debug" ) ]
419+ profile : Profile ,
426420
427- /// Codegen backend to use.
428- #[ arg( long = "backend" , default_value = "Llvm" ) ]
429- codegen_backend : CodegenBackend ,
421+ /// Codegen backend to use.
422+ #[ arg( long = "backend" , default_value = "Llvm" ) ]
423+ codegen_backend : CodegenBackend ,
430424
431- /// An optional second toolchain to compare to.
432- #[ arg( long) ]
433- rustc2 : Option < String > ,
425+ /// An optional second toolchain to compare to.
426+ #[ arg( long) ]
427+ rustc2 : Option < String > ,
434428
435- /// Codegen backend to use for the second toolchain.
436- #[ arg( long = "backend2" ) ]
437- codegen_backend2 : Option < CodegenBackend > ,
429+ /// Codegen backend to use for the second toolchain.
430+ #[ arg( long = "backend2" ) ]
431+ codegen_backend2 : Option < CodegenBackend > ,
432+ }
433+
434+ #[ derive( Debug , clap:: Subcommand ) ]
435+ #[ command( rename_all = "snake_case" ) ]
436+ enum BinaryStatsMode {
437+ /// Show size statistics for the selected compile benchmark(s).
438+ /// Optionally compares sizes between two compiler toolchains, if `--rustc2` is provided.
439+ Compile ( BinaryStatsCompile ) ,
440+ }
438441
442+ // For each subcommand we list the mandatory arguments in the required
443+ // order, followed by the options in alphabetical order.
444+ #[ derive( Debug , clap:: Subcommand ) ]
445+ #[ command( rename_all = "snake_case" ) ]
446+ enum Commands {
447+ /// Show binary (executable or library) section (and optionally symbol) size statistics.
448+ BinaryStats {
439449 /// Also print symbol comparison in addition to section comparison.
440450 ///
441451 /// Warning: may generate *A LOT* of data.
442- #[ arg( long, default_value_t = false ) ]
452+ #[ arg( long, default_value_t = false , global = true ) ]
443453 symbols : bool ,
454+
455+ #[ clap( subcommand) ]
456+ mode : BinaryStatsMode ,
444457 } ,
445458
446459 /// Benchmarks the performance of programs generated by a local rustc
@@ -649,89 +662,10 @@ fn main_result() -> anyhow::Result<i32> {
649662 let target_triple = format ! ( "{}-unknown-linux-gnu" , std:: env:: consts:: ARCH ) ;
650663
651664 match args. command {
652- Commands :: BinaryStats {
653- local,
654- codegen_backend,
655- profile,
656- rustc2,
657- codegen_backend2,
658- symbols,
659- } => {
660- let codegen_backend2 = codegen_backend2. unwrap_or ( codegen_backend) ;
661- let toolchain = get_local_toolchain (
662- & [ Profile :: Debug , Profile :: Opt ] ,
663- & [ codegen_backend] ,
664- & local. rustc ,
665- * ToolchainConfig :: default ( )
666- . cargo ( local. cargo . as_deref ( ) )
667- . id ( local. id . as_deref ( ) ) ,
668- "" ,
669- target_triple. clone ( ) ,
670- ) ?;
671- let toolchain2 = rustc2
672- . map ( |rustc| {
673- get_local_toolchain (
674- & [ Profile :: Debug , Profile :: Opt ] ,
675- & [ codegen_backend2] ,
676- & rustc,
677- * ToolchainConfig :: default ( )
678- . cargo ( local. cargo . as_deref ( ) )
679- . id ( local. id . as_deref ( ) ) ,
680- "" ,
681- target_triple,
682- )
683- } )
684- . transpose ( ) ?;
685- let profile = match profile {
686- Profile :: Debug => CargoProfile :: Debug ,
687- Profile :: Opt => CargoProfile :: Release ,
688- _ => return Err ( anyhow:: anyhow!( "Only Debug and Opt profiles are supported" ) ) ,
689- } ;
690- let benchmarks = get_compile_benchmarks (
691- & compile_benchmark_dir,
692- & local. include ,
693- & local. exclude ,
694- & local. exclude_suffix ,
695- ) ?;
696- for benchmark in benchmarks {
697- println ! ( "Stats for benchmark `{}`" , benchmark. name) ;
698- println ! ( "{}" , "-" . repeat( 20 ) ) ;
699- let artifacts =
700- compile_and_get_stats ( & benchmark. path , & toolchain, profile, codegen_backend) ?;
701- let archives2: HashMap < String , ArtifactWithStats > = toolchain2
702- . as_ref ( )
703- . map ( |toolchain| {
704- compile_and_get_stats ( & benchmark. path , toolchain, profile, codegen_backend2)
705- } )
706- . transpose ( ) ?
707- . unwrap_or_default ( )
708- . into_iter ( )
709- . map ( |artifact| ( artifact. target_name . clone ( ) , artifact) )
710- . collect ( ) ;
711-
712- for artifact in artifacts {
713- let archive2 = archives2. get ( & artifact. target_name ) ;
714-
715- println ! (
716- "Target `{}` (artifact `{}`)" ,
717- artifact. target_name,
718- artifact
719- . path
720- . file_name( )
721- . and_then( |s| s. to_str( ) )
722- . unwrap_or( & artifact. target_name)
723- ) ;
724-
725- let sections = artifact. stats . sections ;
726- let sections2 = archive2. as_ref ( ) . map ( |a| a. stats . sections . clone ( ) ) ;
727- print_binary_stats ( "Section" , sections, sections2) ;
728-
729- if symbols {
730- let symbols = artifact. stats . symbols ;
731- let symbols2 = archive2. as_ref ( ) . map ( |a| a. stats . symbols . clone ( ) ) ;
732- print_binary_stats ( "Symbol" , symbols, symbols2) ;
733- }
734- println ! ( ) ;
665+ Commands :: BinaryStats { mode, symbols } => {
666+ match mode {
667+ BinaryStatsMode :: Compile ( args) => {
668+ binary_stats_compile ( args, symbols, & target_triple) ?;
735669 }
736670 }
737671
@@ -1234,6 +1168,99 @@ Make sure to modify `{dir}/perf-config.json` if the category/artifact don't matc
12341168 }
12351169}
12361170
1171+ fn binary_stats_compile (
1172+ args : BinaryStatsCompile ,
1173+ symbols : bool ,
1174+ target_triple : & str ,
1175+ ) -> anyhow:: Result < ( ) > {
1176+ let BinaryStatsCompile {
1177+ local,
1178+ profile,
1179+ codegen_backend,
1180+ rustc2,
1181+ codegen_backend2,
1182+ } = args;
1183+
1184+ let codegen_backend2 = codegen_backend2. unwrap_or ( codegen_backend) ;
1185+ let toolchain = get_local_toolchain (
1186+ & [ Profile :: Debug , Profile :: Opt ] ,
1187+ & [ codegen_backend] ,
1188+ & local. rustc ,
1189+ * ToolchainConfig :: default ( )
1190+ . cargo ( local. cargo . as_deref ( ) )
1191+ . id ( local. id . as_deref ( ) ) ,
1192+ "" ,
1193+ target_triple. to_string ( ) ,
1194+ ) ?;
1195+ let toolchain2 = rustc2
1196+ . map ( |rustc| {
1197+ get_local_toolchain (
1198+ & [ Profile :: Debug , Profile :: Opt ] ,
1199+ & [ codegen_backend2] ,
1200+ & rustc,
1201+ * ToolchainConfig :: default ( )
1202+ . cargo ( local. cargo . as_deref ( ) )
1203+ . id ( local. id . as_deref ( ) ) ,
1204+ "" ,
1205+ target_triple. to_string ( ) ,
1206+ )
1207+ } )
1208+ . transpose ( ) ?;
1209+ let profile = match profile {
1210+ Profile :: Debug => CargoProfile :: Debug ,
1211+ Profile :: Opt => CargoProfile :: Release ,
1212+ _ => return Err ( anyhow:: anyhow!( "Only Debug and Opt profiles are supported" ) ) ,
1213+ } ;
1214+ let benchmarks = get_compile_benchmarks (
1215+ & compile_benchmark_dir ( ) ,
1216+ & local. include ,
1217+ & local. exclude ,
1218+ & local. exclude_suffix ,
1219+ ) ?;
1220+ for benchmark in benchmarks {
1221+ println ! ( "Stats for benchmark `{}`" , benchmark. name) ;
1222+ println ! ( "{}" , "-" . repeat( 20 ) ) ;
1223+ let artifacts =
1224+ compile_and_get_stats ( & benchmark. path , & toolchain, profile, codegen_backend) ?;
1225+ let archives2: HashMap < String , ArtifactWithStats > = toolchain2
1226+ . as_ref ( )
1227+ . map ( |toolchain| {
1228+ compile_and_get_stats ( & benchmark. path , toolchain, profile, codegen_backend2)
1229+ } )
1230+ . transpose ( ) ?
1231+ . unwrap_or_default ( )
1232+ . into_iter ( )
1233+ . map ( |artifact| ( artifact. target_name . clone ( ) , artifact) )
1234+ . collect ( ) ;
1235+
1236+ for artifact in artifacts {
1237+ let archive2 = archives2. get ( & artifact. target_name ) ;
1238+
1239+ println ! (
1240+ "Target `{}` (artifact `{}`)" ,
1241+ artifact. target_name,
1242+ artifact
1243+ . path
1244+ . file_name( )
1245+ . and_then( |s| s. to_str( ) )
1246+ . unwrap_or( & artifact. target_name)
1247+ ) ;
1248+
1249+ let sections = artifact. stats . sections ;
1250+ let sections2 = archive2. as_ref ( ) . map ( |a| a. stats . sections . clone ( ) ) ;
1251+ print_binary_stats ( "Section" , sections, sections2) ;
1252+
1253+ if symbols {
1254+ let symbols = artifact. stats . symbols ;
1255+ let symbols2 = archive2. as_ref ( ) . map ( |a| a. stats . symbols . clone ( ) ) ;
1256+ print_binary_stats ( "Symbol" , symbols, symbols2) ;
1257+ }
1258+ println ! ( ) ;
1259+ }
1260+ }
1261+ Ok ( ( ) )
1262+ }
1263+
12371264fn build_async_runtime ( ) -> Runtime {
12381265 let mut builder = tokio:: runtime:: Builder :: new_multi_thread ( ) ;
12391266 // We want to minimize noise from the runtime
0 commit comments