Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Compiler construction 从LLVM IR中删除/替换代码_Compiler Construction_Llvm_Compiler Optimization_Llvm Clang_Llvm Ir - Fatal编程技术网

Compiler construction 从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(用替换所有用法),然后安全地删除

我正在使用LLVM IR代码。我想通过程序从LLVM IR表示中删除指令。描述如何删除,但不太清楚。由于某些正向引用,当我尝试删除时,它会抛出异常

例如:

在这里,我想删除
%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();
}