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) である必要があります。このパスをはるかに大きなベンチマークで実行したところ、すべてのループでまったく同じエラーが発生したため、ループ自体ではないと推測していますが、十分な情報を提供していません。
この変換を使用した完全な opt コマンドの例を見つけるために、ドキュメントと Google の結果をくまなく調べましたが、これまでのところ成功していません。何が欠けているかについてのヒントをいただければ幸いです (コードをベクトル化するのは初めてなので、非常に明白なものになる可能性があります)。
ありがとうございました、
スティーブン