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

LLVM 16.0.6自定义HelloPass加载失败求助:opt提示未知pass名称

问题排查与解决方案

你的核心问题在于LLVM 16默认启用新版Pass Manager(New PM),但你的代码使用的是旧版Legacy Pass Manager的注册方式,导致opt无法识别自定义的hello Pass。以下是具体的排查和解决方法:

一、快速修复:使用旧版Pass Manager调用Opt

直接修改opt命令,强制启用旧版Pass Manager并使用旧参数格式:

opt -load build/helloPass/libHelloPass.so -legacy-pass-manager -hello test.bc > /dev/null

执行该命令后,应该能正常输出函数名的Hello日志。

二、长期方案:适配新版Pass Manager修改代码

如果需要兼容LLVM 16+的新版Pass Manager,需要修改代码和CMake配置:

1. 修改hello.cpp代码

替换为新版Pass的定义与注册逻辑:

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

using namespace llvm;

namespace {
// 继承新版Pass的基类PassInfoMixin
struct Hello : public PassInfoMixin<Hello> {
    // 新版Pass的核心执行方法
    PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
        errs() << "Hello: ";
        errs().write_escaped(F.getName()) << '\n';
        return PreservedAnalyses::all(); // 保留所有分析结果
    }

    // 标记该Pass为必须执行
    static bool isRequired() { return true; }
};
} // 匿名命名空间结束

// 注册Pass插件的入口函数
extern "C" LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo llvmGetPassPluginInfo() {
    return {
        LLVM_PLUGIN_API_VERSION, "HelloPass", "v0.1",
        [](PassBuilder &PB) {
            // 注册Pipeline解析回调,识别"hello"命令
            PB.registerPipelineParsingCallback(
                [](StringRef Name, FunctionPassManager &FPM, ArrayRef<PassBuilder::PipelineElement>) {
                    if (Name == "hello") {
                        FPM.addPass(Hello());
                        return true;
                    }
                    return false;
                }
            );
        }
    };
}

2. 更新CMake配置

修改helloPass/CMakeLists.txt,添加新版Pass所需的链接库:

cmake_minimum_required(VERSION 3.25)

add_library(HelloPass MODULE hello.cpp)

set_target_properties(HelloPass PROPERTIES
        COMPILE_FLAGS "-fno-rtti"
)

# 链接新版Pass相关库
target_link_libraries(HelloPass PRIVATE LLVMIRReader LLVMPasses)

同时优化主CMakeLists.txt,使用LLVM提供的标准变量替代手动路径:

cmake_minimum_required(VERSION 3.25)
project(llvm_kernel CXX C)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_COMPILER /usr/bin/clang)
set(CMAKE_CXX_COMPILER /usr/bin/clang++)

find_package(LLVM REQUIRED CONFIG)

separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})

# 使用LLVM自动设置的目录变量
include_directories(${LLVM_INCLUDE_DIRS})
link_directories(${LLVM_LIBRARY_DIRS})

add_subdirectory(helloPass)

3. 编译并调用

重新编译后,使用新版Pass Manager的命令调用:

opt --load-pass-plugin=build/helloPass/libHelloPass.so -p hello test.bc > /dev/null

三、额外验证

执行以下命令查看是否能识别自定义Pass:

opt --load-pass-plugin=build/helloPass/libHelloPass.so --print-passes | grep hello

此时应该能看到自定义的hello Pass。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:11:07