3

为了开发我自己的 Pass,我想编写单元测试——我有很多“纯”辅助方法,所以它们似乎是单元测试的理想候选者。但其中一些需要 llvm::LoopInfo 的实例作为参数。

在我的 (Function-)Pass 我只是使用

void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
    AU.setPreservesCFG();
    AU.addRequired<llvm::LoopInfoWrapperPass>();
}
...
llvm::LoopInfo &loopInfo = getAnalysis<LoopInfoWrapperPass>(F).getLoopInfo();

获取此信息对象。

在我的单元测试中,我目前llvm::Function void foo()从磁盘解析我的(我想运行我的分析),如下所示:

llvm::SMDiagnostic Err;
llvm::LLVMContext Context;
std::unique_ptr<llvm::Module> module(parseIRFile(my_bc_filename, Err, Context));
llvm::Function* foo = module.operator*().getFunction("foo");

要完成我的测试,我必须填写以下存根:

llvm::LoopInfo& = /*run LoopInfoWrapperPass on foo and return LoopInfo element */;

我的第一次尝试是基于使用PassManager<Function>(in Header "llvm/IR/PassManager.h"), AnalysisManager<Function>和 class LoopInfoWrapperPass,但我在网上找不到 LLVM 4.0 的任何示例用法 - 较旧的示例似乎使用了以前的PassManager 的版本,我没有看到如何使用LegacyPassManager. 我试图调查来源,PassManager但无法充分理解 typedef 和模板参数(它们增加了我对 C++ 作为一种语言的非理性厌恶)。

我该如何填写那个存根?如何在我的纯 C++ 代码中调用此分析通行证(并获取 LoopInfo)?

PS:除了 LoopInfoWrapperPass 之外,我还需要使用更多的通行证,但我假设这种方式应该可以转移到任何分析通行证。

PPS:我使用 googletest 作为单元测试框架,使用 CMake 构建配置使单元测试成为自己的目标,并且我正在针对 LLVM 4.0.1 的二进制库(如果有)构建我的 Pass out-of-tree这在某种程度上是相关的。

4

1 回答 1

1

我不确定你的单元测试是如何结构化的,但是在 LLVM 源代码树中查看是个好主意。

一个例子可以在CFGTest.cpp 这里找到。您需要自己创建PassManager和管道。根据我在这方面的短暂经验,它适用于小型测试,但是一旦您需要更大的东西或将数据传入/传出,它就会真正受到限制,因为LoopInfo数据仅在管道中有意义(又名runOn()方法和朋友)。

否则,您可能希望选择(没有双关语)更简单的恕我直言,自己创建所需分析集的方法(仅在 的情况下为支配者LoopInfo)而不使用通行证管理器基础结构。这方面的一个例子可以在这里看到。

希望这可以帮助。

于 2017-11-09T12:31:59.023 回答