我试图弄清楚如何运行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)。我在一个更大的基准测试中运行了这个传递,它在每个循环中给出了完全相同的错误,因此我猜测它不是循环本身,但我不是给它足够的信息。
我花了很多时间梳理文档和Google搜索结果,找到使用此转换的完整opt命令的示例,但到目前为止还没有成功;我很欣赏任何关于我可能遗漏的提示(我对代码进行矢量化以及它可能非常明显)。
谢谢,
斯蒂芬
答案 0 :(得分:0)
矢量化取决于之前需要运行的其他优化的数量。它们根本不在-O0运行,因此您不能指望您的代码只是&#39;只是&#39;在那里矢量化。
在opt cmdline中添加-O2之前的-loop-vectorize会有所帮助(确保你的&#39; A&#39;阵列是外部的/以某种方式使用,否则一切都将被优化掉。)