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

How to alter instruction variables in LLVM IR?

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)

一般来说,在迭代指令时如何

假设你有一个 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 指令。

以下可能是相关的:

注意在 LLVM 领域 Instruction 继承自 User 并且 User 继承自 Value.

可能是有用的