如何在LLVM IR中更改指令变量?

时间:2015-10-02 12:34:32

标签: c llvm

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)

一般情况下,迭代指令如何

  • 首先识别所有内存读取 - 我必须使用哪些API?
  • 如何更新或者我对它们的常数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指令。

以下内容可能相关:

值得注意的是Instruction继承自LLVM域中的UserUser继承自Value