Compiler construction 从LLVM IR中删除/替换代码
我正在使用LLVM IR代码。我想通过程序从LLVM IR表示中删除指令。描述如何删除,但不太清楚。由于某些正向引用,当我尝试删除时,它会抛出异常 例如: 在这里,我想删除Compiler construction 从LLVM IR中删除/替换代码,compiler-construction,llvm,compiler-optimization,llvm-clang,llvm-ir,Compiler Construction,Llvm,Compiler Optimization,Llvm Clang,Llvm Ir,我正在使用LLVM IR代码。我想通过程序从LLVM IR表示中删除指令。描述如何删除,但不太清楚。由于某些正向引用,当我尝试删除时,它会抛出异常 例如: 在这里,我想删除%add2=add nsw i32%4,%5指令,但它引发异常,因为第二条指令引用了%add2。 有replaceinswithvalue和replaceinswithinst说明,但是官方文档中没有明确的用法 如何做到这一点?有人能帮我举一些例子吗。您可能想做的是首先对%add2进行RAUW(用替换所有用法),然后安全地删除
%add2=add nsw i32%4,%5
指令,但它引发异常,因为第二条指令引用了%add2
。有
replaceinswithvalue
和replaceinswithinst
说明,但是官方文档中没有明确的用法
如何做到这一点?有人能帮我举一些例子吗。您可能想做的是首先对%add2进行RAUW(用替换所有用法),然后安全地删除add指令 例如,如果您知道上述加法的结果是一个常量(假设您正在编写一个常量传播过程),那么如果您有一个值*CI和指令*I,您可以:
I->replaceAllUsesWith(CI)
I->eraseFromParent()
希望对您有所帮助。如果有两条指令具有相同的llvm:Type,您可以使用ReplaceInstWithInst函数 例如,如果您的
二进制运算符*
导致%add2=添加新南威尔士州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);
这将导致如下结果:存储i32未定义、i32*%b、align 4
,并可能通过优化过程删除
如果您还想删除存储,则必须通过所有使用说明的用户递归地执行此操作:
void replaceAndErase(Instruction& I) {
for (auto& U : I.users()) {
replaceAndErase(*UI);
}
I.replaceAllUsesWith(UndefValue::get(I.getType()));
I.eraseFromParent();
}
<>但是你可以认为这个函数不安全。它假定所有用户都是指令。如果您有元数据引用指令,这可能会中断,但您应该了解这一点 如果结果不是常数怎么办?我可以用任何其他临时名称替换
%add2
,比如tempadd
?如果可能的话,我该怎么做?任何值都可以通过这种方式替换,如果您查看RAUW的代码和相关注释:///\brief Change all use of this指向一个新值浏览此定义的使用列表,并使每个使用点指向//“V”而不是“this”。完成此操作后,“this的使用列表///保证为空。无效替换为(值*V);您可以使用完全不同的添加、加载的结果或任何其他内容替换您的添加。
oldAdd->replaceAllUsesWith(UndefValue::get(oldAdd->getType()));
oldAdd->eraseFromParent();
void replaceAndErase(Instruction& I) {
for (auto& U : I.users()) {
replaceAndErase(*UI);
}
I.replaceAllUsesWith(UndefValue::get(I.getType()));
I.eraseFromParent();
}