Skip to content

Commit 0cfa1c4

Browse files
committed
Auto merge of #159642 - Kobzol:bootstrap-pgo-clippy, r=Mark-Simulacrum
Optimize Clippy with PGO After rustdoc and Cargo, this seemed like an obvious target for PGO. Perf results: https://perf.rust-lang.org/compare.html?start=390279b302ca98ae270f434100ae3730531d1246&end=caf67342a544d6eab7a40ebf0d02e802f62008a4&stat=instructions:u - [Quick try build that doesn't optimize Clippy](#159642 (comment)) - [Full try build that optimizes Clippy](#159642 (comment))
2 parents 095d9ef + d77e1e4 commit 0cfa1c4

8 files changed

Lines changed: 80 additions & 9 deletions

File tree

‎bootstrap.example.toml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,11 @@
10281028
# Instrument cargo, so that when executed, it will gather profiles
10291029
# to this path.
10301030
#pgo.cargo.generate = "/tmp/profiles/foo.profraw"
1031+
# Use the following profile to PGO optimize clippy.
1032+
#pgo.clippy.use = "/tmp/profiles/foo.profraw"
1033+
# Instrument clippy, so that when executed, it will gather profiles
1034+
# to this path.
1035+
#pgo.clippy.generate = "/tmp/profiles/foo.profraw"
10311036
# Use the following profile to PGO optimize LLVM.
10321037
#pgo.llvm.use = "/tmp/profiles/foo.profraw"
10331038
# Instrument LLVM, so that when executed, it will gather profiles

