我正在使用LLVM IR代码。我想通过程序从LLVM IR表示中删除指令。 LLVM Official documentation描述了如何删除,但不是那么清楚。由于一些前向引用,当我尝试删除时,它会抛出异常。
例如:
`%add2 = add nsw i32 %4, %5`
`store i32 %add2, i32* %b, align 4 `
在这里,我想删除%add2 = add nsw i32 %4, %5
指令,但它会引发异常,因为%add2
被第二条指令引用。
有ReplaceInstWithValue
和ReplaceInstWithInst
说明,但官方文档中的用法并不明确。
怎么做?任何人都可以帮我一些例子。
答案 0 :(得分:1)
如果有两条带有相同llvm的指令,则可以使用ReplaceInstWithInst函数:Type。
例如,如果您的BinaryOperator*
导致%add2 = add nsw i32 %4, %5
,则可以执行以下操作:
auto& ctx = getGlobalContext();
auto newAdd = BinaryOperator::CreateAdd(
ConstantInt::get(cast<Type>(Type::getInt32Ty(ctx)), APInt(32, 42)),
ConstantInt::get(cast<Type>(Type::getInt32Ty(ctx)), APInt(32, -42)));
ReplaceInstWithInst(oldAdd, newAdd);
如果您只是想从IR中删除指令(可能是使用它的所有内容),则替换为UndefValue
执行RAUW:
oldAdd->replaceAllUsesWith(UndefValue::get(oldAdd->getType()));
oldAdd->eraseFromParent();
这会产生类似:store i32 undef, i32* %b, align 4
的内容,可能会被优化过程删除。
如果你想删除商店,你必须递归所有用户的指示:
void replaceAndErase(Instruction& I) {
for (auto& U : I.users()) {
replaceAndErase(*UI);
}
I.replaceAllUsesWith(UndefValue::get(I.getType()));
I.eraseFromParent();
}
但是你可以认为这个功能不安全。它假定所有用户都是指令。如果您有元数据引用指令,这可能会中断,但您应该明白这一点。
答案 1 :(得分:0)
您可能想要做的是首先使用%add2的RAUW(替换所有用途),然后您可以安全地删除添加指令。
例如,如果你知道上面添加的结果是一个常数(比如说你正在写一个常量传播传递),那么如果你有一个Value * CI和你的指令* I你可以:
I->replaceAllUsesWith(CI)
I->eraseFromParent()
希望有所帮助。