Table of Contents
1 Prepare LLVM project.
- Clone LLVM-Project from Github.
git clone https://github.com/llvm/llvm-project.git <your_favorite_folder>
- Build LLVM-Project with Building LLVM with CMake
cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_TARGETS_TO_BUILD="RISCV" -G Ninja ../llvm cmake --build .
After build completed, we have a workable opt for testing our new passes,
like the following command shows.
cd llvm-project/build ./bin/opt -load lib/LLVMHello.dylib --help ... Optimizations available: --aa - Function Alias Analysis Results ...
2 Make your pass
Reference Writing an LLVM Pass to make a pass.
3 Compile your pass
Because in above step, following that document to make an example pass,
we should add add_subdirectory(XXX) into the lib/Transforms/CMakeLists.txt.
So when we reconfig our cmake build, cmake will generate build commands to handle our new pass shared library.
cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_TARGETS_TO_BUILD="RISCV" -G Ninja ../llvm cmake --build .
Then the compiled shared library would be under the build/lib directory.
4 Test it with opt
./bin/opt -load lib/LLVMHello.dylib -hello <xxx.ll>
-load: load a shared library.
-hello: execute the hello pass.
<xxx.ll>: the file to be run pass on.
5 Dump Passes
To dump passes, we can add a module pass to do that.
namespace {
struct DumpPasses : public ModulePass {
static char ID; // Pass identification, replacement for typeid
DumpPasses() : ModulePass(ID) {}
bool runOnModule(Module &) override {
this->getResolver()->getPMDataManager().getTopLevelManager()->dumpPasses();
return false;
}
};
} // namespace
char DumpPasses::ID = 0;
static RegisterPass<DumpPasses> Z("DumpPasses", "DumpPasses");
Then rebuild llvm:
cmake --build .
Now, use the following command to show the result:
./bin/opt --debug-pass=Structure -S -load lib/BBOpts.dylib -DumpPasses <xxx.ll>