如何更改 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)
。
一般来说,在迭代指令时如何
- 首先确定所有内存读取 - 我必须使用哪些 API?
- 如何更新或我的常数 100 添加到所有这些?
假设你有一个 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
注意在 LLVM 领域 Instruction
继承自 User
并且 User
继承自 Value
.
可能是有用的
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 添加到所有这些?
假设你有一个 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#a9105541412dab869e18b3cceebfff07dBinaryOperator::Create
与Instruction::Add
操作码:http://llvm.org/docs/doxygen/html/classllvm_1_1BinaryOperator.html#a02ce9966395063ac501ecbc1623deda4User::setOperand
: http://llvm.org/docs/doxygen/html/classllvm_1_1User.html#a5fa9b8e1842b354f64c1ba6be0a4a17f
注意在 LLVM 领域 Instruction
继承自 User
并且 User
继承自 Value
.