Skip to content

Commit 0da7d66

Browse files
committed
Allow profiling rustdoc
- Distinguish between rustdoc and rustc - Use `rustdoc` instead of `doc` subcommand This only profiles the last crate and also avoids special casing RUSTDOCFLAGS. - Add a fake rustdoc - Create symlink automatically if it doesn't already exist
1 parent 1fcd9e4 commit 0da7d66

File tree

3 files changed

+64
-36
lines changed

3 files changed

+64
-36
lines changed

collector/src/bin/rustc-fake.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,18 @@ use std::process::Command;
44
use std::time::{Duration, Instant};
55

66
fn main() {
7-
let mut args = env::args_os().skip(1).collect::<Vec<_>>();
7+
let mut args_os = env::args_os();
8+
let name = args_os.next().unwrap().into_string().unwrap();
9+
10+
let mut args = args_os.collect::<Vec<_>>();
811
let rustc = env::var_os("RUSTC_REAL").unwrap();
12+
let rustdoc = env::var_os("RUSTDOC_REAL").unwrap();
13+
let actually_rustdoc = name.ends_with("rustdoc-fake");
14+
let tool = if actually_rustdoc {
15+
rustdoc
16+
} else {
17+
rustc
18+
};
919

1020
if let Some(count) = env::var("RUSTC_THREAD_COUNT")
1121
.ok()
@@ -36,7 +46,7 @@ fn main() {
3646
.arg("instructions:u,cycles:u,task-clock,cpu-clock,faults")
3747
.arg("--log-fd")
3848
.arg("1")
39-
.arg(&rustc)
49+
.arg(&tool)
4050
.args(&args);
4151

4252
let prof_out_dir = std::env::current_dir().unwrap().join("self-profile-output");
@@ -91,14 +101,14 @@ fn main() {
91101
}
92102

93103
"self-profile" => {
94-
let mut cmd = Command::new(&rustc);
104+
let mut cmd = Command::new(&tool);
95105
cmd.arg("-Zself-profile=Zsp").args(&args);
96106

97107
assert!(cmd.status().expect("failed to spawn").success());
98108
}
99109

100110
"time-passes" => {
101-
let mut cmd = Command::new(&rustc);
111+
let mut cmd = Command::new(&tool);
102112
cmd.arg("-Ztime-passes").args(&args);
103113

104114
assert!(cmd.status().expect("failed to spawn").success());
@@ -113,7 +123,7 @@ fn main() {
113123
.arg("--output=perf")
114124
.arg("--freq=299")
115125
.arg("--event=cycles:u,instructions:u")
116-
.arg(&rustc)
126+
.arg(&tool)
117127
.args(&args);
118128

119129
assert!(cmd.status().expect("failed to spawn").success());
@@ -124,7 +134,7 @@ fn main() {
124134
let has_oprofile = cmd.output().is_ok();
125135
assert!(has_oprofile);
126136
// Other possibly useful args: --callgraph, --separate-thread
127-
cmd.arg("operf").arg(&rustc).args(&args);
137+
cmd.arg("operf").arg(&tool).args(&args);
128138

129139
assert!(cmd.status().expect("failed to spawn").success());
130140
}
@@ -140,7 +150,7 @@ fn main() {
140150
.arg("--cache-sim=no")
141151
.arg("--branch-sim=no")
142152
.arg("--cachegrind-out-file=cgout")
143-
.arg(&rustc)
153+
.arg(&tool)
144154
.args(&args);
145155

146156
assert!(cmd.status().expect("failed to spawn").success());
@@ -157,7 +167,7 @@ fn main() {
157167
.arg("--cache-sim=no")
158168
.arg("--branch-sim=no")
159169
.arg("--callgrind-out-file=clgout")
160-
.arg(&rustc)
170+
.arg(&tool)
161171
.args(&args);
162172

163173
assert!(cmd.status().expect("failed to spawn").success());
@@ -170,7 +180,7 @@ fn main() {
170180
cmd.arg("--tool=dhat")
171181
.arg("--num-callers=4")
172182
.arg("--dhat-out-file=dhout")
173-
.arg(&rustc)
183+
.arg(&tool)
174184
.args(&args);
175185

176186
assert!(cmd.status().expect("failed to spawn").success());
@@ -186,14 +196,14 @@ fn main() {
186196
.arg("--threshold=0.2")
187197
.arg("--massif-out-file=msout")
188198
.arg("--alloc-fn=__rdl_alloc")
189-
.arg(&rustc)
199+
.arg(&tool)
190200
.args(&args);
191201

192202
assert!(cmd.status().expect("failed to spawn").success());
193203
}
194204

195205
"eprintln" | "llvm-lines" => {
196-
let mut cmd = Command::new(&rustc);
206+
let mut cmd = Command::new(&tool);
197207
cmd.args(&args);
198208

199209
assert!(cmd.status().expect("failed to spawn").success());
@@ -204,7 +214,7 @@ fn main() {
204214
}
205215
}
206216
} else {
207-
let mut cmd = Command::new(&rustc);
217+
let mut cmd = Command::new(&tool);
208218
cmd.args(&args);
209219
exec(&mut cmd);
210220
}

collector/src/bin/rustc-perf-collector/execute.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,9 @@ impl<'a> CargoProcess<'a> {
236236
// Not all cargo invocations (e.g. `cargo clean`) need all of these
237237
// env vars set, but it doesn't hurt to have them.
238238
.env("RUSTC", &*FAKE_RUSTC)
239+
.env("RUSTDOC", &*FAKE_RUSTDOC)
239240
.env("RUSTC_REAL", &self.compiler.rustc)
241+
.env("RUSTDOC_REAL", dbg!(&self.compiler.rustdoc))
240242
.env(
241243
"CARGO_INCREMENTAL",
242244
&format!("{}", self.incremental as usize),
@@ -280,7 +282,7 @@ impl<'a> CargoProcess<'a> {
280282
}
281283

282284
if self.build_kind == BuildKind::Doc {
283-
dbg!("doc")
285+
"rustdoc"
284286
} else {
285287
profiler.subcommand()
286288
}
@@ -309,8 +311,9 @@ impl<'a> CargoProcess<'a> {
309311
// onto rustc for the final crate, which is exactly the crate for which
310312
// we want to wrap rustc.
311313
if let Some((ref mut processor, ..)) = self.processor_etc {
314+
let profiler = processor.profiler().name();
312315
cmd.arg("--wrap-rustc-with");
313-
cmd.arg(processor.profiler().name());
316+
cmd.arg(profiler);
314317
cmd.args(&self.rustc_args);
315318
}
316319

@@ -347,6 +350,16 @@ lazy_static::lazy_static! {
347350
fake_rustc.push("rustc-fake");
348351
fake_rustc
349352
};
353+
static ref FAKE_RUSTDOC: PathBuf = {
354+
let mut fake_rustdoc = env::current_exe().unwrap();
355+
fake_rustdoc.pop();
356+
fake_rustdoc.push("rustdoc-fake");
357+
// link from rustc-fake to rustdoc-fake
358+
if !fake_rustdoc.exists() {
359+
std::fs::hard_link(&*FAKE_RUSTC, &fake_rustdoc).expect("failed to make hard link");
360+
}
361+
fake_rustdoc
362+
};
350363
}
351364

352365
/// Used to indicate if we need to retry a run.

collector/src/bin/rustc-perf-collector/main.rs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use sysroot::Sysroot;
2929
#[derive(Debug, Copy, Clone)]
3030
pub struct Compiler<'a> {
3131
pub rustc: &'a Path,
32+
pub rustdoc: &'a Path,
3233
pub cargo: &'a Path,
3334
pub triple: &'a str,
3435
pub is_nightly: bool,
@@ -38,6 +39,7 @@ impl<'a> Compiler<'a> {
3839
fn from_sysroot(sysroot: &'a Sysroot) -> Compiler<'a> {
3940
Compiler {
4041
rustc: &sysroot.rustc,
42+
rustdoc: &sysroot.rustdoc,
4143
cargo: &sysroot.cargo,
4244
triple: &sysroot.triple,
4345
is_nightly: true,
@@ -86,6 +88,7 @@ pub enum KindError {
8688
const STRINGS_AND_BUILD_KINDS: &[(&str, BuildKind)] = &[
8789
("Check", BuildKind::Check),
8890
("Debug", BuildKind::Debug),
91+
("Doc", BuildKind::Doc),
8992
("Opt", BuildKind::Opt),
9093
];
9194

@@ -378,6 +381,7 @@ fn main_result() -> anyhow::Result<i32> {
378381
(@subcommand bench_local =>
379382
(about: "benchmark a local rustc")
380383
(@arg RUSTC: --rustc +required +takes_value "The path to the local rustc to benchmark")
384+
(@arg RUSTDOC: --rustdoc +required +takes_value "The path to the local rustdoc to benchmark")
381385
(@arg CARGO: --cargo +required +takes_value "The path to the local Cargo to use")
382386
(@arg BUILDS: --builds +takes_value
383387
"One or more (comma-separated) of: 'Check', 'Debug',\n\
@@ -465,12 +469,14 @@ fn main_result() -> anyhow::Result<i32> {
465469

466470
("bench_local", Some(sub_m)) => {
467471
let rustc = sub_m.value_of("RUSTC").unwrap();
472+
let rustdoc = sub_m.value_of("RUSTDOC").unwrap();
468473
let cargo = sub_m.value_of("CARGO").unwrap();
469474
let build_kinds = build_kinds_from_arg(&sub_m.value_of("BUILDS"))?;
470475
let run_kinds = run_kinds_from_arg(&sub_m.value_of("RUNS"))?;
471476
let id = sub_m.value_of("ID").unwrap();
472477

473478
let rustc_path = PathBuf::from(rustc).canonicalize()?;
479+
let rustdoc_path = PathBuf::from(rustdoc).canonicalize()?;
474480
let cargo_path = PathBuf::from(cargo).canonicalize()?;
475481
let conn = rt.block_on(pool.expect("--db passed").connection());
476482
bench_commit(
@@ -481,6 +487,7 @@ fn main_result() -> anyhow::Result<i32> {
481487
&run_kinds,
482488
Compiler {
483489
rustc: &rustc_path,
490+
rustdoc: &rustdoc_path,
484491
cargo: &cargo_path,
485492
triple: "x86_64-unknown-linux-gnu",
486493
is_nightly: true,
@@ -503,28 +510,22 @@ fn main_result() -> anyhow::Result<i32> {
503510
anyhow::bail!("failed to install toolchain for {}", id);
504511
}
505512

506-
let rustc = String::from_utf8(
507-
Command::new("rustup")
508-
.arg("which")
509-
.arg("--toolchain")
510-
.arg(&id)
511-
.arg("rustc")
512-
.output()
513-
.context("rustup which rustc")?
514-
.stdout,
515-
)
516-
.context("utf8")?;
517-
let cargo = String::from_utf8(
518-
Command::new("rustup")
519-
.arg("which")
520-
.arg("--toolchain")
521-
.arg(&id)
522-
.arg("cargo")
523-
.output()
524-
.context("rustup which cargo")?
525-
.stdout,
526-
)
527-
.context("utf8")?;
513+
let which = |tool| {
514+
String::from_utf8(
515+
Command::new("rustup")
516+
.arg("which")
517+
.arg("--toolchain")
518+
.arg(&id)
519+
.arg(tool)
520+
.output()
521+
.context(format!("rustup which {}", tool))?
522+
.stdout,
523+
)
524+
.context("utf8")
525+
};
526+
let rustc = which("rustc")?;
527+
let rustdoc = which("rustdoc")?;
528+
let cargo = which("cargo")?;
528529

529530
// Remove benchmarks that don't work with a stable compiler.
530531
benchmarks.retain(|b| b.supports_stable());
@@ -543,6 +544,7 @@ fn main_result() -> anyhow::Result<i32> {
543544
&run_kinds,
544545
Compiler {
545546
rustc: Path::new(rustc.trim()),
547+
rustdoc: Path::new(rustdoc.trim()),
546548
cargo: Path::new(cargo.trim()),
547549
is_nightly: false,
548550
triple: "x86_64-unknown-linux-gnu",
@@ -567,6 +569,7 @@ fn main_result() -> anyhow::Result<i32> {
567569

568570
("profile", Some(sub_m)) => {
569571
let rustc = sub_m.value_of("RUSTC").unwrap();
572+
let rustdoc = sub_m.value_of("RUSTDOC").unwrap();
570573
let cargo = sub_m.value_of("CARGO").unwrap();
571574
let build_kinds = build_kinds_from_arg(&sub_m.value_of("BUILDS"))?;
572575
let run_kinds = run_kinds_from_arg(&sub_m.value_of("RUNS"))?;
@@ -577,9 +580,11 @@ fn main_result() -> anyhow::Result<i32> {
577580
eprintln!("Profiling with {:?}", profiler);
578581

579582
let rustc_path = PathBuf::from(rustc).canonicalize()?;
583+
let rustdoc_path = PathBuf::from(rustdoc).canonicalize()?;
580584
let cargo_path = PathBuf::from(cargo).canonicalize()?;
581585
let compiler = Compiler {
582586
rustc: &rustc_path,
587+
rustdoc: &rustdoc_path,
583588
cargo: &cargo_path,
584589
is_nightly: true,
585590
triple: "x86_64-unknown-linux-gnu", // XXX: Technically not necessarily true

0 commit comments

Comments
 (0)