-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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](#94381 (comment)). The current CI build time with BOLT applied is around 1h 55 minutes.
- Loading branch information
Showing
8 changed files
with
158 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
use std::path::Path; | ||
use std::process::Command; | ||
|
||
/// Uses the `llvm-bolt` binary to instrument the binary/library at the given `path` with BOLT. | ||
/// When the instrumented artifact is executed, it will generate BOLT profiles into | ||
/// `/tmp/prof.fdata.<pid>.fdata`. | ||
pub fn instrument_with_bolt_inplace(path: &Path) { | ||
let dir = std::env::temp_dir(); | ||
let instrumented_path = dir.join("instrumented.so"); | ||
|
||
let status = Command::new("llvm-bolt") | ||
.arg("-instrument") | ||
.arg(&path) | ||
// Make sure that each process will write its profiles into a separate file | ||
.arg("--instrumentation-file-append-pid") | ||
.arg("-o") | ||
.arg(&instrumented_path) | ||
.status() | ||
.expect("Could not instrument artifact using BOLT"); | ||
|
||
if !status.success() { | ||
panic!("Could not instrument {} with BOLT, exit code {:?}", path.display(), status.code()); | ||
} | ||
|
||
std::fs::copy(&instrumented_path, path).expect("Cannot copy instrumented artifact"); | ||
std::fs::remove_file(instrumented_path).expect("Cannot delete instrumented artifact"); | ||
} | ||
|
||
/// Uses the `llvm-bolt` binary to optimize the binary/library at the given `path` with BOLT, | ||
/// using merged profiles from `profile_path`. | ||
/// | ||
/// The recorded profiles have to be merged using the `merge-fdata` tool from LLVM and the merged | ||
/// profile path should be then passed to this function. | ||
pub fn optimize_library_with_bolt_inplace(path: &Path, profile_path: &Path) { | ||
let dir = std::env::temp_dir(); | ||
let optimized_path = dir.join("optimized.so"); | ||
|
||
let status = Command::new("llvm-bolt") | ||
.arg(&path) | ||
.arg("-data") | ||
.arg(&profile_path) | ||
.arg("-o") | ||
.arg(&optimized_path) | ||
// Reorder basic blocks within functions | ||
.arg("-reorder-blocks=ext-tsp") | ||
// Reorder functions within the binary | ||
.arg("-reorder-functions=hfsort+") | ||
// Split function code into hot and code regions | ||
.arg("-split-functions=2") | ||
// Split as many basic blocks as possible | ||
.arg("-split-all-cold") | ||
// Move jump tables to a separate section | ||
.arg("-jump-tables=move") | ||
// Use GNU_STACK program header for new segment (workaround for issues with strip/objcopy) | ||
.arg("-use-gnu-stack") | ||
// Fold functions with identical code | ||
.arg("-icf=1") | ||
// Update DWARF debug info in the final binary | ||
.arg("-update-debug-sections") | ||
// Print optimization statistics | ||
.arg("-dyno-stats") | ||
.status() | ||
.expect("Could not optimize artifact using BOLT"); | ||
|
||
if !status.success() { | ||
panic!("Could not optimize {} with BOLT, exit code {:?}", path.display(), status.code()); | ||
} | ||
|
||
std::fs::copy(&optimized_path, path).expect("Cannot copy optimized artifact"); | ||
std::fs::remove_file(optimized_path).expect("Cannot delete optimized artifact"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters