LLVM 学习
目录
安装
git clone --depth 1 --branch release/16.x https://github.com/llvm/llvm-project.git
cd llvm-project
mkdir build
cd build
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TARGETS_TO_BUILD="AArch64" ../llvm
ninja -j2
sudo ninja installPass示例
最外面的CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(Skeleton) # 定义项目名称
set(CMAKE_CXX_STANDARD 17)
# 查找 LLVM 的安装路径,export LLVM_DIR=/path/to/llvm-install/lib/cmake/llvm/
find_package(LLVM REQUIRED CONFIG)
# 加载 LLVM 提供的 AddLLVM.cmake 脚本。这个脚本提供了 add_llvm_pass_plugin 宏,用于 简化 LLVM Pass 插件的构建
include(AddLLVM)
add_definitions(${LLVM_DEFINITIONS}) # 添加 LLVM 的预处理器定义
include_directories(${LLVM_INCLUDE_DIRS}) # 添加 LLVM 的头文件搜索路径(如 llvm/IR、llvm/Support 等)。
link_directories(${LLVM_LIBRARY_DIRS}) # 添加 LLVM 库文件的搜索路径(如 libLLVMCore.so、libLLVMSupport.so 等)。
# 进入 skeleton 子目录,并执行其中的 CMakeLists.txt
add_subdirectory(skeleton)子目录下的cmakelist:
add_llvm_pass_plugin(SkeletonPass
# List your source files here.
Skeleton.cpp
)源码文件后面再好好看,先写一下命令:
# build
$ cd llvm-pass-skeleton
$ mkdir build
$ cd build
$ cmake ..
$ make
$ cd ..
# run
$ clang -fpass-plugin=./build/skeleton/SkeletonPass.so test.c -o testPass源码分析
#include "llvm/Pass.h" // LLVM Pass 基础类
#include "llvm/IR/Module.h" // Module 类定义
#include "llvm/Passes/PassBuilder.h" // PassBuilder 类
#include "llvm/Passes/PassPlugin.h" // Pass 插件机制
#include "llvm/Support/raw_ostream.h" // LLVM 输出流Pass 主体结构:
struct SkeletonPass : public PassInfoMixin<SkeletonPass> {
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {
// Pass 的主要逻辑
};
};- 继承自 PassInfoMixin 模板类
- 必须实现 run() 方法作为 Pass 的入口点
- PreservedAnalyses 表示 Pass 保留了哪些分析结果
Pass 核心逻辑
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
{
for (auto &F : M)
{
errs() << "I saw a function called " << F.getName() << "!\n";
}
return PreservedAnalyses::all();
};返回值表示这个 Pass 没有修改任何分析结果,保留了所有之前的分析。
插件注册
extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo() {
return {
.APIVersion = LLVM_PLUGIN_API_VERSION,
.PluginName = "Skeleton pass",
.PluginVersion = "v0.1",
.RegisterPassBuilderCallbacks = [](PassBuilder &PB) {
PB.registerPipelineStartEPCallback(
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(SkeletonPass());
});
}
};
}clang参数
clang -fsyntax-only -Xclang -ast-dump test.cpp-fsyntax-only意味着只解析语法,不进行编译和链接(不会生成 a.out);-Xclang是指向 Clang 核心传递一个选项,也就是后面紧挨着的-ast-dump-ast-dump是 Clang 核心的选项,表示要求打印出语法树