Update README
feat(generator): Add maximum number of functions cli option
feat(generator): Add functions only if some constraints are met
Profile guided optimization of LLVM-IR via combinatorial optimization and metaheuristics.
This repository is part of an end of degree work: A Combinatorial Approach for Profile Guided Optimization with Metaheuristics.
IMPORTANT NOTE: This project is a preliminary work in approaching code optimizations from the CO and metaheuristics perspective. The objective is not to reach state-of-the-art performance, but to motivate the research in this direction, and open new doors to efficient and intelligent code optimizations.
Code optimization is one of the main tasks that a modern compiler is expected to handle. However, the number of different code optimization scenarios that compilers have to face is vast.
With the objective to address the maximum number of code optimization scenarios as possible, most compilers employ conservative and generalist heuristics in their decision taking process, missing many code optimization opportunities.
In recent years, the growing popularity of ML, has guided multiple attempts to replace the mentioned heuristics with ML based systems. However, the learning and inference cost of ML models, has stopped these proposals to reach real-world environments.
In this work, we propose a new approach for improving code optimization heuristics. Concretely, we focus on the basic block ordering code optimization, and formalize it as a combinatorial problem, with the objective to apply CO algorithms to solve such problem.
Conducted experiments reveal that our CO approach is comparable to the one implemented in the widely used clang compiler, even being able to improve its results in some of the collected metrics.
First, ensure that you have the following dependencies:
Then, clone this repository and move inside:
git clone https://git.sr.ht/~mikelma/pgo_co
cd pgo_co
Once inside the repo, you can build the project as the following:
# to build fully optimized
cargo build --profile opt
# or, to build as debug
cargo build
If the --features log
CLI option is given in to the cargo build
command,
the optimizer
tool will generate a CSV log file with a variety optimization
stats when it is run.
Once the command finishes, compiled binaries will be located inside target/opt
(if it was a debug build, in target/debug
).
These are the tools that compose the project:
inspector
: Given an annotated(*) LLVM IR bitcode file, outputs a bunch of information about the
relevant profiling metadata contained in the IR.
generator
: Generates a combinatorial problem instance file from an annotated LLVM IR bitcode.
optimizer
: Given an LLVM IR bitcode file to optimize, and its instance (the one generated by generator
tool),
optimizes the basic block layout of the program.
(*) With annotated, I refer to LLVM IR that contains profiling metadata, see this, and this for more info.
In the following lines, the steps to optimize your program with our PGO approach are listed. Note that our optimization operates on LLVM IR, thus, it can be applied to any programming language that translates to LLVM.
The first step is to generate profiling data about the program to optimize. Clang's
documentation has an excellent guide on how to do this
(link).
If your project does not use clang, you can refer to the specific guide on PGO of your compiler of choice.
Anyhow, the objective of this step is to generate one or multiple whatever.profraw
files with the profiling data.
Link all the .profraw
files into a single .profdata
file with the following command:
llvm-profdata merge -output=code.profdata *.profraw
Compile your program into a single LLVM, annotated, IR bitcode file. This can be done adding
the -flto
and -fprofile-instr-use=code.profdata
flags in your compilation command (if you use
clang or a compatible compiler), as it will generate a bunch of .o
files that contain LLVM IR
bitcode, that can be linked by running: llvm-link *.o -o linked.bc
.
Generate an CO problem instance file with the following command: ./generator -i linked.bc -o myprogram.json
Optimize linked.bc
with: ./optimizer -i linked.bc -p myprogram.json -o optimized.ll
Finally you can compile the optimized LLVM IR to a binary (linked to the libraries you might need):
clang optimized.ll -o myprogram <the linker flags you might need>
This project is distributed under the terms of the GLPv3 license. See LICENSE for more details.