0

我试图弄清楚如何运行 LLVM 的内置循环矢量化器。我有一个包含一个非常简单的循环的小程序(我曾经有一些输出,这就是为什么 stdio.h 尽管从未被使用过,但仍然被包含在内):

  1 #include <stdio.h>
  2 
  3 unsigned NUM_ELS = 10000;
  4 
  5 int main() {
  6     int A[NUM_ELS];
  7 
  8 #pragma clang loop vectorize(enable)
  9     for (int i = 0; i < NUM_ELS; ++i) {
 10         A[i] = i*2;
 11     }
 12 
 13     return 0;
 14 }

如您所见,它没有任何用处。我只需要 for 循环可以矢量化。我正在将其编译为 LLVM 字节码

clang -emit-llvm -O0 -c loop1.c -o loop1.bc
llvm-dis -f loop1.bc

然后我将矢量化器与

opt -loop-vectorize -force-vector-width=4 -S -debug loop1.ll

但是,调试输出给了我这个:

LV: Checking a loop in "main" from loop1.bc
LV: Loop hints: force=? width=4 unroll=0
LV: Found a loop: for.cond
LV: SCEV could not compute the loop exit count.
LV: Not vectorizing: Cannot prove legality.

我在 LLVM 源代码中进行了一些研究,看起来 SCEV 来自 ScalarEvolution 通道,它的任务是(除其他外)计算返回到循环条件的后边缘的数量,在这种情况下(如果我没记错的话)应该是行程计数减去第一次行程(在这种情况下为 9,999)。我已经在一个更大的基准上运行了这个 pass,它在每个循环中都给了我完全相同的错误,所以我猜它不是循环本身,而是我没有给它足够的信息。

我花了很多时间梳理文档和谷歌结果,以找到使用此转换的完整 opt 命令的示例,但到目前为止还没有成功;我很感激任何关于我可能遗漏的提示(我是矢量化代码的新手,所以它可能非常明显)。

谢谢,

斯蒂芬

4

1 回答 1

0

矢量化取决于之前需要运行的其他优化的数量。它们根本不会在 -O0 处运行,因此您不能期望您的代码会在那里“只是”矢量化。

在 opt cmdline 中的 -loop-vectorize 之前添加 -O2 会有所帮助(确保您的“A”数组是外部的/以某种方式使用,否则一切都会被优化掉)。

于 2014-11-18T18:21:58.970 回答