1+ use std:: io:: { stdout, Write } ;
12use std:: path:: PathBuf ;
23use std:: process:: Command ;
34
45use clap:: Parser ;
6+ use config:: DB_PATH ;
57
68use crate :: config:: { Profile , Scenario } ;
79
@@ -17,9 +19,6 @@ pub struct Args {
1719 #[ clap( subcommand) ]
1820 cmd : PerfCommand ,
1921
20- #[ clap( flatten) ]
21- opts : SharedOpts ,
22-
2322 #[ clap( flatten) ]
2423 ctx : BuildContext ,
2524}
@@ -28,22 +27,36 @@ pub struct Args {
2827enum PerfCommand {
2928 /// Run `profile_local eprintln`.
3029 /// This executes the compiler on the given benchmarks and stores its stderr output.
31- Eprintln ,
30+ Eprintln {
31+ #[ clap( flatten) ]
32+ opts : SharedOpts ,
33+ } ,
3234 /// Run `profile_local samply`
3335 /// This executes the compiler on the given benchmarks and profiles it with `samply`.
3436 /// You need to install `samply`, e.g. using `cargo install samply`.
35- Samply ,
37+ Samply {
38+ #[ clap( flatten) ]
39+ opts : SharedOpts ,
40+ } ,
3641 /// Run `profile_local cachegrind`.
3742 /// This executes the compiler on the given benchmarks under `Cachegrind`.
38- Cachegrind ,
39- }
40-
41- impl PerfCommand {
42- fn is_profiling ( & self ) -> bool {
43- match self {
44- PerfCommand :: Eprintln | PerfCommand :: Samply | PerfCommand :: Cachegrind => true ,
45- }
46- }
43+ Cachegrind {
44+ #[ clap( flatten) ]
45+ opts : SharedOpts ,
46+ } ,
47+ Benchmark {
48+ id : String ,
49+
50+ #[ clap( flatten) ]
51+ opts : SharedOpts ,
52+ } ,
53+ Compare {
54+ /// The name of the base artifact to be compared.
55+ base : String ,
56+
57+ /// The name of the modified artifact to be compared.
58+ modified : String ,
59+ } ,
4760}
4861
4962#[ derive( Debug , clap:: Parser ) ]
@@ -52,6 +65,10 @@ struct SharedOpts {
5265 /// If unspecified, all benchmarks will be executed.
5366 #[ clap( long, global = true , value_delimiter = ',' ) ]
5467 include : Vec < String > ,
68+
69+ #[ clap( long, global = true , value_delimiter = ',' ) ]
70+ exclude : Vec < String > ,
71+
5572 /// Select the scenarios that should be benchmarked.
5673 #[ clap(
5774 long,
@@ -88,34 +105,62 @@ fn main() {
88105fn run ( args : Args ) {
89106 let mut cmd = Command :: new ( args. ctx . collector ) ;
90107 match & args. cmd {
91- PerfCommand :: Eprintln => {
92- cmd. arg ( "profile_local" ) . arg ( "eprintln" ) ;
108+ PerfCommand :: Eprintln { opts }
109+ | PerfCommand :: Samply { opts }
110+ | PerfCommand :: Cachegrind { opts } => {
111+ cmd. arg ( "profile_local" ) ;
112+ cmd. arg ( match & args. cmd {
113+ PerfCommand :: Eprintln { .. } => "eprintln" ,
114+ PerfCommand :: Samply { .. } => "samply" ,
115+ PerfCommand :: Cachegrind { .. } => "cachegrind" ,
116+ _ => unreachable ! ( ) ,
117+ } ) ;
118+
119+ cmd. arg ( "--out-dir" ) . arg ( & args. ctx . results_dir ) ;
120+
121+ apply_shared_opts ( & mut cmd, opts) ;
122+ execute_benchmark ( & mut cmd, & args. ctx . compiler ) ;
123+
124+ println ! ( "You can find the results at `{}`" , args. ctx. results_dir. display( ) ) ;
93125 }
94- PerfCommand :: Samply => {
95- cmd. arg ( "profile_local" ) . arg ( "samply" ) ;
126+ PerfCommand :: Benchmark { id, opts } => {
127+ cmd. arg ( "bench_local" ) ;
128+ cmd. arg ( "--db" ) . arg ( DB_PATH ) ;
129+ cmd. arg ( "--id" ) . arg ( id) ;
130+
131+ apply_shared_opts ( & mut cmd, opts) ;
132+ execute_benchmark ( & mut cmd, & args. ctx . compiler ) ;
96133 }
97- PerfCommand :: Cachegrind => {
98- cmd. arg ( "profile_local" ) . arg ( "cachegrind" ) ;
134+ PerfCommand :: Compare { base, modified } => {
135+ cmd. arg ( "bench_cmp" ) ;
136+ cmd. arg ( "--db" ) . arg ( DB_PATH ) ;
137+ cmd. arg ( base) . arg ( modified) ;
138+
139+ cmd. status ( ) . expect ( "error while running rustc-perf bench_cmp" ) ;
99140 }
100141 }
101- if args. cmd . is_profiling ( ) {
102- cmd. arg ( "--out-dir" ) . arg ( & args. ctx . results_dir ) ;
103- }
142+ }
104143
105- if !args. opts . include . is_empty ( ) {
106- cmd. arg ( "--include" ) . arg ( args. opts . include . join ( "," ) ) ;
144+ fn apply_shared_opts ( cmd : & mut Command , opts : & SharedOpts ) {
145+ if !opts. include . is_empty ( ) {
146+ cmd. arg ( "--include" ) . arg ( opts. include . join ( "," ) ) ;
107147 }
108- if !args. opts . profiles . is_empty ( ) {
148+ if !opts. exclude . is_empty ( ) {
149+ cmd. arg ( "--exclude" ) . arg ( opts. exclude . join ( "," ) ) ;
150+ }
151+ if !opts. profiles . is_empty ( ) {
109152 cmd. arg ( "--profiles" )
110- . arg ( args . opts . profiles . iter ( ) . map ( |p| p. to_string ( ) ) . collect :: < Vec < _ > > ( ) . join ( "," ) ) ;
153+ . arg ( opts. profiles . iter ( ) . map ( |p| p. to_string ( ) ) . collect :: < Vec < _ > > ( ) . join ( "," ) ) ;
111154 }
112- if !args . opts . scenarios . is_empty ( ) {
155+ if !opts. scenarios . is_empty ( ) {
113156 cmd. arg ( "--scenarios" )
114- . arg ( args . opts . scenarios . iter ( ) . map ( |p| p. to_string ( ) ) . collect :: < Vec < _ > > ( ) . join ( "," ) ) ;
157+ . arg ( opts. scenarios . iter ( ) . map ( |p| p. to_string ( ) ) . collect :: < Vec < _ > > ( ) . join ( "," ) ) ;
115158 }
116- cmd . arg ( & args . ctx . compiler ) ;
159+ }
117160
118- println ! ( "Running `rustc-perf` using `{}`" , args. ctx. compiler. display( ) ) ;
161+ fn execute_benchmark ( cmd : & mut Command , compiler : & PathBuf ) {
162+ cmd. arg ( compiler) ;
163+ println ! ( "Running `rustc-perf` using `{}`" , compiler. display( ) ) ;
119164
120165 const MANIFEST_DIR : & str = env ! ( "CARGO_MANIFEST_DIR" ) ;
121166
@@ -125,8 +170,4 @@ fn run(args: Args) {
125170 // with compile-time benchmarks.
126171 let cmd = cmd. current_dir ( rustc_perf_dir) ;
127172 cmd. status ( ) . expect ( "error while running rustc-perf collector" ) ;
128-
129- if args. cmd . is_profiling ( ) {
130- println ! ( "You can find the results at `{}`" , args. ctx. results_dir. display( ) ) ;
131- }
132173}
0 commit comments