llvm-pass编写尝试

Findkey Lv1

一.环境准备

指引:

  • whitebird师傅blog:Blog
  • llvm的官方文档:LLVM

注意:ninja -j8 很慢是正常的,
也可以改成ninja -j4或ninja -j2
(报错可以多次使用,配置低一点数字就调小一点)

二.开始编写llvm-pass(示例)

首先,进入llvm-project(源码文件夹)中的llvm/inlucde/llvm/Transforms/Utils文件夹.
我们看见了官方文档所说的HelloWorld.h头文件,

#ifndef LLVM_TRANSFORMS_UTILS_ENCODE_H
#define LLVM_TRANSFORMS_UTILS_ENCODE_H

#include "llvm/IR/PassManager.h"

namespace llvm {

class HelloWorldPass : public PassInfoMixin {
public:
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};

} // namespace llvm

#endif // LLVM_TRANSFORMS_UTILS_ENCODE_H

这是个简单的模板,我们在这个目录下创建一个Encode.h

#ifndef LLVM_TRANSFORMS_UTILS_ENCODE_H
#define LLVM_TRANSFORMS_UTILS_ENCODE_H

#include "llvm/IR/PassManager.h"//可能会用编译器警告,可忽略

namespace llvm {

class EncodePass : public PassInfoMixin {
public:
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};

} // namespace llvm

#endif // LLVM_TRANSFORMS_UTILS_ENCODE_H

创建完头文件后我们需要创建对应的cpp文件
进入llvm-project的llvm/lib/Transforms/Utils目录下,
创建Encode.cpp,内容如下:

#include "llvm/Transforms/Utils/Encode.h"
using namespace llvm;
PreservedAnalyses EncodePass::run(Function &F,
                                      FunctionAnalysisManager &AM) {
  errs() << F.getName() << "\n";//获取函数名称
  return PreservedAnalyses::all();
}

然后在llvm/lib/Transforms/Utils的Cmakelists.txt中添加

Encode.cpp

alt text

在llvm/lib/Passes/PassRegistry.def中添加

FUNCTION_PASS("encode",EncodePass())

alt text

在llvm/lib/Passes/PassBuilder.cpp添加

#include "llvm/Transforms/Utils/Encode.h"

alt text

进而,我们在clion打开重新加载该项目
alt text

然后进入编译出现的cmake-build-release文件夹
用终端打开,
使用命令:

ninja -j2 opt

ok,准备工作已经完成

三.使用一下自定义的llvm-pass

首先创建一个简单的c语言代码(这里直接借用kw17师傅blog的代码)

#include

void test_hello1(){

  printf("test_hello1\n");
  return ;
}
void test_hello2(){

  printf("test_hello2\n");

  return ;
}
int main(int argc ,char const *argv[]){

  printf("hello clang\n");

  return 0;
}

用终端打开该文件所在目录,

clang -O3 -emit-llvm hello_clang.c -S -o hello_clang.ll

这里的-o3应该也可以是-o1或-o2,
而hello_clang.c是文件名

如果clang报错说not found,就是没加环境变量

export PATH=/home/whitebird/llvm-project-llvmorg-14.0.6/llvm/cmake-build-release/bin:$PATHlan

记得改成自己对应的目录

然后使用

opt -disable-out hello_clang.ll -passes=helloworld

就输出了该文件的所有函数名

以上.

参考

参考内容:

  • Title: llvm-pass编写尝试
  • Author: Findkey
  • Created at : 2024-08-15 10:31:30
  • Updated at : 2024-08-15 15:58:17
  • Link: https://find-key.github.io/2024/08/15/llvm-pass编写尝试/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments