我试图弄清楚如何运行 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 命令的示例,但到目前为止还没有成功;我很感激任何关于我可能遗漏的提示(我是矢量化代码的新手,所以它可能非常明显)。
谢谢,
斯蒂芬