LLVM Pass 第一步

2023/02/18 LLVM 共 1714 字,约 5 分钟
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/ADT/Statistic.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 {
  struct Hello : public FunctionPass {
    static char ID;
    Hello() : FunctionPass(ID) {}

    ~Hello() {
        errs() << "\nCompile Finish!\n";
        errs() << "Functions count: " << HelloCounter;
    }

    bool runOnFunction(Function &F) override {
      ++HelloCounter;
      errs() << "Got Function> ";
      errs().write_escaped(F.getName()) << '\n';
      return false;
    }
  };
}

char Hello::ID = 0;
// 为 opt 注册
static RegisterPass<Hello> X("funcname", "Hello World Pass");
// 为 clang 注册, 在高版本中不可用, 测试在10.0.0版本中可用
static RegisterStandardPasses Y(PassManagerBuilder::EP_EarlyAsPossible,
                                [](const PassManagerBuilder& Builder,
                                   legacy::PassManagerBase& PM) {
                                  PM.add(new Hello());
                                });

使用以下命令编译此 LLVM Pass:

clang `llvm-config --cxxflags` -Wl,-znodelete -fno-rtti -fPIC -shared Hello.cpp -o LLVMHello.so `llvm-config --ldflags`

使用以下命令使用此 LLVM Pass:

## opt
opt -enable-new-pm=0 -load ./LLVMHello.so -funcname main.ll
# -enable-new-pm=0: 设置 Pass 管理器为旧版本
# -load ./LLVMHello.so: 加载 LLVMBirkhoff.so 模块作为 LLVM Pass
# -funcname: 指定要执行的命令为 funcname

## clang
clang -flegacy-pass-manager -g -Xclang -load -Xclang ./LLVMHello.so main.c -o main.elf
# -flegacy-pass-manager: 使用旧版本的Pass Manager, 以支持在 LLVM 13 版本中使用 LLVM Pass
# -Xclang -load -Xclang ./LLVMHello.so: 加载LLVMHello.so作为LLVM Pass
# main.c: 要编译的源代码文件
# -o main.elf: 生成的可执行文件文件名。

img

文档中提到, optimization pipeline 使用新版本的 PM (New PM), 而后端(即 backend) 使用旧版 PM(Legacy PM), 而一部分 IR Pass 被认为属于后端.

输出结果如下:

$ clang -flegacy-pass-manager -g -Xclang -load -Xclang ./LLVMHello.so main.c -o main.elf 
Got Function> add
Got Function> main

Compile Finish!
Functions count: 2

文档信息

搜索

    Table of Contents