1. 在 github 页面下载最新的 llvm 工程, 当初最新的版本应该对应着是 llvm13
2. 在 llvm-project/llvm/lib/Transforms 文件夹新建自定义的 pass 文件夹
cd llvm-project/llvm/lib/Transforms
mkdir MyPass
在 MyPass 文件夹下新建一个 CMakeLists.txt
写入
add_llvm_library( MYPass MODULE
MYPass.cpp
DEPENDS
intrinsics_gen
PLUGIN_TOOL
opt
)
3. 在 llvm-project/llvm/lib/Transforms/CmakeLists.txt 中增加文件夹目录
add_subdirectory(MYPass)
4. 编写 Pass
#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;
}
void getAnalysisUsage(AnalysisUsage &AU) const override {AU.setPreservesAll();
}
void releaseMemory() override {errs() << "releaseMemory";
}
};
}
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass",false,false);
static RegisterStandardPasses Y2(PassManagerBuilder::EP_EarlyAsPossible,[](const PassManagerBuilder &Builder,legacy::PassManagerBase &PM) {PM.add(new Hello());
});
5. 构建和编译 pass
cd /yourPath/llvm-project
cmake -S llvm -B build -G Xcode -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi"
在 xcode 里抉择 sechme:MYPass, 开始编译
编译实现后,可在 llvm-project/build/Debug/bin 目录下找到编译后的可执行文件, 以及 llvm-project/build/Debug/lib 目录下找到 LLVM pass 的动静库
5.opt 应用 MYPass.dylib, 这里官网文档有误, 须要通过 -enable-new-pm= 0 指定用 legacy pass manager
./opt -load ../lib/LLVMHello.dylib -hello -enable-new-pm=0 < hello.bc >/dev/null
6.clang 应用 MYPass.dylib, 这里官网文档有误, 须要通过 -flegacy-pass-manager 指定用 legacy pass manager
hello.mm 只有 c /c++ 根本库女人
./clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.2.sdk -Xclang -load -Xclang ../lib/LLVMHello.dylib -flegacy-pass-manager hello.mm
-isysroot 指定零碎 sdk 版本
如果有用到 oc 的库编译还需指定 -framework Foundation
./clang -framework Foundation -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.2.sdk -Xclang -load -Xclang ../lib/LLVMHello.dylib -flegacy-pass-manager hello.m
hello.m 源码
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
int main(){NSLog(@"songxuhua");
return 0;
}