‎src/bootstrap/src/core/build_steps/dist.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3148,6 +3148,7 @@ impl CommandLineStep for ReproducibleArtifacts {
31483148
&builder.config.llvm_pgo.use_profile,
31493149
&builder.config.rustdoc_pgo.use_profile,
31503150
&builder.config.cargo_pgo.use_profile,
3151+
&builder.config.clippy_pgo.use_profile,
31513152
];
31523153
for profile in pgo_profiles {
31533154
if let Some(path) = profile.as_ref() {

‎src/bootstrap/src/core/build_steps/tool.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ impl Step for ToolBuild {
140140
let pgo_config = match self.path {
141141
"src/tools/rustdoc" => Some(&builder.config.rustdoc_pgo),
142142
"src/tools/cargo" => Some(&builder.config.cargo_pgo),
143+
"src/tools/clippy" => Some(&builder.config.clippy_pgo),
143144
_ => None,
144145
};
145146
if let Some(pgo_config) = pgo_config {

‎src/bootstrap/src/core/config/config.rs‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ pub(crate) struct Config {
234234
pub rust_pgo: PgoConfig,
235235
pub rustdoc_pgo: PgoConfig,
236236
pub cargo_pgo: PgoConfig,
237+
pub clippy_pgo: PgoConfig,
237238

238239
pub stdlib_semver_baseline: Option<String>,
239240

@@ -666,8 +667,13 @@ impl Config {
666667
libgccjit_libs_dir: gcc_libgccjit_libs_dir,
667668
} = toml_gcc.unwrap_or_default();
668669

669-
let Pgo { rustc: pgo_rustc, llvm: pgo_llvm, rustdoc: pgo_rustdoc, cargo: pgo_cargo } =
670-
toml_pgo.unwrap_or_default();
670+
let Pgo {
671+
rustc: pgo_rustc,
672+
rustdoc: pgo_rustdoc,
673+
cargo: pgo_cargo,
674+
clippy: pgo_clippy,
675+
llvm: pgo_llvm,
676+
} = toml_pgo.unwrap_or_default();
671677

672678
// Backcompat: flags have priority over config
673679
if flags_rust_profile_use.is_some() || flags_rust_profile_generate.is_some() {
@@ -722,6 +728,7 @@ impl Config {
722728

723729
let pgo_rustdoc = init_pgo(pgo_rustdoc, "rustdoc");
724730
let pgo_cargo = init_pgo(pgo_cargo, "cargo");
731+
let pgo_clippy = init_pgo(pgo_clippy, "clippy");
725732

726733
let bootstrap_override_lld = rust_bootstrap_override_lld.unwrap_or_default();
727734

@@ -1423,6 +1430,7 @@ NOTE: Please add `--stage 2` to your command line, or if you're sure you want to
14231430
channel,
14241431
ci_env,
14251432
clippy_info,
1433+
clippy_pgo: pgo_clippy,
14261434
cmd: flags_cmd,
14271435
codegen_tests: rust_codegen_tests.unwrap_or(true),
14281436
color: flags_color,

‎src/bootstrap/src/core/config/toml/pgo.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ define_config! {
2626
rustc: Option<PgoConfig> = "rustc",
2727
rustdoc: Option<PgoConfig> = "rustdoc",
2828
cargo: Option<PgoConfig> = "cargo",
29+
clippy: Option<PgoConfig> = "clippy",
2930
llvm: Option<PgoConfig> = "llvm",
3031
}
3132
}

‎src/tools/opt-dist/src/exec.rs‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use camino::{Utf8Path, Utf8PathBuf};
77
use crate::environment::Environment;
88
use crate::metrics::{load_metrics, record_metrics};
99
use crate::timer::TimerSection;
10-
use crate::training::{BoltProfile, LlvmPGOProfile, RustcPGOProfile, RustdocPGOProfile};
10+
use crate::training::{
11+
BoltProfile, ClippyPGOProfile, LlvmPGOProfile, RustcPGOProfile, RustdocPGOProfile,
12+
};
1113
use crate::utils::io::normalize_path;
1214

1315
#[derive(Default)]
@@ -129,6 +131,11 @@ impl Bootstrap {
129131
self
130132
}
131133

134+
pub fn with_clippy(mut self) -> Self {
135+
self.cmd = self.cmd.arg("clippy");
136+
self
137+
}
138+
132139
pub fn dist(env: &Environment, dist_args: &[String]) -> Self {
133140
let metrics_path = env.build_root().join("metrics.json");
134141
let args = dist_args.iter().map(|arg| arg.as_str()).collect::<Vec<_>>();
@@ -218,6 +225,22 @@ impl Bootstrap {
218225
self
219226
}
220227

228+
pub fn clippy_pgo_instrument(mut self, profile_dir: &Utf8Path) -> Self {
229+
self.cmd = self
230+
.cmd
231+
.arg("--set")
232+
.arg(format!(r#"pgo.clippy.generate="{}""#, normalize_path(profile_dir).as_str()));
233+
self
234+
}
235+
236+
pub fn clippy_pgo_optimize(mut self, profile: &ClippyPGOProfile) -> Self {
237+
self.cmd = self
238+
.cmd
239+
.arg("--set")
240+
.arg(format!(r#"pgo.clippy.use="{}""#, normalize_path(&profile.0).as_str()));
241+
self
242+
}
243+
221244
pub fn with_llvm_bolt_ldflags(mut self) -> Self {
222245
self.cmd = self.cmd.arg("--set").arg("llvm.ldflags=-Wl,-q");
223246
self

‎src/tools/opt-dist/src/main.rs‎

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use crate::exec::{Bootstrap, cmd};
1010
use crate::tests::run_tests;
1111
use crate::timer::Timer;
1212
use crate::training::{
13-
gather_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles, gather_rustdoc_profiles,
14-
llvm_benchmarks, rustc_benchmarks,
13+
gather_bolt_profiles, gather_clippy_profiles, gather_llvm_profiles, gather_rustc_profiles,
14+
gather_rustdoc_profiles, llvm_benchmarks, rustc_benchmarks,
1515
};
1616
use crate::utils::artifact_size::print_binary_sizes;
1717
use crate::utils::io::{copy_directory, reset_directory};
@@ -236,11 +236,13 @@ fn execute_pipeline(
236236
copy_rustc_perf(env, &rustc_perf_checkout_dir)
237237
})?;
238238

239+
let optimize_clippy = !is_fast_try_build();
240+
239241
// Stage 1: Build PGO instrumented rustc
240242
// We use a normal build of LLVM, because gathering PGO profiles for LLVM and `rustc` at the
241243
// same time can cause issues, because the host and in-tree LLVM versions can diverge.
242-
let (rustc_pgo_profile, rustdoc_pgo_profile) =
243-
timer.section("Stage 1 (Rustc + rustdoc PGO)", |stage| {
244+
let (rustc_pgo_profile, rustdoc_pgo_profile, clippy_pgo_profile) =
245+
timer.section("Stage 1 (Rustc + rustdoc + cargo + clippy PGO)", |stage| {
244246
let rustc_profile_dir_root = env.artifact_dir().join("rustc-pgo");
245247

246248
stage.section("Build PGO instrumented rustc and LLVM", |section| {
@@ -253,6 +255,9 @@ fn execute_pipeline(
253255
.rustc_pgo_instrument(&rustc_profile_dir_root)
254256
.cargo_pgo_instrument(&rustc_profile_dir_root)
255257
.rustdoc_pgo_instrument(&rustc_profile_dir_root);
258+
if optimize_clippy {
259+
builder = builder.with_clippy().clippy_pgo_instrument(&rustc_profile_dir_root);
260+
}
256261

257262
if env.supports_shared_llvm() {
258263
// This first LLVM that we build will be thrown away after this stage, and it
@@ -271,6 +276,13 @@ fn execute_pipeline(
271276
let rustdoc_profile = stage.section("Gather rustdoc profiles", |_| {
272277
gather_rustdoc_profiles(env, &rustc_profile_dir_root)
273278
})?;
279+
let clippy_profile = if optimize_clippy {
280+
stage.section("Gather clippy profiles", |_| {
281+
Ok(Some(gather_clippy_profiles(env, &rustc_profile_dir_root)?))
282+
})?
283+
} else {
284+
None
285+
};
274286
print_free_disk_space()?;
275287

276288
stage.section("Build PGO optimized rustc", |section| {
@@ -280,14 +292,17 @@ fn execute_pipeline(
280292
.rustc_pgo_optimize(&rustc_profile)
281293
.cargo_pgo_optimize(&rustc_profile)
282294
.rustdoc_pgo_optimize(&rustdoc_profile);
295+
if let Some(clippy_profile) = clippy_profile.as_ref() {
296+
cmd = cmd.with_clippy().clippy_pgo_optimize(clippy_profile);
297+
}
283298
if env.use_bolt() {
284299
cmd = cmd.with_rustc_bolt_ldflags();
285300
}
286301

287302
cmd.run(section)
288303
})?;
289304

290-
Ok((rustc_profile, rustdoc_profile))
305+
Ok((rustc_profile, rustdoc_profile, clippy_profile))
291306
})?;
292307

293308
// Stage 2: Gather LLVM PGO profiles
@@ -423,6 +438,9 @@ fn execute_pipeline(
423438
.rustc_pgo_optimize(&rustc_pgo_profile)
424439
.cargo_pgo_optimize(&rustc_pgo_profile)
425440
.rustdoc_pgo_optimize(&rustdoc_pgo_profile);
441+
if let Some(clippy_pgo_profile) = clippy_pgo_profile {
442+
dist = dist.clippy_pgo_optimize(&clippy_pgo_profile);
443+
}
426444

427445
// if LLVM is not built we'll have PGO optimized rustc
428446
dist = if env.supports_shared_llvm() || !env.build_llvm() {

‎src/tools/opt-dist/src/training.rs‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,14 @@ pub fn rustc_benchmarks(env: &Environment) -> CmdBuilder {
115115
init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["All"], RUSTC_PGO_CRATES)
116116
}
117117

118-
pub fn rustdoc_benchmarks(env: &Environment) -> CmdBuilder {
118+
fn rustdoc_benchmarks(env: &Environment) -> CmdBuilder {
119119
init_compiler_benchmarks(env, &["Doc"], &["Full"], RUSTC_PGO_CRATES)
120120
}
121121

122+
fn clippy_benchmarks(env: &Environment) -> CmdBuilder {
123+
init_compiler_benchmarks(env, &["Clippy"], &["All"], RUSTC_PGO_CRATES)
124+
}
125+
122126
pub struct LlvmPGOProfile(pub Utf8PathBuf);
123127

124128
pub fn gather_llvm_profiles(
@@ -165,6 +169,16 @@ pub fn gather_rustdoc_profiles(
165169
.map(RustdocPGOProfile)
166170
}
167171

172+
pub struct ClippyPGOProfile(pub Utf8PathBuf);
173+
174+
pub fn gather_clippy_profiles(
175+
env: &Environment,
176+
profile_root: &Utf8Path,
177+
) -> anyhow::Result<ClippyPGOProfile> {
178+
log::info!("Running benchmarks with PGO instrumented clippy");
179+
gather_pgo_profiles(env, profile_root, "clippy", clippy_benchmarks(env)).map(ClippyPGOProfile)
180+
}
181+
168182
pub fn gather_pgo_profiles(
169183
env: &Environment,
170184
profile_root: &Utf8Path,

0 commit comments

Comments
 (0)