Frage

I have the following loop in a C code:

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
}

I want to determine that the array b has a stride of 3 and f has increment factor of 2 in the above code.

The generated LLVM assembly is(for the block containing loop):

;<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

Now in my LoopPass, I use the following code:

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

}

But I don't get anything as output. What am I doing wrong here ?

War es hilfreich?

Lösung

First of all, the proper way to get an integer from a ConstantInt instance is via getSExtValue(), not getValue(); and it's best if you also make sure you can handle the returned value, so:

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

Secondly, just getting the value passed as the 3rd operand to the GEP will not get you a ConstantInt, it will get you a pointer to the sext instruction! If you want to find the actual constant, you have to traverse the graph all the way back until you find the add instruction, then identify the constant as one of its operands.

Finally, it seems you are looking for offsets, not steps; but if you are looking for steps, consider using Scalar Evolution, which has mechanisms you might find useful, such as:

/// 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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top