LLVM将Loop*存储在std::vector中
LLVM storing Loop* in std::vector
我偶然发现了一件非常奇特的事情——我正在编写一个LLVM模块Pass。我迭代模块的所有函数,然后迭代每个非声明函数的所有循环,并将指向循环的指针存储在std::vector
中。来源:
virtual bool runOnModule(Module& Mod){
std::vector<Loop*> loops;
// first gather all loop info
for(Module::iterator f = Mod.begin(), fend = Mod.end(); f != fend; ++f){
if (!(*f).isDeclaration()){
LoopInfo& LI = getAnalysis<LoopInfo>(*f);
for(LoopInfo::iterator l = LI.begin(), lend = LI.end(); l != lend; ++l){
loops.push_back(*l);
}
}
}
for (auto& l: loops) errs () << *l << " ";
}
现在,如果我运行这个,我会得到一个运行时错误-它无法打印循环,不知怎么的,我正在做一个空指针取消引用或其他什么。有什么想法吗?
您必须确保LoopInfo
过程在您的过程之前实际运行
class AnalyzeLoops : public FunctionPass {
public:
AnalyzeLoops()
: FunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfo>();
}
virtual bool runOnFunction(Function &F) {
LoopInfo &LI = getAnalysis<LoopInfo>();
for (LoopInfo::iterator L = LI.begin(), LE = LI.end(); L != LE; ++L) {
(*L)->dump();
}
return false;
}
static char ID;
};
此外,在创建通行证时,执行:
PassManager PM;
PM.add(new LoopInfo());
PM.add(new AnalyzeLoops());
PM.run(*Mod);
我怀疑要使opt
在通过之前真正运行LoopInfo
,您也应该通过-loops
。
此外,请注意,我定义了getAnalysisUsage
——如果LoopInfo
在此过程之前没有运行,这将使LLVM抱怨,从而使问题更加明显。
注意,LoopInfo
具体地是FunctionPass
,并且作为分析,它必须从另一个FunctionPass
使用。LoopInfo
数据结构在不同的函数之间并不能真正存活下来,而且由于它拥有自己的数据(那些Loop*
对象),它们也会被销毁。
如果您真的需要ModulePass
,您可以做的一件事就是手动调用LoopInfo
,而不是作为分析。迭代模块中的函数时,为每个函数创建一个新的LoopInfo
对象并使用其runOnFunction
方法。尽管即使在这种情况下,如果您想使用给定的Loop*
,您也必须确保拥有该CCD_19的LoopInfo
仍然存在。
首先,LoopInfo应该在for循环之前运行一次。第二个LoopInfo::迭代器只包括Function的顶级循环。为了访问所有循环,您还需要迭代每个循环的子循环。它既可以用递归函数实现,也可以用WorkList实现,比如
virtual bool runOnFunction(Function &F) {
LoopInfo *loopinfo;
loopinfo = &getAnalysis<LoopInfo>();
std::vector<Loop*> allLoops;
for (LoopInfo::iterator Li = loopinfo->begin(), Le = loopinfo->end();
Li != Le; Li++) {
Loop *L = *Li;
allLoops.push_back(L);
dfsOnLoops(L, loopinfo, allLoops);
}
}
void dfsOnLoops(Loop *L, LoopInfo *loopinfo, std::vector<Loop*> LoopS) {
std::vector<Loop *> subloops = L->getSubLoops();
if (subloops.size()) {
// recursive on subloops
for (std::vector<Loop *>::iterator Li = subloops.begin();Li != subloops.end(); Li++){
LoopS.push_back(*Li);
dfsOnLoops(*Li, loopinfo, LoopS);
}
}
}
`
没有一个答案真的有帮助,但我自己设法解决了这个问题。基本上,每个llvm传递都可以定义一个releaseMemory()方法,请在此处阅读更多信息。LoopInfo类实现了该方法,因此每当我们从对getAnalysis的调用中脱离作用域时,分析信息就会丢失。我只是删除了Loopinfo.h中的releaseMemory()方法,内存就不再被释放了。请注意,这引发了代码库的巨大变化,甚至不得不重建opt,所以一般来说这样做可能是个坏主意,而且这肯定不会被轻易接受为对llvm的更改(我推测,不确定)。
我认为解决这个问题的最佳方法是显式创建LoopInfo对象并保存它们。这是LLVM 3.5 的代码
using LoopInfoType=llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>;
std::vector<llvm::Loop*> loopVec;
std::vector<LoopInfoType*> loopInfoVec;
for(llvm::Module::iterator F = M.begin(); F!= M.end(); F++){
//skip declrations
if(F->isDeclaration()){
continue;
}
//TODO that scope problem
llvm::DominatorTree DT = llvm::DominatorTree();
DT.recalculate(*F);
LoopInfoType *loopInfo = new LoopInfoType();
loopInfo->releaseMemory();
loopInfo->Analyze(DT);
loopInfoVec.push_back(loopInfo);
for(llvm::LoopInfo::iterator lit = loopInfo->begin(); lit != loopInfo->end(); lit++){
Loop * L = * lit;
loopVec.push_back(L);
//L->dump();
}
}//for all functions
cin.get();
for(auto loop : loopVec){
std::cout << "loopn";
loop->dump();
for(llvm::Loop::block_iterator bit = loop->block_begin(); bit != loop->block_end(); bit++){
llvm::BasicBlock * B = * bit;
B->dump();
std::cout << "nn";
}
}
- 使用std::vector的OpenCL矩阵乘法
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- std::vector的包装器,使数组的结构看起来像结构的数组
- 编译器如何区分std::vector的构造函数
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 在std::vector上存储带有模板的类实例
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 为什么std::vector比数组慢
- std::vector::迭代器是否可以合法地作为指针
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 为什么std::vector和std::valarray初始化构造函数不同
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 在没有未定义行为的情况下实现类似std::vector的容器
- 如何调整 std::vector of Eigen::MatrixXd 的大小
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 如何将AERT_Allocate与 std:vector 一起使用
- 推导 std::vector::back() 的返回类型
- 如何将原始字节附加到 std::vector?
- std::vector 没有重载函数的实例与参数列表匹配
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?