Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 28cb03d

Browse files
author
Matthew Hammer
committed
profiling with -Z profile-queries recognizes -Z time-passes
1 parent d7ec3e1 commit 28cb03d

File tree

3 files changed

+139
-26
lines changed

3 files changed

+139
-26
lines changed

src/librustc/util/common.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,12 @@ pub struct ProfQDumpParams {
5151
/// FIXME(matthewhammer): Determine whether we should include cycle detection here or not.
5252
#[derive(Clone,Debug)]
5353
pub enum ProfileQueriesMsg {
54+
/// begin a timed pass
55+
TimeBegin(String),
56+
// end a timed pass
57+
TimeEnd,
5458
/// begin a new query
55-
QueryBegin(Span,QueryMsg),
59+
QueryBegin(Span, QueryMsg),
5660
/// query is satisfied by using an already-known value for the given key
5761
CacheHit,
5862
/// query requires running a provider; providers may nest, permitting queries to nest.
@@ -110,9 +114,15 @@ pub fn time<T, F>(do_it: bool, what: &str, f: F) -> T where
110114
r
111115
});
112116

117+
if cfg!(debug_assertions) {
118+
profq_msg(ProfileQueriesMsg::TimeBegin(what.to_string()))
119+
};
113120
let start = Instant::now();
114121
let rv = f();
115122
let dur = start.elapsed();
123+
if cfg!(debug_assertions) {
124+
profq_msg(ProfileQueriesMsg::TimeEnd)
125+
};
116126

117127
print_time_passes_entry_internal(what, dur);
118128

src/librustc_driver/profile/mod.rs

Lines changed: 89 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use std::time::{Instant};
1112
use rustc::util::common::{ProfQDumpParams, ProfileQueriesMsg, profq_msg, profq_set_chan};
1213
use std::sync::mpsc::{Receiver};
1314
use std::io::{Write};
@@ -41,14 +42,30 @@ pub fn dump(path:String) {
4142
let _ = rx.recv().unwrap();
4243
}
4344

45+
// State for parsing recursive trace structure in separate thread, via messages
46+
#[derive(Clone, Eq, PartialEq)]
47+
enum ParseState {
48+
// No (local) parse state; may be parsing a tree, focused on a
49+
// sub-tree that could be anything.
50+
Clear,
51+
// Have Query information from the last message
52+
HaveQuery(trace::Query, Instant),
53+
// Have "time-begin" information from the last message (doit flag, and message)
54+
HaveTimeBegin(String, Instant),
55+
}
56+
struct StackFrame {
57+
pub parse_st: ParseState,
58+
pub traces: Vec<trace::Rec>,
59+
}
60+
4461
// profiling thread; retains state (in local variables) and dump traces, upon request.
4562
fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
4663
use self::trace::*;
4764
use std::fs::File;
4865
use std::time::{Instant};
4966

