У меня есть следующий цикл в коде 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
}
Но я ничего не получаю в качестве вывода. Что я здесь не так делаю?
Прежде всего, правильный способ получить целое число от ConstantInt
экземпляр через getSExtValue()
не getValue()
; и лучше, если вы также убедитесь, что можете обработать возвращаемое значение, поэтому:
assert (CI->getBitWidth() <= 32);
int x = CI->getSExtValue();
Во-вторых, простое получение значения, переданного в качестве третьего операнда в GEP, не даст вам ConstantInt
, вы получите указатель на sext
инструкция! Если вы хотите найти фактическую константу, вы должны пройти весь график назад, пока не найдете add
инструкции, затем идентифицируйте константу как один из ее операндов.
Наконец, кажется, вы ищете смещения, а не шаги; но если ты являются ищите шаги, рассмотрите возможность использования 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
Других решений пока нет …