Auto merge of #94381 - Kobzol:llvm-bolt, r=Mark-Simulacrum
Use BOLT in CI to optimize LLVM This PR adds an optimization step in the Linux `dist` CI pipeline that uses [BOLT](https://github.com/llvm/llvm-project/tree/main/bolt) to optimize the `libLLVM.so` library built by boostrap. Steps: - [x] Use LLVM 15 as a bootstrap compiler and use it to build BOLT - [x] Compile LLVM with support for relocations (`-DCMAKE_SHARED_LINKER_FLAGS="-Wl,-q"`) - [x] Gather profile data using instrumented LLVM - [x] Apply profile to LLVM that has already been PGOfied - [x] Run with BOLT profiling on more benchmarks - [x] Decide on the order of optimization (PGO -> BOLT?) - [x] Decide how we should get `bolt` (currently we use the host `bolt`) - [x] Clean up The latest perf results can be found [here](https://github.com/rust-lang/rust/pull/94381#issuecomment-1258269440). The current CI build time with BOLT applied is around 1h 55 minutes.
This commit is contained in:
commit
8dfb40722d
8 changed files with 158 additions and 7 deletions
|
|
@ -16,6 +16,7 @@ use std::io;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use crate::bolt::{instrument_with_bolt_inplace, optimize_library_with_bolt_inplace};
|
||||
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::channel;
|
||||
use crate::config::TargetSelection;
|
||||
|
|
@ -403,6 +404,12 @@ impl Step for Llvm {
|
|||
if let Some(path) = builder.config.llvm_profile_use.as_ref() {
|
||||
cfg.define("LLVM_PROFDATA_FILE", &path);
|
||||
}
|
||||
if builder.config.llvm_bolt_profile_generate
|
||||
|| builder.config.llvm_bolt_profile_use.is_some()
|
||||
{
|
||||
// Relocations are required for BOLT to work.
|
||||
ldflags.push_all("-Wl,-q");
|
||||
}
|
||||
|
||||
// Disable zstd to avoid a dependency on libzstd.so.
|
||||
cfg.define("LLVM_ENABLE_ZSTD", "OFF");
|
||||
|
|
@ -571,12 +578,34 @@ impl Step for Llvm {
|
|||
}
|
||||
}
|
||||
|
||||
// After LLVM is built, we modify (instrument or optimize) the libLLVM.so library file
|
||||
// in place. This is fine, because currently we do not support incrementally rebuilding
|
||||
// LLVM after a configuration change, so to rebuild it the build files have to be removed,
|
||||
// which will also remove these modified files.
|
||||
if builder.config.llvm_bolt_profile_generate {
|
||||
instrument_with_bolt_inplace(&get_built_llvm_lib_path(&build_llvm_config));
|
||||
}
|
||||
if let Some(path) = &builder.config.llvm_bolt_profile_use {
|
||||
optimize_library_with_bolt_inplace(
|
||||
&get_built_llvm_lib_path(&build_llvm_config),
|
||||
&Path::new(path),
|
||||
);
|
||||
}
|
||||
|
||||
t!(stamp.write());
|
||||
|
||||
build_llvm_config
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns path to a built LLVM library (libLLVM.so).
|
||||
/// Assumes that we have built LLVM into a single library file.
|
||||
fn get_built_llvm_lib_path(llvm_config_path: &Path) -> PathBuf {
|
||||
let mut cmd = Command::new(llvm_config_path);
|
||||
cmd.arg("--libfiles");
|
||||
PathBuf::from(output(&mut cmd).trim())
|
||||
}
|
||||
|
||||
fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
|
||||
if !builder.config.llvm_version_check {
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue