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

如何从LLVM Pass中获取O0、O1、O2等编译优化等级

解决方案

LLVM 没有直接在 Function Pass 上下文内置查询优化等级的单步API,你可以根据你使用的 PassManager 版本选择以下实现方式:

新PassManager(LLVM 13+ 官方推荐)

优化等级可以在注册Pass时从PassBuilder实例中获取,作为构造参数传入你的Function Pass即可:

#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

namespace {
class MyFunctionPass : public PassInfoMixin<MyFunctionPass> {
  OptimizationLevel CurrentOL;
public:
  // 构造函数接收优化等级参数
  MyFunctionPass(OptimizationLevel OL) : CurrentOL(OL) {}

  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
    // 检测到O0/O1直接返回,跳过当前Pass逻辑
    if (CurrentOL == OptimizationLevel::O0 || CurrentOL == OptimizationLevel::O1) {
      return PreservedAnalyses::all();
    }

    // 此处放置O2/O3下需要执行的Pass逻辑
    errs() << "Running pass on function: " << F.getName() << "\n";
    return PreservedAnalyses::all();
  }

  static bool isRequired() { return true; }
};
} // 匿名命名空间

// Pass 注册逻辑
extern "C" LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo llvmGetPassPluginInfo() {
  return {
    LLVM_PLUGIN_API_VERSION, "MyFunctionPass", "v0.1",
    [](PassBuilder &PB) {
      // 手动指定-pass参数调用时的注册逻辑
      PB.registerPipelineParsingCallback(
        [&](StringRef Name, FunctionPassManager &FPM, ArrayRef<PassBuilder::PipelineElement>) {
          if (Name == "my-custom-pass") {
            FPM.addPass(MyFunctionPass(PB.getOptLevel()));
            return true;
          }
          return false;
        }
      );
      // 自动插入到优化流水线末尾的注册逻辑
      PB.registerOptimizerLastEPCallback(
        [](ModulePassManager &MPM, OptimizationLevel OL, ThinLTOPhase, PassBuilder::DebugLogging) {
          FunctionPassManager FPM;
          FPM.addPass(MyFunctionPass(OL));
          MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
        }
      );
    }
  };
}

旧版Legacy PassManager

直接引用LLVM全局定义的OptLevel命令行参数即可读取当前优化等级:

#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

// 引用LLVM全局定义的优化等级参数,无需自己重新定义
extern cl::opt<int> OptLevel;

namespace {
struct LegacyMyFunctionPass : public FunctionPass {
  static char ID;
  LegacyMyFunctionPass() : FunctionPass(ID) {}

  bool runOnFunction(Function &F) override {
    // OptLevel取值0对应O0、1对应O1、2对应O2、3对应O3
    if (OptLevel <= 1) {
      return false;
    }

    // 此处放置O2/O3下需要执行的Pass逻辑
    errs() << "Running legacy pass on function: " << F.getName() << "\n";
    return false;
  }
};
} // 匿名命名空间

char LegacyMyFunctionPass::ID = 0;
static RegisterPass<LegacyMyFunctionPass> X("legacy-my-pass", "My Legacy Custom Function Pass");

注意事项

  • 仅需要跳过当前Pass执行时,直接返回空修改的结果即可,不会影响其他Pass的正常运行
  • 如果你需要直接终止整个编译流程,可以调用report_fatal_error("MyPass requires O2/O3 optimization level"),该方法会直接中断编译并输出错误信息,非必要不建议使用
  • LLVM 12及更早版本的新PassManager没有PassBuilder::getOptLevel()接口,你可以在注册Pass时手动把优化等级作为参数传入即可正常使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:24:07