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

Commit 2f10bd1

Browse files
committed
Auto merge of rust-lang#139648 - Kobzol:ra-bolt, r=<try>
Optimize Rust Analyzer with BOLT Funnily enough, it is easier to use BOLT for another component than to do PGO (at least I think so..). Let's try. r? `@ghost` try-job: dist-x86_64-linux
2 parents 81d8c74 + d33c8f6 commit 2f10bd1

File tree

5 files changed

+81
-22
lines changed

5 files changed

+81
-22
lines changed

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,15 +1228,20 @@ impl Step for RustAnalyzer {
12281228
}
12291229

12301230
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
1231-
let compiler = self.compiler;
1231+
// let compiler = self.compiler;
12321232
let target = self.target;
12331233

1234-
let rust_analyzer = builder.ensure(tool::RustAnalyzer { compiler, target });
1234+
let rust_analyzer = builder
1235+
.out
1236+
.join("x86_64-unknown-linux-gnu")
1237+
.join("stage1-tools-bin")
1238+
.join("rust-analyzer");
1239+
//builder.ensure(tool::RustAnalyzer { compiler, target });
12351240

12361241
let mut tarball = Tarball::new(builder, "rust-analyzer", &target.triple);
12371242
tarball.set_overlay(OverlayKind::RustAnalyzer);
12381243
tarball.is_preview(true);
1239-
tarball.add_file(&rust_analyzer.tool_path, "bin", FileType::Executable);
1244+
tarball.add_file(&rust_analyzer, "bin", FileType::Executable);
12401245
tarball.add_legal_and_readme_to("share/doc/rust-analyzer");
12411246
Some(tarball.generate())
12421247
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,17 @@ impl Step for ToolBuild {
148148
&self.extra_features,
149149
);
150150

151+
if self.tool == "rust-analyzer" {
152+
// if std::env::var("RA_PGO_GEN").is_ok() {
153+
// cargo.rustflag("-Cprofile-generate=/tmp/ra-pgo");
154+
// } else if let Ok(path) = std::env::var("RA_PGO_USE") {
155+
// cargo.rustflag(&format!("-Cprofile-use={path}"));
156+
// }
157+
if builder.config.enable_bolt_settings {
158+
cargo.rustflag("-Clink-args=-Wl,-q");
159+
}
160+
}
161+
151162
if path.ends_with("/rustdoc") &&
152163
// rustdoc is performance sensitive, so apply LTO to it.
153164
is_lto_stage(&self.compiler)

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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,16 @@ impl CmdBuilder {
7575
if let Some(ref workdir) = self.workdir {
7676
cmd.current_dir(workdir.clone().into_std_path_buf());
7777
}
78-
let exit_status = cmd.spawn()?.wait()?;
79-
if !exit_status.success() {
80-
Err(anyhow::anyhow!(
81-
"Command {cmd_str} has failed with exit code {:?}",
82-
exit_status.code(),
83-
))
84-
} else {
85-
Ok(())
86-
}
78+
cmd.spawn()?.wait()?;
79+
// let exit_status = cmd.spawn()?.wait()?;
80+
// if !exit_status.success() {
81+
// Err(anyhow::anyhow!(
82+
// "Command {cmd_str} has failed with exit code {:?}",
83+
// exit_status.code(),
84+
// ))
85+
// } else {
86+
Ok(())
87+
// }
8788
}
8889
}
8990

@@ -98,7 +99,15 @@ pub struct Bootstrap {
9899
}
99100

