# Load LLVMConfig.cmake. If this fails, consider setting `LLVM_DIR` to point # to your LLVM installation's `lib/cmake/llvm` directory. # set(LLVM_DIR "/usr/lib/llvm-14/lib/cmake/llvm/") #找不到可以加 find_package(LLVM REQUIRED CONFIG) # Include the part of LLVM's CMake libraries that defines # `add_llvm_pass_plugin`. include(AddLLVM) # Use LLVM's preprocessor definitions, include directories, and library search # paths. add_definitions(${LLVM_DEFINITIONS}) include_directories(${LLVM_INCLUDE_DIRS}) link_directories(${LLVM_LIBRARY_DIRS}) # 要includeaddllvm才能用下面这个命令 add_llvm_pass_plugin(SkeletonPass # List your source files here. Skeleton.cpp )
$ clang -Xclang -load -Xclang build/skeleton/libSkeletonPass.* 某个c程序.c I saw a function called main!# 这里就会打印函数名称 # -Xclang -load -Xclang path/to/lib.so这是你在Clang中载入并激活你的流程所用的所有代码。 #所以当你处理较大的项目的时候,你可以直接把这些参数加到Makefile的CFLAGS里或者你构建系统的对应的地方。
cat ~/test.c 2 int test(int a, int b) 3 { 4 int c = 0; 5 if (a) { 6 c = b; 7 a = c; 8 } 9 return c; 10 } ../llvm_build/bin/clang ~/test.c -O0 -emit-llvm -S -o ~/test.ll cat ~/test.ll #查看ll这个IR语言的
structSkeletonPass : public PassInfoMixin<SkeletonPass> { PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM){ for (auto &F : M.functions()) { for (auto &B : F) { for (auto &I : B) { // dyn_cast<T>(p)构造函数是LLVM类型检查工具的应用。如果I不是“二元操作符”,这个构造函数返回一个空指针。 if (auto *op = dyn_cast<BinaryOperator>(&I)) { // Insert at the point where the instruction `op` // appears. // IRBuilder用于构造代码。 IRBuilder<> builder(op);
// Make a multiply with the same operands as `op`. Value *lhs = op->getOperand(0); Value *rhs = op->getOperand(1); Value *mul = builder.CreateMul(lhs, rhs);
// Everywhere the old instruction was used as an // operand, use our new multiply instruction instead. for (auto &U : op->uses()) { // A User is anything with operands. User *user = U.getUser(); user->setOperand(U.getOperandNo(), mul); }
// We modified the code. return PreservedAnalyses::none(); } } } } return PreservedAnalyses::all(); }; };
// 再举一个例子 // cat register.td classRegister<int _size, string _alias=""> { int size = _size; string alias = _alias; }
// 64 bit general purpose registers are X<N>. def X0: Register<8> {} // Some have special alternate names. def X29: Register<8, "frame pointer"> {} // Some registers omitted...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
执行tablegen命令./bin/llvm-tblgen register.td
------------- Classes ----------------- class Register<int Register:_size = ?, string Register:_alias = ""> { int size = Register:_size; string alias = Register:_alias; } ------------- Defs ----------------- def X0 { // Register int size = 8; string alias = ""; } def X29 { // Register int size = 8; string alias = "frame pointer"; }