0

我正在与 LLVM 合作以获取存储指令并将其替换为另一个指令,以便我可以使用类似的东西

store i64 %0, i64* %a

并将其替换为

store i64 <value>, i64* %a

我用过

llvm::Value *str = i->getOperand(1);

获取我的旧指令正在使用的地址,然后我通过创建一个新存储(我是当前指令位置,所以这个存储将在我要替换的存储之前创建)

StoreInstr *store = new StoreInst(value, str, i);

然后我删除了我已经替换的商店

i->eraseFromParent();

但是我收到错误消息:删除时:i64% Use 在 Def 被销毁后仍然卡住: store i64 , i64* %a 和 Assertion “use empty” && 使用的失败消息在值被销毁失败时仍然存在。

我怎么能解决这个问题?我很想创建一个存储指令,然后使用 LLVM 的 ReplaceInstWithInst,但是我找不到一种方法来创建存储指令而不给它一个插入自身的位置。我也不是 100% 会解决我的问题。

我会在更换商店之前添加它,我匹配一条指令 i,然后在执行 i->eraseFromParent 之前获取我需要的值,所以我不确定这是否是我的问题的一部分;我假设 eraseFromParent 将 i 移动到以下存储指令。

4

1 回答 1

1

eraseFromParent从封闭的基本块中删除一条指令(因此,从封闭的函数中)。它不会将它移动到任何地方。以这种方式擦除指令而不首先考虑其使用会使您的 IR 格式错误,这就是您收到错误的原因 - 就好像您从以下 C 代码段中删除了第 1 行:

1   int x = 3;
2   int y = x + 1;

显然你会在剩下的那行得到一个错误,x现在缺少定义了!

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

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

于 2013-04-28T15:21:06.257 回答