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>