-loop-unroll pass 是否强制 LLVM 展开循环?

Does the -loop-unroll pass force LLVM to unroll loops?

我有一段代码,我希望 LLVM 按某个因素展开其中的所有循环。我正在使用以下命令:

opt -mem2reg -simplifycfg -loops -lcssa -loop-simplify -loop-rotate -loop-unroll -unroll-count=3 -unroll-allow-partial -debug TrainingCode/trainingCode.ll -o TrainingCode/unrolledTrainingCode.bc

具体来说,-loop-unroll-unroll-count=3 处理循环展开的内容——其余的只是转换代码,以便 LLVM 可以展开代码。

此命令是否保证所有循环都展开 3 倍?或者它更像是在 GCC 中使用 pragma 语句,如果编译器认为它不是最佳的,它可以选择忽略它?换句话说,-loop-unroll-unroll-count=3 传递 强制 编译器使用 3 的展开因子还是更像是 "hint"编译器可以选择忽略吗?

据我所知,循环展开是 translated#pragmas 。如果在编译时不知道展开计数,则不会发生展开。如果你选择full unrolling,那就意味着LLVM确实会消除循环。

Does this command guarantee that all loops will be unrolled by a factor of 3?

简短的回答是否定的。

首先要看循环。例如,如果它是一个指针追踪循环,那就是一个主要的抑制因素。展开的一个决定因素是能够在编译时计算行程计数。因此,循环展开的主要帮助是执行 indvars 遍。

窥探 LoopUnroll.cppLoopUnrollPass.cpp 可能很有启发性。除此之外,还有像 NumCompletelyUnrolledNumUnrolled 这样的统计数据,可以给出粗略的整体状态。接下来,有一些元数据可以作为提示考虑(搜索 GetLoopUnrollMetadata 来补充@schaiba 所写的内容)。 pass 源文件中要遵循的另一件事是 TripCount 以及如何使用它来确定展开循环的确切策略。

PS:我的笔记是基于LLVM 3.7源代码树,所以我在描述中不是很明确。 YMMV 取决于您正在使用的版本,但这些东西大部分都在最新的主干 (6.0.0) 中。