Skip to content

Commit d304414

Browse files
committed
Generalize binary_stats command
1 parent 5f608ec commit d304414

File tree

3 files changed

+140
-113
lines changed

3 files changed

+140
-113
lines changed

collector/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -518,19 +518,19 @@ Codegen diff is currently only implemented for runtime benchmarks.
518518
You can use the `binary_stats` command to display size statistics (section and symbol sizes) of
519519
binary artifacts (executables, libraries) of selected compile benchmarks.
520520

521-
```
522-
./target/release/collector binary_stats `<rustc>` --include <benchmark name> \
521+
```bash
522+
./target/release/collector binary_stats compile `<rustc>` --include <benchmark name> \
523523
[--profile <Debug|Opt>] \
524524
[--backend <Llvm|Cranelift>]
525525
```
526526

527527
You can also compare (diff) the size statistics between two compilers:
528-
```
529-
./target/release/collector binary_stats `<rustc>` --include <benchmark name> --rustc2 <rustc2>
528+
```bash
529+
./target/release/collector binary_stats compile `<rustc>` --include <benchmark name> --rustc2 <rustc2>
530530
```
531531
or between two codegen backends:
532-
```
533-
./target/release/collector binary_stats `<rustc>` --include <benchmark name> --rustc2 <rustc>
532+
```bash
533+
./target/release/collector binary_stats compile `<rustc>` --include <benchmark name> --rustc2 <rustc>
534534
--backend <Llvm|Cranelift> --backend2 <Llvm|Cranelift>
535535
```
536536

collector/src/bin/collector.rs

Lines changed: 133 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
12371264
fn build_async_runtime() -> Runtime {
12381265
let mut builder = tokio::runtime::Builder::new_multi_thread();
12391266
// We want to minimize noise from the runtime

site/frontend/src/pages/compare/compile/table/shortcuts/binary-size-shortcut.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function normalizeBackend(backend: string): string {
3636
</Tooltip>
3737
</div>
3838

39-
<pre><code>./target/release/collector binary_stats \
39+
<pre><code>./target/release/collector binary_stats compile \
4040
+{{ props.baseArtifact.commit }} \
4141
--rustc2 +{{ props.artifact.commit }} \
4242
--include {{ testCase.benchmark }} \

0 commit comments

Comments
 (0)