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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值