1
+ use std:: io:: { stdout, Write } ;
1
2
use std:: path:: PathBuf ;
2
3
use std:: process:: Command ;
3
4
4
5
use clap:: Parser ;
6
+ use config:: DB_PATH ;
5
7
6
8
use crate :: config:: { Profile , Scenario } ;
7
9
@@ -17,9 +19,6 @@ pub struct Args {
17
19
#[ clap( subcommand) ]
18
20
cmd : PerfCommand ,
19
21
20
- #[ clap( flatten) ]
21
- opts : SharedOpts ,
22
-
23
22
#[ clap( flatten) ]
24
23
ctx : BuildContext ,
25
24
}
@@ -28,22 +27,36 @@ pub struct Args {
28
27
enum PerfCommand {
29
28
/// Run `profile_local eprintln`.
30
29
/// This executes the compiler on the given benchmarks and stores its stderr output.
31
- Eprintln ,
30
+ Eprintln {
31
+ #[ clap( flatten) ]
32
+ opts : SharedOpts ,
33
+ } ,
32
34
/// Run `profile_local samply`
33
35
/// This executes the compiler on the given benchmarks and profiles it with `samply`.
34
36
/// You need to install `samply`, e.g. using `cargo install samply`.
35
- Samply ,
37
+ Samply {
38
+ #[ clap( flatten) ]
39
+ opts : SharedOpts ,
40
+ } ,
36
41
/// Run `profile_local cachegrind`.
37
42
/// 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
+ } ,
47
60
}
48
61
49
62
#[ derive( Debug , clap:: Parser ) ]
@@ -52,6 +65,10 @@ struct SharedOpts {
52
65
/// If unspecified, all benchmarks will be executed.
53
66
#[ clap( long, global = true , value_delimiter = ',' ) ]
54
67
include : Vec < String > ,
68
+
69
+ #[ clap( long, global = true , value_delimiter = ',' ) ]
70
+ exclude : Vec < String > ,
71
+
55
72
/// Select the scenarios that should be benchmarked.
56
73
#[ clap(
57
74
long,
@@ -88,34 +105,62 @@ fn main() {
88
105
fn run ( args : Args ) {
89
106
let mut cmd = Command :: new ( args. ctx . collector ) ;
90
107
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( ) ) ;
93
125
}
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 ) ;
96
133
}
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" ) ;
99
140
}
100
141
}
101
- if args. cmd . is_profiling ( ) {
102
- cmd. arg ( "--out-dir" ) . arg ( & args. ctx . results_dir ) ;
103
- }
142
+ }
104
143
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 ( "," ) ) ;
107
147
}
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 ( ) {
109
152
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 ( "," ) ) ;
111
154
}
112
- if !args . opts . scenarios . is_empty ( ) {
155
+ if !opts. scenarios . is_empty ( ) {
113
156
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 ( "," ) ) ;
115
158
}
116
- cmd . arg ( & args . ctx . compiler ) ;
159
+ }
117
160
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( ) ) ;
119
164
120
165
const MANIFEST_DIR : & str = env ! ( "CARGO_MANIFEST_DIR" ) ;
121
166
@@ -125,8 +170,4 @@ fn run(args: Args) {
125
170
// with compile-time benchmarks.
126
171
let cmd = cmd. current_dir ( rustc_perf_dir) ;
127
172
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
- }
132
173
}
0 commit comments