我正在编写一个LLVM FunctionPass,可以相当积极地转换某些功能。它最终会删除旧的块集并用完全不同的块替换它们。但是,之后运行的循环展开器(LoopUnrollPass)无法在转换后的函数中找到循环。 (转换后的版本应该有自然循环。)
重新创建一个函数后,我有什么需要戳的吗?如何触发循环检测器再次运行?最后,还有其他分析,我必须在转换函数时更新吗?
答案 0 :(得分:5)
首先,如果您跳过它,请务必阅读Writing and LLVM Pass文档页面。
当您的传递运行时,它会说明功能/模块是否已被修改。传递管理器应该将其作为重新运行下一次传递所需的所有分析的线索,除非你的传递声明它保留它们(使用addPreserved
)。您可以在LoopUnroll
方法中查看getAnalysisUsage
所需的分析列表:
/// This transformation requires natural loop information & requires that
/// loop preheaders be inserted into the CFG...
///
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfo>();
AU.addPreserved<LoopInfo>();
AU.addRequiredID(LoopSimplifyID);
AU.addPreservedID(LoopSimplifyID);
AU.addRequiredID(LCSSAID);
AU.addPreservedID(LCSSAID);
AU.addRequired<ScalarEvolution>();
AU.addPreserved<ScalarEvolution>();
AU.addRequired<TargetTransformInfo>();
// FIXME: Loop unroll requires LCSSA. And LCSSA requires dom info.
// If loop unroll does not preserve dom info then LCSSA pass on next
// loop will receive invalid dom info.
// For now, recreate dom info, if loop is unrolled.
AU.addPreserved<DominatorTree>();
}