You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在LLVM FunctionPass中获取自定义RegionPass的分析结果?

在FunctionPass中获取自定义RegionPass的分析结果

要实现这个需求,你需要让你的RPass保存分析结果并提供公共访问接口,同时在FPass中声明对RPass的依赖,这样LLVM的Pass管理器会确保RPass先完成所有Region的分析,再运行你的FPass。下面是具体的实现步骤和代码示例:

步骤1:修改RPass,保存并暴露分析结果

首先,你的RPass需要存储每个Region的分析数据,并提供一个方法让外部Pass获取指定Region的结果。同时要确保它被标记为分析Pass(不修改IR):

#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionPass.h"
#include "llvm/Pass.h"
#include <map>
#include <cassert>

class RPass : public RegionPass {
public:
  static char ID;
  RPass() : RegionPass(ID) {}

  // 用map存储每个Region对应的分析结果,这里假设结果是int,你可以替换成自己的类型
  std::map<Region*, int> RegionAnalysisResults;

  bool runOnRegion(Region *R, RGPassManager &RGM,
                   PassManagerBuilder &PMB) override {
    // 这里写你的Region分析逻辑,示例计算Region包含的基本块数量
    int exampleResult = R->getBlocks().size();
    RegionAnalysisResults[R] = exampleResult;
    
    return false; // 分析Pass不修改IR,返回false
  }

  // 公共方法:获取指定Region的分析结果
  int getResultForRegion(Region *R) {
    auto resultIter = RegionAnalysisResults.find(R);
    // 断言确保Region已经被分析过,避免运行时错误
    assert(resultIter != RegionAnalysisResults.end() && "Region未被RPass分析!");
    return resultIter->second;
  }

  // 声明这是一个分析Pass,不修改任何IR
  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesAll();
  }
};

// 注册RPass,最后两个参数:false表示不修改IR,true表示这是一个分析Pass
char RPass::ID = 0;
static RegisterPass<RPass> X("r-pass", "自定义Region分析Pass", false, true);

步骤2:修改FPass,声明依赖并获取结果

接下来,在你的FPass中,需要声明对RPass的依赖,这样LLVM会先执行RPass处理函数内的所有Region,然后你就可以通过RPass的实例获取每个Region的结果:

#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include <deque>

class FPass : public FunctionPass {
public:
  static char ID;
  FPass() : FunctionPass(ID) {}

  bool runOnFunction(Function &F) override {
    // 获取当前函数的RegionInfo
    auto &regionInfo = getAnalysis<RegionInfoPass>().getRegionInfo();
    std::deque<Region *> regionQueue = getRegionList(regionInfo->getTopLevelRegion());

    // 获取RPass的实例,因为已经声明依赖,这里可以安全获取
    auto &rPassInstance = getAnalysis<RPass>();

    // 遍历每个Region,获取分析结果
    for(Region *R : regionQueue){
      int regionResult = rPassInstance.getResultForRegion(R);
      // 这里写你使用分析结果的逻辑,比如打印结果
      llvm::errs() << "函数" << F.getName() << "中的Region,包含" << regionResult << "个基本块\n";
    }

    return false;
  }

  // 声明Pass依赖:必须先运行RegionInfoPass和RPass
  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<RegionInfoPass>();
    AU.addRequired<RPass>(); // 关键:添加对RPass的依赖
    AU.setPreservesAll();
  }
};

// 注册FPass
char FPass::ID = 0;
static RegisterPass<FPass> Y("f-pass", "使用Region分析结果的FunctionPass", false, false);

关键注意事项

  • Pass注册类型:确保RPass注册时最后一个参数为true,标记为分析Pass,LLVM会正确保留它的分析数据。
  • 依赖声明:FPass的getAnalysisUsage必须添加AU.addRequired<RPass>(),否则Pass管理器不会先运行RPass,会导致获取分析结果时出错。
  • 结果存储:如果你的分析结果是复杂类型,建议使用智能指针或者确保Region的生命周期长于RPass实例(LLVM中Region和函数生命周期一致,Pass实例由PassManager管理,只要PassManager存在,结果就会保留)。
  • Legacy vs New Pass Manager:上面的代码基于传统的Legacy Pass Manager,如果使用LLVM 13+的新Pass Manager,需要使用AnalysisInfoMixin等新的API,但核心逻辑(保存结果+依赖声明)是一致的。

内容的提问来源于stack exchange,提问作者TSG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:04:27