函数转换Pass修改IR后,如何更新获取分析Pass结果?
在LLVM中修改IR后高效更新分析结果的方案
针对修改函数IR后无需全量重跑分析管线、直接更新并获取分析结果的需求,以下是LLVM生态下的实操方案:
1. 依赖AnalysisManager的自动失效与增量更新
LLVM的FunctionAnalysisManager是管理分析结果的核心组件,它会自动追踪分析的依赖关系和IR修改带来的失效:
- 当转换Pass修改函数IR后,受影响的分析结果会被标记为失效,但并非所有分析都需要全量重算——多数内置分析(比如
DominanceFrontierAnalysis、LoopAnalysis)已实现增量更新逻辑。 - 直接通过
AM.getResult<AnalysisType>(F)获取分析结果即可,AnalysisManager会自动判断:若结果仍有效则直接返回,若失效则触发增量或全量重算,无需手动重启整个分析管线。
2. 自定义分析Pass实现增量更新
如果是自己编写的分析Pass,要支持增量更新需重载invalidate方法,精准判断IR修改是否影响分析结果:
class MyCustomAnalysis : public AnalysisInfoMixin<MyCustomAnalysis> { public: using Result = MyAnalysisResult; Result run(Function &F, FunctionAnalysisManager &AM) { // 初始分析逻辑 } // 重载失效判断方法 bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv) { // 若当前分析被显式保留,直接返回false表示结果有效 if (PA.preserved<MyCustomAnalysis>()) return false; // 检查依赖的分析是否失效,或IR修改是否影响当前分析结果 return Inv.invalidate<DependencyAnalysis>(F, PA); } static AnalysisKey Key; }; AnalysisKey MyCustomAnalysis::Key;
3. 转换Pass中显式保留不受影响的分析
在转换Pass的run方法返回PreservedAnalyses对象时,明确保留那些未被IR修改影响的分析,减少不必要的重算:
PreservedAnalyses MyTransformPass::run(Function &F, FunctionAnalysisManager &AM) { // 修改IR的业务逻辑 // ... PreservedAnalyses PA; // 保留不受当前修改影响的自定义分析 PA.preserve<MyCustomAnalysis>(); // 保留未被影响的内置分析 PA.preserve<DominanceFrontierAnalysis>(); return PA; }
4. 同Pass内多次获取分析结果的正确姿势
在同一个转换Pass中,修改IR后再次获取分析结果,直接调用AM.getResult即可,AnalysisManager会自动处理更新:
void MyTransformPass::run(Function &F, FunctionAnalysisManager &AM) { // 获取初始分析结果 auto &initialResult = AM.getResult<MyCustomAnalysis>(F); // 修改函数IR modifyFunctionIR(F); // 自动获取更新后的分析结果 auto &updatedResult = AM.getResult<MyCustomAnalysis>(F); // 基于更新后的结果执行后续转换 applyFurtherTransforms(F, updatedResult); }
注意事项
- 避免手动缓存分析结果,完全依赖AnalysisManager管理,防止出现分析结果与IR状态不一致的问题。
- 内置LLVM分析已完善了失效与增量逻辑,直接使用即可,无需额外改造。
内容的提问来源于stack exchange,提问作者Bryan968
相关产品推荐
相关产品推荐

