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
被第二条指令引用,所以抛出异常。
有ReplaceInstWithValue
和ReplaceInstWithInst
说明,但是从官方文档看不清楚用法
如何做到这一点?谁能帮我举个例子。
您可能想要做的是首先对 %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();
}
但是你可以认为这个函数不安全。它假定所有用户都是指令。如果您有引用指令的元数据,这可能会中断,但您应该明白这一点。
我正在使用 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
说明,但是从官方文档看不清楚用法
如何做到这一点?谁能帮我举个例子。
您可能想要做的是首先对 %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();
}
但是你可以认为这个函数不安全。它假定所有用户都是指令。如果您有引用指令的元数据,这可能会中断,但您应该明白这一点。