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

如何通过LLVM API在程序中用新Pass Builder运行Pass优化IR

基于LLVM新Pass管理器在程序内优化内存IR模块的实现方案

一、核心步骤拆解

1. 加载本地Pass库

如果自定义Pass是编译为动态库的,用LLVM的llvm::sys::DynamicLibrary实现加载:

  • 调用llvm::sys::DynamicLibrary::LoadLibraryPermanently传入动态库路径完成加载
  • 通过sys::DynamicLibrary::SearchForAddressOfSymbol查找插件标准入口符号llvmGetPassPluginInfo
  • 将符号转换为函数指针并调用,获取PassPluginInfo结构体,执行其中的注册回调,把Pass注册到全局PassBuilder中

如果是静态库,无需动态加载,编译时直接链接即可。

2. 构建顺序执行的Pass管线

用llvm::PassBuilder构建管线,有两种常用方式:

  • 手动添加:创建llvm::ModulePassManager对象,调用addPass依次添加自定义Pass或标准Pass
  • 管线字符串解析:用PassBuilder::parsePipeline解析类似"my-custom-pass,instcombine"的字符串,自动按顺序添加Pass
  • 若需要标准优化级别(如-O2),可调用PassBuilder::buildPerModuleDefaultPipeline生成对应管线,再追加自定义Pass

3. 应用管线优化IR模块

  • 创建llvm::AnalysisManager<llvm::Module>,用于管理Pass执行所需的分析结果
  • 调用ModulePassManager::run,传入内存中的Module对象和AnalysisManager完成优化
  • 执行后原Module对象(或传入的拷贝)会被直接修改,可直接使用内存中的优化后IR

二、源码树外编译链接要点

编译时需要链接LLVM核心静态库,可通过llvm-config工具获取依赖:

  • 编译参数:$(llvm-config --cxxflags)
  • 链接参数:$(llvm-config --libs core passes support demangle analysis transformutils passbuilder)
  • 自定义Pass动态库编译需加-fPIC -shared参数

三、完整示例代码

主程序代码(内存IR优化)

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

using namespace llvm;

int main() {
    // 模拟内存中的IR模块(实际场景可从内存加载/生成)
    LLVMContext Context;
    std::unique_ptr<Module> M = std::make_unique<Module>("MyModule", Context);

    // 1. 加载自定义Pass动态库
    StringRef PassLibPath = "./libMyCustomPass.so";
    if (!sys::DynamicLibrary::LoadLibraryPermanently(PassLibPath.data())) {
        errs() << "加载Pass库失败: " << PassLibPath << "\n";
        return 1;
    }

    // 获取插件入口函数
    void *PluginEntry = sys::DynamicLibrary::SearchForAddressOfSymbol("llvmGetPassPluginInfo");
    if (!PluginEntry) {
        errs() << "找不到插件入口符号\n";
        return 1;
    }

    // 注册Pass到全局PassBuilder
    auto GetPluginInfo = reinterpret_cast<decltype(&llvmGetPassPluginInfo)>(PluginEntry);
    const PassPluginInfo &PluginInfo = GetPluginInfo();
    PluginInfo.RegisterPassBuilderCallbacks(*PassBuilder::getGlobalPassBuilder());

    // 2. 构建Pass管线
    ModulePassManager MPM;
    AnalysisManager<Module> AM;

    // 示例:解析管线字符串,按顺序执行自定义Pass+instcombine
    StringRef PipelineStr = "my-custom-pass,instcombine";
    if (Error E = PassBuilder().parsePipeline(MPM, PipelineStr, PassBuilder::PipelineParsingOptions{})) {
        errs() << "解析管线失败: " << toString(std::move(E)) << "\n";
        return 1;
    }

    // 可选:替换为-O2标准管线+追加自定义Pass
    // PassBuilder PB;
    // MPM = PB.buildPerModuleDefaultPipeline(PassBuilder::OptimizationLevel::O2);
    // MPM.addPass(MyCustomPass());

    // 3. 运行管线优化模块
    MPM.run(*M, AM);

    // 输出优化后的IR(实际场景直接使用内存中的Module即可)
    M->print(outs(), nullptr);

    return 0;
}

自定义Pass插件代码

#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/PassManager.h"

using namespace llvm;

struct MyCustomPass : public PassInfoMixin<MyCustomPass> {
    PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {
        // 这里写你的自定义Pass逻辑
        errs() << "运行MyCustomPass处理模块: " << M.getName() << "\n";
        return PreservedAnalyses::all();
    }
};

extern "C" LLVM_ATTRIBUTE_WEAK PassPluginInfo llvmGetPassPluginInfo() {
    return {
        LLVM_PLUGIN_API_VERSION, "MyCustomPass", "v0.1",
        [](PassBuilder &PB) {
            PB.registerPipelineParsingCallback(
                [](StringRef Name, ModulePassManager &MPM, ArrayRef<PassBuilder::PipelineElement>) {
                    if (Name == "my-custom-pass") {
                        MPM.addPass(MyCustomPass());
                        return true;
                    }
                    return false;
                }
            );
        }
    };
}

编译命令

  • 编译自定义Pass动态库:
    clang++ -fPIC -shared MyCustomPass.cpp -o libMyCustomPass.so $(llvm-config --cxxflags --libs core passes support analysis)
    
  • 编译主程序:
    clang++ Main.cpp -o Main $(llvm-config --cxxflags --libs core passes support demangle analysis transformutils passbuilder)
    

四、关键API说明

  • llvm::sys::DynamicLibrary:动态库加载与符号查找工具
  • llvm::PassBuilder:新Pass管理器的核心,负责管线构建、Pass注册、管线解析
  • llvm::ModulePassManager:模块级Pass的容器,管理Pass执行顺序
  • llvm::AnalysisManager<Module>:管理Pass依赖的分析结果,是Pass执行的必要参数
  • PassPluginInfo:Pass插件的标准信息结构体,包含Pass注册逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 05:27:18