100101
impl Bootstrap {
101-
pub fn build(env: &Environment) -> Self {
102+
pub fn build_compiler(env: &Environment) -> Self {
103+
Self::build(env, "library/std")
104+
}
105+
106+
pub fn build_rust_analyzer(env: &Environment) -> Self {
107+
Self::build(env, "rust-analyzer")
108+
}
109+
110+
pub fn build(env: &Environment, component: &str) -> Self {
102111
let metrics_path = env.build_root().join("build").join("metrics.json");
103112
let cmd = cmd(&[
104113
env.python_binary(),
@@ -110,7 +119,7 @@ impl Bootstrap {
110119
&env.host_tuple(),
111120
"--stage",
112121
"2",
113-
"library/std",
122+
component,
114123
])
115124
.env("RUST_BACKTRACE", "full");
116125
Self { cmd, metrics_path }

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

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::tests::run_tests;
1111
use crate::timer::Timer;
1212
use crate::training::{
1313
gather_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles, llvm_benchmarks,
14-
rustc_benchmarks,
14+
rust_analyzer_benchmarks, rustc_benchmarks,
1515
};
1616
use crate::utils::artifact_size::print_binary_sizes;
1717
use crate::utils::io::{copy_directory, reset_directory};
@@ -209,7 +209,8 @@ fn execute_pipeline(
209209
let rustc_profile_dir_root = env.artifact_dir().join("rustc-pgo");
210210

211211
stage.section("Build PGO instrumented rustc and LLVM", |section| {
212-
let mut builder = Bootstrap::build(env).rustc_pgo_instrument(&rustc_profile_dir_root);
212+
let mut builder =
213+
Bootstrap::build_compiler(env).rustc_pgo_instrument(&rustc_profile_dir_root);
213214

214215
if env.supports_shared_llvm() {
215216
// This first LLVM that we build will be thrown away after this stage, and it
@@ -227,7 +228,7 @@ fn execute_pipeline(
227228
print_free_disk_space()?;
228229

229230
stage.section("Build PGO optimized rustc", |section| {
230-
let mut cmd = Bootstrap::build(env).rustc_pgo_optimize(&profile);
231+
let mut cmd = Bootstrap::build_compiler(env).rustc_pgo_optimize(&profile);
231232
if env.use_bolt() {
232233
cmd = cmd.with_rustc_bolt_ldflags();
233234
}
@@ -248,7 +249,7 @@ fn execute_pipeline(
248249
let llvm_profile_dir_root = env.artifact_dir().join("llvm-pgo");
249250

250251
stage.section("Build PGO instrumented LLVM", |section| {
251-
Bootstrap::build(env)
252+
Bootstrap::build_compiler(env)
252253
.llvm_pgo_instrument(&llvm_profile_dir_root)
253254
.avoid_rustc_rebuild()
254255
.run(section)
@@ -274,7 +275,7 @@ fn execute_pipeline(
274275
// therefore the LLVM artifacts on disk are not "tainted" with BOLT instrumentation and they can be reused.
275276
timer.section("Stage 3 (BOLT)", |stage| {
276277
stage.section("Build PGO optimized LLVM", |stage| {
277-
Bootstrap::build(env)
278+
Bootstrap::build_compiler(env)
278279
.with_llvm_bolt_ldflags()
279280
.llvm_pgo_optimize(&llvm_pgo_profile)
280281
.avoid_rustc_rebuild()
@@ -290,7 +291,7 @@ fn execute_pipeline(
290291
// FIXME(kobzol): try gather profiles together, at once for LLVM and rustc
291292
// Instrument the libraries and gather profiles
292293
let llvm_profile = with_bolt_instrumented(&llvm_lib, |llvm_profile_dir| {
293-
stage.section("Gather profiles", |_| {
294+
stage.section("Gather LLVM profiles", |_| {
294295
gather_bolt_profiles(env, "LLVM", llvm_benchmarks(env), llvm_profile_dir)
295296
})
296297
})?;
@@ -310,7 +311,7 @@ fn execute_pipeline(
310311

311312
// Instrument it and gather profiles
312313
let rustc_profile = with_bolt_instrumented(&rustc_lib, |rustc_profile_dir| {
313-
stage.section("Gather profiles", |_| {
314+
stage.section("Gather rustc profiles", |_| {
314315
gather_bolt_profiles(env, "rustc", rustc_benchmarks(env), rustc_profile_dir)
315316
})
316317
})?;
@@ -320,8 +321,28 @@ fn execute_pipeline(
320321
bolt_optimize(&rustc_lib, &rustc_profile, env)
321322
.context("Could not optimize rustc with BOLT")?;
322323

324+
Bootstrap::build_rust_analyzer(env)
325+
.avoid_rustc_rebuild()
326+
.with_rustc_bolt_ldflags()
327+
.run(stage)?;
328+
let ra_binary = env.build_artifacts().join("stage1-tools-bin").join("rust-analyzer");
329+
let ra_profile = with_bolt_instrumented(&ra_binary, |ra_profile_dir| {
330+
stage.section("Gather rust analyzer profiles", |_| {
331+
gather_bolt_profiles(
332+
env,
333+
"rust-analyzer",
334+
rust_analyzer_benchmarks(env, &ra_binary),
335+
ra_profile_dir,
336+
)
337+
})
338+
})?;
339+
340+
// Now optimize rust-analyzer with BOLT.
341+
bolt_optimize(&ra_binary, &ra_profile, env)
342+
.context("Could not optimize rust-analyzer with BOLT")?;
343+
323344
// LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
324-
Ok(vec![llvm_profile, rustc_profile])
345+
Ok(vec![llvm_profile, rustc_profile, ra_profile])
325346
})?
326347
} else {
327348
vec![]

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,19 @@ pub fn rustc_benchmarks(env: &Environment) -> CmdBuilder {
110110
init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["All"], RUSTC_PGO_CRATES)
111111
}
112112

113+
pub fn rust_analyzer_benchmarks(env: &Environment, ra_bin: &Utf8Path) -> CmdBuilder {
114+
let ld_library_path = std::env::var("LD_LIBRARY_PATH").unwrap_or_default();
115+
let ld_library_path =
116+
format!("{}:{ld_library_path}", env.rustc_stage_2().parent().unwrap().as_str());
117+
118+
CmdBuilder::default()
119+
.arg(ra_bin)
120+
.arg("analysis-stats")
121+
.env("LD_LIBRARY_PATH", &ld_library_path)
122+
.arg(env.checkout_path().join("src").join("tools").join("rust-analyzer"))
123+
.arg("--run-all-ide-things")
124+
}
125+
113126
pub struct LlvmPGOProfile(pub Utf8PathBuf);
114127

115128
pub fn gather_llvm_profiles(

0 commit comments

Comments
 (0)