我正在编写一个 LLVM FunctionPass,它可以相当积极地转换某些函数。它最终会删除旧的一组块并用完全不同的块替换它们。但是,之后运行的循环展开器 (LoopUnrollPass) 无法在转换后的函数中找到循环。(转换后的版本应该有自然循环。)
重新创建一个函数后我有什么需要戳的吗?如何触发循环检测器再次运行?最后,在转换函数时是否还需要更新其他分析?
我正在编写一个 LLVM FunctionPass,它可以相当积极地转换某些函数。它最终会删除旧的一组块并用完全不同的块替换它们。但是,之后运行的循环展开器 (LoopUnrollPass) 无法在转换后的函数中找到循环。(转换后的版本应该有自然循环。)
重新创建一个函数后我有什么需要戳的吗?如何触发循环检测器再次运行?最后,在转换函数时是否还需要更新其他分析?
首先,以防万一您跳过它,阅读了解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>();
}