LLVM9.0编写Hello pass
最近动手尝试了一下,在安装完成LLVM9.0之后,新建一个FunctionPass。以下是参考他人文档和自己实现的过程。
1. 新建或修改Hello.cpp
在/home/zgl/llvm-project-9.0.0/llvm/lib/Transforms/Hello目录下新建或修改Hello.cpp,代码如下:
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
using namespace llvm;
#define DEBUG_TYPE "hello"
STATISTIC(HelloCounter, "Counts number of functions greeted");
namespace {
// Hello - The first implementation, without getAnalysisUsage.
struct Hello : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
Hello() : FunctionPass(ID) {}
bool runOnFunction(Function &F) override {
++HelloCounter;
errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
};
}
// 初始化pass的ID
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass");
// 将本pass注册为现有流水线中的一步
static RegisterStandardPasses Y(
PassManagerBuilder::EP_EarlyAsPossible,
[](const PassManagerBuilder &Builder,
legacy::PassManagerBase &PM)
{PM.add(new Hello()); }
);
2. 新建或修改CMakeLists.txt
在/home/zgl/llvm-project-9.0.0/llvm/lib/Transforms/Hello目录下新建或修改CMakeLists.txt,添加代码如下:
if( NOT LLVM_REQUIRES_RTTI )
if( NOT LLVM_REQUIRES_EH )
set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/Hello.exports)
endif()
endif()
if(WIN32 OR CYGWIN)
set(LLVM_LINK_COMPONENTS Core Support)
endif()
add_llvm_library(LLVMHello MODULBUILDTREE_ONLY SHARED
Hello.cpp
DEPENDS
intrinsics_gen
PLUGIN_TOOL
opt
)
3. 修改上层目录CMakeLists.txt
修改/home/zgl/llvm-project-9.0.0/llvm/lib/Transforms目录下CMakeLists.txt文件,如下:add_subdirectory(Hello)
4. 编译Hello.cpp
若你在xx/Hello/CMakeLists.txt文件中没采用添加SHARED
属性的方式来生成动态链接库,而是使用clang编译:
clang `llvm-config --cxxflags` -Wl,-znodelete -fno-rtti -fPIC -shared Hello.cpp -o LLVMHello.so `llvm-config --ldflags`
在使用opt -load
的时候可能会因为libc++
和stdlibc++
不一致的原因出现如下错误:
Error opening '/home/zgl/llvm-project-9.0.0/llvm/lib/Transforms/Hello/LLVMHello.so': /home/zgl/llvm-project-9.0.0/llvm/lib/Transforms/Hello/LLVMHello.so: undefined symbol: _ZNK4llvm12FunctionPass17createPrinterPassERNS_11raw_ostreamERKSs
-load request ignored.
此处使用安装LLVM时的脚本来编译: step1.sh,编译完成之后在/home/zgl/llvm-project-9.0.0/llvm/build/lib/
目录下生成一个LLVMHello.so
的动态库,LLVMHello
为生成的库名字。
5. 测试
找个测试文件,使用clang
工具生成.ll文件。clang -emit-llvm -S -c size.c -o size.ll
。
使用opt -load /home/zgl/llvm-project-9.0.0/llvm/build/lib/LLVMHello.so -hello <size.ll> /dev/null
便可成功查看到pass的输出信息。
也可使用opt -load /home/zgl/llvm-project-9.0.0/llvm/build/lib/LLVMHello.so -gvn -hello -licm --debug-pass=Structure <size.ll> /dev/null
命令打印pass的依赖信息。
References:
- https://zhuanlan.zhihu.com/p/122522485
- https://www.jianshu.com/p/9f450969121b
上一篇: 分治法的递归算法模式
下一篇: php表单笔记
推荐阅读
-
俺啥也不懂-不知道什么时候才会编写操作系统-一个hello world写一年-10h中断黑底绿字
-
编写第一个程序hello world
-
FFmpeg 开发环境搭建及第一个程序 Hello FFmpeg 编写
-
RabbitMQ(五)之快速编写Hello RabbitMQ
-
golang编写Hello World
-
win10下Free Pascal使用方法(从安装、消除乱码、编写个简单的hello谈起)
-
使用JavaScript的AngularJS库编写hello world的方法
-
typecho插件编写教程(一):Hello World
-
typecho插件编写教程(一):Hello World_PHP
-
typecho插件编写教程(一):Hello World,typechohello