使用来自LLVM存储的地址指令创建另一个

使用来自LLVM存储的地址指令创建另一个,llvm,Llvm,我正在与LLVM合作,获取一条存储指令,并将其替换为另一条指令,这样我就可以 store i64 %0, i64* %a 并将其替换为 store i64 <value>, i64* %a 获取旧指令正在使用的地址,然后通过创建一个新的存储(我是当前指令位置,因此此存储将在替换存储之前创建) 然后,我删除已替换为的存储 i->eraseFromParent(); 但我得到了一个错误: 删除时:i64% 销毁Def后仍在使用:存储i64,i64*%a 当值被销毁时,断言“u

我正在与LLVM合作,获取一条存储指令,并将其替换为另一条指令,这样我就可以

store i64 %0, i64* %a
并将其替换为

store i64 <value>, i64* %a
获取旧指令正在使用的地址,然后通过创建一个新的存储(我是当前指令位置,因此此存储将在替换存储之前创建)

然后,我删除已替换为的存储

i->eraseFromParent();
但我得到了一个错误: 删除时:i64% 销毁Def后仍在使用:存储i64,i64*%a 当值被销毁时,断言“use empty”&&使用的失败消息仍然存在

我怎样才能避开这件事?我希望创建一条存储指令,然后使用LLVM的ReplaceInstWithInst,但如果不给它一个插入自身的位置,我找不到创建存储指令的方法。我也不是100%能解决我的问题


我要补充的是,在替换存储之前,我正在匹配指令I,然后在执行I->eraseFromParent之前获得所需的值,所以我不确定这是否是我的问题的一部分;我假设eraseFromParent将I移动到下面的存储指令。

eraseFromParent
从封闭的基本块(从而从封闭函数)中删除指令。它不会移动到任何地方。以这种方式删除指令而不首先考虑其用途将导致IR格式不正确,这就是为什么会出现错误-就好像从以下C代码段中删除了第1行:

1   int x = 3;
2   int y = x + 1;
显然,您将在剩下的一行中得到一个错误,
x
的定义现在丢失了

ReplaceInstWithInst
可能是将一条指令替换为另一条指令的最佳方法。您不需要为新指令提供插入它的位置:只需将指令保留为NULL(或者更好的是,省略参数),它将创建一条悬空指令,然后您可以将其放置在任何需要的地方


由于上述原因,顺便说一句,
ReplaceInstWithInst
调用的关键方法是
Value::replaceAlluseWith
,这可以确保您的IR中不会丢失值。

哦,太棒了-我刚刚意识到我的问题是,我正在删除算术运算,而旧存储仍然引用它,所以我现在忽略它(我想我会在另一个过程中删除它)。我已经照你说的做了;因此,在我创建了一个新的存储指令并将其放在我之前之后,我尝试用NULL a la ReplaceInstWithInst(BB.getInstList(),I,NULL)替换我的旧存储,然后我得到一个堆栈转储。。。如果我对替换内容进行注释,我可以看到我有了新的存储(除了旧存储和添加)。我是否使用了替换错误?我似乎无法让它工作-在我的代码中,在忽略算术运算后,我用++I递增指令指针,然后用它创建新的存储。如果我停在那里,我的代码有算术运算、新存储和旧存储。但是,如果在创建新存储后,我尝试在I上调用
code
erasefrompent
code
code
ReplaceInstWithInst
code
,我会得到一个堆栈转储。我觉得这里缺少了一些东西。@winepretzel我的意思是应该使用NULL作为
StoreInst
构造函数的位置参数-这样它就不会与任何位置关联。
i->eraseFromParent();
1   int x = 3;
2   int y = x + 1;