5067
let mut profq_msgs : Vec<ProfileQueriesMsg> = vec![];
51-
let mut frame : StackFrame = StackFrame{ parse_st:ParseState::NoQuery, traces:vec![] };
68+
let mut frame : StackFrame = StackFrame{ parse_st:ParseState::Clear, traces:vec![] };
5269
let mut stack : Vec<StackFrame> = vec![];
5370
loop {
5471
let msg = r.recv();
@@ -64,7 +81,7 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
6481
ProfileQueriesMsg::Halt => return,
6582
ProfileQueriesMsg::Dump(params) => {
6683
assert!(stack.len() == 0);
67-
assert!(frame.parse_st == trace::ParseState::NoQuery);
84+
assert!(frame.parse_st == ParseState::Clear);
6885
{
6986
// write log of all messages
7087
if params.dump_profq_msg_log {
@@ -94,6 +111,10 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
94111
trace::write_traces(&mut html_file, &mut counts_file, &frame.traces);
95112
write!(html_file, "</body>\n</html>\n").unwrap();
96113

114+
let ack_path = format!("{}.ack", params.path);
115+
let ack_file = File::create(&ack_path).unwrap();
116+
drop(ack_file);
117+
97118
// Tell main thread that we are done, e.g., so it can exit
98119
params.ack.send(()).unwrap();
99120
}
@@ -108,35 +129,33 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
108129
(_,ProfileQueriesMsg::Halt) => unreachable!(),
109130
(_,ProfileQueriesMsg::Dump(_)) => unreachable!(),
110131

111-
// Parse State: NoQuery
112-
(ParseState::NoQuery,
132+
// Parse State: Clear
133+
(ParseState::Clear,
113134
ProfileQueriesMsg::QueryBegin(span,querymsg)) => {
114135
let start = Instant::now();
115136
frame.parse_st = ParseState::HaveQuery
116137
(Query{span:span, msg:querymsg}, start)
117138
},
118-
(ParseState::NoQuery,
139+
(ParseState::Clear,
119140
ProfileQueriesMsg::CacheHit) => {
120141
panic!("parse error: unexpected CacheHit; expected QueryBegin")
121142
},
122-
(ParseState::NoQuery,
143+
(ParseState::Clear,
123144
ProfileQueriesMsg::ProviderBegin) => {
124145
panic!("parse error: expected QueryBegin before beginning a provider")
125146
},
126-
(ParseState::NoQuery,
147+
(ParseState::Clear,
127148
ProfileQueriesMsg::ProviderEnd) => {
128149
let provider_extent = frame.traces;
129150
match stack.pop() {
130151
None =>
131152
panic!("parse error: expected a stack frame; found an empty stack"),
132153
Some(old_frame) => {
133154
match old_frame.parse_st {
134-
ParseState::NoQuery =>
135-
panic!("parse error: expected a stack frame for a query"),
136-
ParseState::HaveQuery(q,start) => {
155+
ParseState::HaveQuery(q, start) => {
137156
let duration = start.elapsed();
138157
frame = StackFrame{
139-
parse_st:ParseState::NoQuery,
158+
parse_st:ParseState::Clear,
140159
traces:old_frame.traces
141160
};
142161
let trace = Rec {
@@ -146,11 +165,66 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
146165
duration: duration,
147166
};
148167
frame.traces.push( trace );
149-
}
168+
},
169+
_ => panic!("internal parse error: malformed parse stack")
150170
}
151171
}
152172
}
153-
}
173+
},
174+
175+
176+
(ParseState::Clear,
177+
ProfileQueriesMsg::TimeBegin(msg)) => {
178+
let start = Instant::now();
179+
frame.parse_st = ParseState::HaveTimeBegin(msg, start);
180+
stack.push(frame);
181+
frame = StackFrame{parse_st:ParseState::Clear, traces:vec![]};
182+
},
183+
(_, ProfileQueriesMsg::TimeBegin(_)) =>
184+
panic!("parse error; did not expect time begin here"),
185+
186+
(ParseState::Clear,
187+
ProfileQueriesMsg::TimeEnd) => {
188+
let provider_extent = frame.traces;
189+
match stack.pop() {
190+
None =>
191+
panic!("parse error: expected a stack frame; found an empty stack"),
192+
Some(old_frame) => {
193+
match old_frame.parse_st {
194+
ParseState::HaveTimeBegin(msg, start) => {
195+
let duration = start.elapsed();
196+
frame = StackFrame{
197+
parse_st:ParseState::Clear,
198+
traces:old_frame.traces
199+
};
200+
let trace = Rec {
201+
effect: Effect::TimeBegin(msg),
202+
extent: Box::new(provider_extent),
203+
start: start,
204+
duration: duration,
205+
};
206+
frame.traces.push( trace );
207+
},
208+
_ => panic!("internal parse error: malformed parse stack")
209+
}
210+
}
211+
}
212+
},
213+
(_, ProfileQueriesMsg::TimeEnd) => { panic!("parse error") }
214+
215+
216+
// Parse State: HaveTimeBegin -- for timing old
217+
// passes in driver (outside of query model, but
218+
// still in use)
219+
(ParseState::HaveTimeBegin(_, _),
220+
ProfileQueriesMsg::ProviderBegin) => {
221+
},
222+
(ParseState::HaveTimeBegin(_, _),
223+
ProfileQueriesMsg::CacheHit) => { unreachable!() },
224+
(ParseState::HaveTimeBegin(_, _),
225+
ProfileQueriesMsg::QueryBegin(_, _)) => { unreachable!() },
226+
(ParseState::HaveTimeBegin(_, _),
227+
ProfileQueriesMsg::ProviderEnd) => { unreachable!() },
154228

155229
// Parse State: HaveQuery
156230
(ParseState::HaveQuery(q,start),
@@ -163,12 +237,12 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
163237
duration: duration,
164238
};
165239
frame.traces.push( trace );
166-
frame.parse_st = ParseState::NoQuery;
240+
frame.parse_st = ParseState::Clear;
167241
},
168242
(ParseState::HaveQuery(_,_),
169243
ProfileQueriesMsg::ProviderBegin) => {
170244
stack.push(frame);
171-
frame = StackFrame{parse_st:ParseState::NoQuery, traces:vec![]};
245+
frame = StackFrame{parse_st:ParseState::Clear, traces:vec![]};
172246
},
173247
(ParseState::HaveQuery(q,_),
174248
ProfileQueriesMsg::ProviderEnd) => {

src/librustc_driver/profile/trace.rs

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub struct Query {
2222
}
2323
pub enum Effect {
2424
QueryBegin(Query, CacheCase),
25+
TimeBegin(String),
2526
}
2627
pub enum CacheCase {
2728
Hit, Miss
@@ -33,16 +34,6 @@ pub struct Rec {
3334
pub duration: Duration,
3435
pub extent: Box<Vec<Rec>>,
3536
}
36-
/// State for parsing recursive trace structure
37-
#[derive(Clone, Eq, PartialEq)]
38-
pub enum ParseState {
39-
NoQuery,
40-
HaveQuery(Query, Instant),
41-
}
42-
pub struct StackFrame {
43-
pub parse_st: ParseState,
44-
pub traces: Vec<Rec>,
45-
}
4637
pub struct QueryMetric {
4738
pub count: usize,
4839
pub duration: Duration,
@@ -58,6 +49,10 @@ pub fn cons_of_query_msg(q: &trace::Query) -> String {
5849
// First return value is text; second return value is a CSS class
5950
pub fn html_of_effect(eff: &Effect) -> (String, String) {
6051
match *eff {
52+
Effect::TimeBegin(ref msg) => {
53+
(msg.clone(),
54+
format!("time-begin"))
55+
},
6156
Effect::QueryBegin(ref qmsg, ref cc) => {
6257
let cons = cons_of_query_msg(qmsg);
6358
(cons.clone(),
@@ -142,6 +137,9 @@ fn write_traces_rec(file: &mut File, traces: &Vec<Rec>, total: Duration, depth:
142137
fn compute_counts_rec(counts: &mut HashMap<String,QueryMetric>, traces: &Vec<Rec>) {
143138
for t in traces.iter() {
144139
match t.effect {
140+
Effect::TimeBegin(ref _msg) => {
141+
// dont count time-begin effects
142+
}
145143
Effect::QueryBegin(ref qmsg, ref _cc) => {
146144
let qcons = cons_of_query_msg(qmsg);
147145
let qm = match counts.get(&qcons) {
@@ -212,6 +210,12 @@ body {
212210
.extent-0 {
213211
padding: 2px;
214212
}
213+
.time-begin {
214+
border-width: 4px;
215+
font-size: 12px;
216+
color: white;
217+
border-color: #afa;
218+
}
215219
.important {
216220
border-width: 3px;
217221
font-size: 12px;
@@ -234,5 +238,30 @@ body {
234238
.dur {
235239
display: none
236240
}
241+
.frac-50 {
242+
padding: 4px;
243+
border-width: 10px;
244+
font-size: 16px;
245+
}
246+
.frac-40 {
247+
padding: 4px;
248+
border-width: 8px;
249+
font-size: 16px;
250+
}
251+
.frac-30 {
252+
padding: 3px;
253+
border-width: 6px;
254+
font-size: 16px;
255+
}
256+
.frac-20 {
257+
padding: 3px;
258+
border-width: 6px;
259+
font-size: 16px;
260+
}
261+
.frac-10 {
262+
padding: 3px;
263+
border-width: 6px;
264+
font-size: 16px;
265+
}
237266
").unwrap();
238267
}

0 commit comments

Comments
 (0)