介绍:实现一个简单的打印function name的out-of-tree pass
项目准备
-
项目布局:
-
<project dir>/ | CMakeLists.txt <pass name>/ | CMakeLists.txt Pass.cpp ...
-
-
/CMakeLists.txt的内容:
-
#指定cmake最小版本 cmake_minimum_required(VERSION 3.13.4) #设置项目名称 project("XXXX") #cmake参数,不加报错 SET(CMAKE_CXX_FLAGS "-Wall -fno-rtti") #查找指定的库文件 find_package(LLVM REQUIRED CONFIG) #将${LLVM_DEFINITIONS}的内容 #以NATIVE_COMMAND的要求分割 #保存在LLVM_DEFINITIONS_LIST中 separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) # 和C/C++中的#define是一样的 add_definitions(${LLVM_DEFINITIONS_LIST}) #将给定的目录添加到编译器(compiler)用于搜索包含文件的目录 include_directories(${LLVM_INCLUDE_DIRS}) #编译子文件夹的CMakeLists.txt add_subdirectory(pass name)
-
-
//CMakeLists.txt的内容:
-
add_library(LLVMPassname MODULE Pass.cpp) //以Pass.cpp为源文件添加moudle模式的名为LLVMPassname的库
-
-
//pass.cpp的内容:
-
#include "llvm/Pass.h" #include "llvm/IR/Function.h" #include "llvm/Support/raw_ostream.h" #include "llvm/IR/LegacyPassManager.h" using namespace llvm; namespace { struct Hello : public FunctionPass { static char ID; Hello() : 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 Hello::ID = 0; static RegisterPass<Hello> X("hello", "Hello World Pass", //通过参数 -hello来使用该pass false /* Only looks at CFG */, false /* Analysis Pass */);
-
编辑项目
-
在目录下执行以下命令:
-
mkdir build cd build cmake .. make cd ..
-
-
在build目录下会生成如下目录文件布局:
-
build/ | CMakeCache.txt CMakeFiles cmake_install.cmake Makefile <pass name>/ | CMakeFiles cmake_install.cmake Makefile lib<pass name>.so
-
pass的使用(通过opt加载pass)
-
opt -load ./build/pass name/lib<pass name>.so \-hello //选择pass \./test_fun/hello.ll //自行编译 \-enable-new-pm=0 //因为使用的legacy pass manager不是并不是LLVM默认的PassManager,所以需要添加该参数