2013-04-28 48 views
0

我与LLVM合作,将存储指令和替换另一个,这样我可以采取类似从LLVM存储指令使用地址创建另一个

store i64 %0, i64* %a 

,取而代之的是

store i64 <value>, i64* %a 

我用

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

让我的旧指令使用的地址,然后创建一个新的S通过撕(i是当前指令的位置,所以这家店将店里我更换之前创建)

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

我再删除,我用

i->eraseFromParent(); 

但是我更换了店“M收到错误: 虽然删除:DEF被破坏后,I64% 使用还停留各地:商店I64,I64 *%是断言‘使用空’& &使用时的值被破坏仍然会失败 和失败消息。

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

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

回答

1

eraseFromParent从封闭基本块(以及随后的封闭函数)中删除一条指令。它不会将它移动到任何地方。删除的指令,而不考虑它的用途的护理首先会离开你的IR畸形的,这就是为什么你得到错误这种方式 - 就好像你从下面的C代码片段删除线1:

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

显然你将在剩余的线路上出现错误,现在缺失x的定义!

ReplaceInstWithInst可能是将一条指令替换为另一条指令的最佳方式。您不需要为新指令提供一个位置来插入它:只要将指令保留为NULL(或者更好,省略参数),它就会创建一个悬挂指令,然后您可以随时随地放置该指令。

由于以上所述,顺便说一句,ReplaceInstWithInst调用的关键方法是Value::replaceAllUsesWith,这可以确保您的IR不会遗漏值。

+0

哦真棒 - 我刚刚意识到我的问题是我正在删除我的算术运算,而旧的商店仍然引用它,所以我现在忽略它(我想我会在另一个通行证中删除它)。 我已经完成了你所说的;因此,在我创建一个新的商店指令并将其放在我之前之后,我尝试用NULL代替我的旧商店。getInstList(),我,NULL) 我得到一个堆栈转储...如果我注释掉ReplaceIwithI我可以看到我有我的新商店(除了旧的商店和添加)。我是否使用替换错误? – winepretzel 2013-04-28 15:28:43

+0

我似乎无法得到那个工作 - 在我的代码中,在我忽略了算术操作之后,我用++ i增加了我的指令指针,然后用它来创建我的新商店。如果我停在那里,我的代码有算术运算,新商店和旧商店。然而,如果我尝试在创建新商店后调用'code'eraseFromParent'code'或'code'ReplaceInstWithInst'code',我会得到堆栈转储。我觉得我在这里错过了一些东西。 – winepretzel 2013-04-28 15:55:47

+0

@winepretzel我的意思是你应该使用NULL作为StoreInst构造函数的位置参数 - 这样它就不会与任何位置关联。 – Oak 2013-04-28 19:17:21