Skip to content

Commit 3fbeb90

Browse files
authored
Merge pull request #1742 from Kobzol/codegen-backend
Add basic support for selecting a codegen backend for compile benchmarks
2 parents a713230 + 83140fb commit 3fbeb90

17 files changed

+295
-175
lines changed

collector/src/bin/collector.rs

Lines changed: 39 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#![recursion_limit = "1024"]
22

33
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};
66
use collector::api::next_artifact::NextArtifact;
77
use collector::codegen::{codegen_diff, CodegenType};
88
use collector::compile::benchmark::category::Category;
9+
use collector::compile::benchmark::codegen_backend::CodegenBackend;
910
use collector::compile::benchmark::profile::Profile;
1011
use collector::compile::benchmark::scenario::Scenario;
1112
use collector::compile::benchmark::{
@@ -22,6 +23,7 @@ use std::fs::File;
2223
use std::future::Future;
2324
use std::io::BufWriter;
2425
use std::io::Write;
26+
use std::marker::PhantomData;
2527
use std::path::{Path, PathBuf};
2628
use std::process;
2729
use 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
)))
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, clap::ValueEnum, serde::Deserialize)]
2+
#[value(rename_all = "PascalCase")]
3+
pub enum CodegenBackend {
4+
Llvm,
5+
}
6+
7+
impl CodegenBackend {
8+
pub fn all() -> Vec<CodegenBackend> {
9+
vec![CodegenBackend::Llvm]
10+
}
11+
}

0 commit comments

Comments
 (0)