2

Cコードに次のループがあります。

int f[10],b[10],k=0;
for(int i = 0; i < 10; i++)
{
    k = b[i+3]*f[i+2]; //please ignore the out of bound problem
}

上記のコードで、配列bのストライドが3で、fの増分係数が2であることを確認したいと思います。

生成されたLLVMアセンブリは(ループを含むブロックの場合):

;<label>:12
%13 = load i32* %i, align 4
%14 = icmp slt i32 %13, 10
br i1 %14, label %15, label %30

;<label>:15                         ;preds=%12
%16 = load i32* %i, align 4
%17 = add nsw i32 %16,**3** // this is the increment value
%18 = sext i32 %17 to i64
**%19 = getelementptr inbounds [10 x i32]* %b, i32 0, i64 % 18**
%20 = load i32* % 19, align 4
%21 = load i32* %i, align 4
%22 = add nsw i32 %21,**2** // this is the increment value
%23 = sext i32 %22 to i64
**%24 = getelementptr invounds[10xi32]* %f, i32 0, i64 %23**
%25 = load i32* %24, align 4
%26 = mul nsw i32 %20, %25
store i32 %26, i32* %k, align 4
br label %27

;<label>:27
%28 = load i32* %l, align 4
%29 = add nsw i32 %28,1
store i32 %29, i32* %i, align 4
br label %12

今私のLoopPassでは、次のコードを使用しています。

Value *f = gep->getOperand(3);
if(dyn_cast<llvm::ConstantInt>(f))
{
    errs()<<(dyn_cast<llvm::ConstantInt>(f))->getValue();
   // the output should be 3 and 2 respectively

}

しかし、出力として何も得られません。私はここで何が間違っているのですか?

4

1 に答える 1

1

まず、ConstantIntインスタンスから整数を取得する適切な方法はgetSExtValue()、 ではなくgetValue();を使用することです。また、返された値を処理できることも確認するのが最善です。

assert (CI->getBitWidth() <= 32);
int x = CI->getSExtValue();

第 2 に、3 番目のオペランドとして GEP に渡された値を取得するだけでは、命令ConstantIntへのポインターは取得されませんsext。実際の定数を見つけたい場合は、add命令が見つかるまでグラフをたどり、そのオペランドの 1 つとして定数を特定する必要があります。

最後に、ステップではなくオフセットを探しているようです。ただし、手順を探している場合は、次のような便利なメカニズムを備えた Scalar Evolution の使用を検討してください。

/// getStepRecurrence - This method constructs and returns the recurrence
/// indicating how much this expression steps by.  If this is a polynomial
/// of degree N, it returns a chrec of degree N-1.
/// We cannot determine whether the step recurrence has self-wraparound.
const SCEV *getStepRecurrence(ScalarEvolution &SE) const
于 2012-11-01T10:09:58.527 に答える