如何在自定义llvm传递之间正确传递数据结构
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在自定义llvm传递之间正确传递数据结构相关的知识,希望对你有一定的参考价值。
我有一个Function
通行证,称为firstPass
,它做了一些分析和填充:
A a;
哪里
typedef std::map< std::string, B* > A;
class firstPass : public FunctionPass {
A a;
}
typedef std::vector< C* > D;
class B {
D d;
}
class C {
// some class packing information about basic blocks;
}
因此,我有一张std::string
遍历的矢量图。我为这些类编写了相关的析构函数。此传递可以自行成功。
我有另一个Function
传球,称为secondPass
,需要这种类型的A
结构进行一些转换。我用了
bool secondPass::doInitialization(Module &M) {
errs() << "now running secondPass
";
a = getAnalysis<firstPass>().getA();
return false;
}
void secondPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<firstPass>();
AU.setPreservesAll();
}
整个代码编译得很好,但是当我在第一次传递结束时打印这个结构时,只有当我调用第二遍时才会出现分段错误(因为B*
为null)。
要明确:
opt -load ./libCustomLLVMPasses.so -passA < someCode.bc
在doFinalization()
打印并成功退出
opt -load ./libCustomLLVMPasses.so -passA -passB < someCode.bc
给出了分段错误。
我应该如何包装这个数据结构并将其传递给第二遍而不会出现问题?我试过std::unique_ptr
而不是原始的但我无法使它工作。我不确定这是否是正确的方法,所以任何帮助将不胜感激。
编辑:我解决了seg的问题。故障。基本上我在doInitialization()中调用getAnalysis。我写了一个ModulePass来组合我的firstPass和secondPass,其runOnModule如下所示。
bool MPass::runOnModule(Module &M) {
for(Function& F : M) {
errs() << "F: " << F.getName() << "
";
if(!F.getName().equals("main") && !F.isDeclaration())
getAnalysis<firstPass>(F);
}
StringRef main = StringRef("main");
A& a = getAnalysis<firstPass>(*(M.getFunction(main))).getA();
return false;
}
这也让我控制了处理函数的顺序。现在我可以获得传递的输出但不能将其用作另一传递的输入。我认为这表明llvm中的传递是自包含的。
我不会根据他们的C ++优点来评论数据结构的质量(仅通过这个最小的例子很难评论)。
而且,我不会使用doInitialization
方法,如果实际的初始化就这么简单,但这也是一个侧面评论。 (doc没有明确提及它的任何内容,但如果每个Module
运行一次,而runOn
方法在该模块的每个Function
上运行,则可能是一个问题)。
我怀疑主要问题似乎源于你的A a
中的firstPass
绑定到传递对象的生命周期,一旦传递完成就结束了。最简单的改变是在堆上分配该对象(例如new
)并在调用getAnalysis<firstPass>().getA();
时返回指向它的指针。
请注意,如果您决定使用原始指针,则使用此方法可能需要手动清理。
以上是关于如何在自定义llvm传递之间正确传递数据结构的主要内容,如果未能解决你的问题,请参考以下文章
如何在自定义 UIView 中从 ViewController 传递数据
如何在自定义 cmdlet 中正确使用 -verbose 和 -debug 参数