如何用新Pass Manager编写带前置依赖的LLVM自定义函数Pass?
LLVM新Pass Manager实现自定义Pass自动依赖LoopSimplify
在新Pass Manager中,不再使用getAnalysisUsage()来声明依赖,而是通过以下两种方式实现自定义Pass自动触发LoopSimplify,无需手动在命令行添加loop-simplify:
方式一:在自定义Pass的run方法中直接运行LoopSimplify
这种方式直接在自定义Pass的执行逻辑前调用LoopSimplify,适合简单场景:
#include "llvm/Transforms/Scalar/LoopSimplify.h" #include "llvm/Passes/PassPlugin.h" #include "llvm/Passes/PassBuilder.h" using namespace llvm; struct CustomPass : PassInfoMixin<CustomPass> { PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) { // 先执行LoopSimplify转换Pass LoopSimplifyPass loopSimplify; PreservedAnalyses PA = loopSimplify.run(F, FAM); // 编写你的自定义Pass核心逻辑 // ... // 合并保留的分析结果,避免破坏分析缓存 return PA; } // 标记Pass为必须执行(可选,确保不会被优化移除) static bool isRequired() { return true; } }; // 注册Pass extern "C" LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo llvmGetPassPluginInfo() { return { LLVM_PLUGIN_API_VERSION, "CustomPass", "v0.1", [](PassBuilder &PB) { PB.registerPipelineParsingCallback( [](StringRef Name, FunctionPassManager &FPM, ArrayRef<PassBuilder::PipelineElement>) { if (Name == "custom-pass") { FPM.addPass(CustomPass()); return true; } return false; } ); } }; }
方式二:通过PassBuilder映射自定义Pass为包含依赖的Pipeline
这种方式更符合新PM的设计理念,将自定义Pass的名称解析为包含LoopSimplify的Pass序列,解耦依赖关系:
#include "llvm/Transforms/Scalar/LoopSimplify.h" #include "llvm/Passes/PassPlugin.h" #include "llvm/Passes/PassBuilder.h" using namespace llvm; struct CustomPass : PassInfoMixin<CustomPass> { PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) { // 编写你的自定义Pass核心逻辑 // ... // 返回保留的分析结果 return PreservedAnalyses::all(); } static bool isRequired() { return true; } }; // 注册Pass并映射Pipeline extern "C" LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo llvmGetPassPluginInfo() { return { LLVM_PLUGIN_API_VERSION, "CustomPass", "v0.1", [](PassBuilder &PB) { PB.registerPipelineParsingCallback( [](StringRef Name, FunctionPassManager &FPM, ArrayRef<PassBuilder::PipelineElement>) { if (Name == "custom-pass") { // 自动添加LoopSimplify到自定义Pass之前 FPM.addPass(LoopSimplifyPass()); FPM.addPass(CustomPass()); return true; } return false; } ); } }; }
注意事项
- 编译时需链接LLVM的
LLVMTransformsScalar库,确保LoopSimplify相关代码可被调用。 - LoopSimplify是转换Pass而非分析Pass,因此需要作为转换步骤添加到Pipeline中,不能通过分析管理器获取。
- 正确处理
PreservedAnalyses,避免不必要的分析结果失效,提升Pass管理器的运行效率。
内容的提问来源于stack exchange,提问作者Billy
相关产品推荐
相关产品推荐

