Delete/Replace 来自 LLVM IR 的代码

Delete/Replace Code from LLVM IR

我正在使用 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被第二条指令引用,所以抛出异常。
ReplaceInstWithValueReplaceInstWithInst说明,但是从官方文档看不清楚用法

如何做到这一点?谁能帮我举个例子。

您可能想要做的是首先对 %add2 进行 RAUW(将所有使用替换为),然后您可以安全地删除添加指令。

例如,如果您知道上面相加的结果是一个常量(假设您正在编写一个常量传播传递),那么如果您有一个值 *CI 和您的指令 *I 你可以:

I->replaceAllUsesWith(CI)
I->eraseFromParent()

希望对您有所帮助。

当您有两个具有相同 llvm:Type 的指令时,您可以使用 ReplaceInstWithInst 函数。

例如,如果您的 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();
} 

但是你可以认为这个函数不安全。它假定所有用户都是指令。如果您有引用指令的元数据,这可能会中断,但您应该明白这一点。