首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Clang中自动注册和加载现代通行证?

如何在Clang中自动注册和加载现代通行证?
EN

Stack Overflow用户
提问于 2019-01-31 03:17:04
回答 1查看 822关注 0票数 7

我正在尝试编写一个简单的“现代”LLVM传递,并将其与Clang一起使用。我希望它能够使用如下命令运行:clang -Xclang -load -Xclang libMyPass.so file.cpp

有很多关于如何将遗留pass集成到Clang中的手册。然而,关于新的pass管理器的信息并不多。我偶然看到了一系列名为“2018年写LLVM通行证”的文章。但它只提到了将通行码放在LLVM代码树中的一种情况。并且我需要在树外构建模块。

代码语言:javascript
复制
class MyPass : public llvm::PassInfoMixin<MyPass> {
public:
    llvm::PreservedAnalyses run(
        llvm::Function &F,
        llvm::FunctionAnalysisManager &FAM
    ) {
    // Pass code here
    }
};

extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
    return {
        LLVM_PLUGIN_API_VERSION, "MyPass", "v0.1",
        [](llvm::PassBuilder &PB) {
            PB.registerPipelineParsingCallback(
                [](
                    llvm::StringRef Name, llvm::FunctionPassManager &FPM,
                    llvm::ArrayRef <llvm::PassBuilder::PipelineElement>
                ) {
                    if (Name == "my-pass") {
                        FPM.addPass(MyPass());
                        return true;
                    }
                    return false;
                }
            );
        }
    };
}

目前,pass没有被执行。我尝试查看-print-after-all选项的输出,并使用std::cout检测它是否已经运行。我在日志中看不到我的通行证。我在控制台窗口中也看不到调试输出。

EN

回答 1

Stack Overflow用户

发布于 2021-03-05 06:35:51

两年过去了,关于这样做的信息仍然很少。我花了一段时间才弄明白我自己的通行证。

首先,让clang使用你的通行库:

代码语言:javascript
复制
clang -O1 -fexperimental-new-pass-manager -fpass-plugin=libMyPass.so file.cpp

请注意,-O1标志很重要(稍后我将介绍这一点)。

至于您的通行证,我无法找到强制 clang 使用“解析管道”,因此我们必须使用 llvm::PassBuilder 上的其他优化器扩展点之一(几乎所有这些都需要优化级别一个或以上,因此-O1)。由于您的 pass 的 run 方法采用 Function,我们需要一个采用 FunctionPassManger 的扩展点回调。我们将使用 registerVectorizerStartEPCallback

代码语言:javascript
复制
class MyPass : public llvm::PassInfoMixin<MyPass> {
public:
    llvm::PreservedAnalyses run(
        llvm::Function &F,
        llvm::FunctionAnalysisManager &FAM
    ) {
    // Pass code here
    }
};

extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
    return {
        LLVM_PLUGIN_API_VERSION, "MyPass", "v0.1",
        [](llvm::PassBuilder &PB) {
            PB.registerVectorizerStartEPCallback(
                [](
                    llvm::FunctionPassManager &FPM,
                    llvm::OptimizationLevel &O
                ) {
                    FPM.addPass(MyPass());
                  }
            );
        }
    };
}

这段代码只有在LLVM11中才是正确的。后来的版本有了新的PassBuilder扩展点,并删除或重命名了一些旧的扩展点。尽管如此,registerVectorizerStartEPCallback在LLVM13中仍然存在。

我花了很长时间试图弄清楚是否可以通过构造一个新的FunctionPassMangager来强制clang使用一个自定义的传递,但似乎没有办法让clang使用它。如果您想坚持使用树外传递,优化器扩展点似乎是惟一的选择。

提示-阅读LLVM头文件或浏览clang源码树在执行此类操作时非常有用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54447985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档