a[1]
的等效IR是
%0 = load i32, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @a, i32 0, i64 1), align 4
在此示例中,我需要通过转换传递将a[1]
更改为*(a + 100 + 1)
。
一般情况下,迭代指令如何
答案 0 :(得分:1)
假设您有Instruction *I
。要检查它是否为load
,您可以使用LLVM' dyn_cast
:
if (LoadInst *LoadI = dyn_cast<LoadInst>(I)) {
// We have identified that I is a load instruction, and assigned it to LoadI
Value *PointerOp = LoadI->getPointerOperand();
load
指令只是取消引用指针。这个指针的值实际上是由getelementptr
计算的,这是一个LLVM概念,因混淆初学者而臭名昭着。请查看此处了解更多详情:http://llvm.org/docs/GetElementPtr.html
现在,我们可以对PointerOp
做类似的事情,以确保我们实际上使用getelementptr
:
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(PointerOp)) {
// The load takes a GEP instruction, assigned to GEPI
...
}
}
GEP可以采用任意数量的指数。一些索引正在执行字段偏移计算(从结构中选择一个字段),其他索引将执行数组索引。找出你需要添加100到哪些索引(你需要引用类型GEPI->getPointerOperandType()
)。
当实际添加常量100时,请注意GEP索引可能不是常量 - 它可能是另一个IR指令的结果。因此,您需要获取该操作数并将其替换为新的add
指令。
以下内容可能相关:
ConstantInt::get
:http://llvm.org/docs/doxygen/html/classllvm_1_1ConstantInt.html#a9105541412dab869e18b3cceebfff07d BinaryOperator::Create
使用Instruction::Add
操作码:http://llvm.org/docs/doxygen/html/classllvm_1_1BinaryOperator.html#a02ce9966395063ac501ecbc1623deda4 User::setOperand
:http://llvm.org/docs/doxygen/html/classllvm_1_1User.html#a5fa9b8e1842b354f64c1ba6be0a4a17f 值得注意的是Instruction
继承自LLVM域中的User
,User
继承自Value
。