Everyone who needs to learn LLVM must know that this is a powerful open source compilation tool chain. In fact, the more you study later, you will find that this thing and the design idea are very awesome. This thing can bring pluggable optimization to the compilation process, which is very convenient. This article does not talk about what LLVM is, but mainly involves practical operation, How to install to complete the first Pass optimization.
There are many ways to download LLVM source code. Here we only talk about git method.
LLVM source code download
git clone https://github.com/llvm/llvm-project
Directly clone this project from git. You can find that after cloning, there are many folders under llvm project, including llvm and so on. This llvm is the core tool we need to use. Create the folder build in llvm project (at the same level as llvm), and then compile the source code.
LLVM compilation
Note here:
- Cmake can add some options to specify the platform or other information. For this, please refer to others on the Internet, but I can directly cmake
- The number behind make -j determines the number of cores to compile. If a single core is used, it will be very, very slow (a few hours). The 16 cores I use here are about a few minutes
- If you encounter a red flag in the process of make and # make install and try sudo, it may be that the file cannot be created during the compilation process
cd llvm-project mkdir build cd build cmake ../llvm make -j4 make install
Written by the first PASS
In this part, we will write the first PASS, and we will not introduce what PASS is. We will write a simple IR analytical PASS and output a function name. The next chapter will introduce the detailed writing method of PASS in detail.
In fact, you follow the official documents( Writing an LLVM Pass — LLVM 15.0.0git documentation )Yes, I'm sure I can. Let's move it here in simple and clear Chinese.
Step 1: create a folder to store your pass. The official website document says that the path is arbitrary, but let's follow the tutorial. First, go to / llvm project / llvm / lib / transforms and create a myhello folder to store our pass.
cd llvm/lib/Transforms mkdir my hello
In this new folder, there are two things
- CMakeLists.txt this must be compiled for our new PASS, but LLVM provides us with a good interface. We just need to do this
add_llvm_library( LLVMmyhello MODULE myhello.cpp PLUGIN_TOOL opt )
2. myhello.cpp# this is our PASS. Let's simply output the name of the Hello function. (a simple analytical PASS)
#include "llvm/Pass.h" #include "llvm/IR/Function.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { struct myhello : public FunctionPass { static char ID; myhello() : FunctionPass(ID) {} bool runOnFunction(Function &F) override { errs() << "Hello: "; errs().write_escaped(F.getName()) << '\n'; return false; } }; // end of struct Hello } // end of anonymous namespace char myhello::ID = 0; static RegisterPass<myhello> X("myhello", "my Hello World Pass", false /* Only looks at CFG */, false /* Analysis Pass */);
x I'm sure you understand. This is the name of the Hello function.
Step 2: go back to the build directory and make again. After making, you will find that llvmmyhello. Com has appeared in build/lib So this file (don't ask me why the file name is so frustrating, it's easy to distinguish)
Step 3: we create a test folder at the same level as llvm and build to test. In it, we randomly write an input c
int add(int a,int b){ return a+b; } int sub(int a,int b){ return a-b; }
Step4: then we use the clang tool to compile bitcode, and then use the opt tool to load our own pass. It's over!! If red or all errors are reported, please continue sudo
Note: the new version needs to be added with - enable new PM = 0, which must be added without error
clang -emit-llvm input.c -o -c input.bc sudo opt -enable-new-pm=0 -load ../build/lib/LLVMmyhello.so -myhello input.bc