我有llvm IR代码,比如:
%0 = load i32* %b, align 4
%mul = mul nsw i32 %0, 1
我想用负载替换第二条指令:%mul = load i32* %0, align4
所以我使用以下代码:
new LoadInst(op1, "mul", x);
其中x是指向我希望替换的指令的指针(指令*),值*op1=x->getOperand(0);
在x之前插入该指令之后,我擦除x(当前指令)。当我运行它时,这里会出现错误。我觉得我没有提出正确的论点。
PS:我不允许使用实用程序类进行更改。
您正在做的事情有两个问题。
首先,如果这是您的目标代码,则它是非法的:
%0 = load i32* %b, align 4
%mul = load i32* %0, align 4
由于%0
的类型是i32
,但在负载中,您假定它是i32*
。
第二步,用另一条指令替换一条指令的正确方法是使用ReplaceInstWithInst
(位于BasicBlockUtils.h),因为它还会更新旧指令的所有用户以使用新指令。
为了澄清为什么你的方法不起作用,这里有一个演示(忽略类型问题):
%0 = load i32* %b, align 4
%mul = mul nsw i32 %0, 1
ret i32 %mul
现在运行new LoadInst(op1, "mul", x);
并获得:
%0 = load i32* %b, align 4
%mul = load i32* %0, align 4
%mul.1 = mul nsw i32 %0, 1
ret i32 %mul.1
为什么要将第二条指令从%mul
重命名为%mul.1
?我没有;均命名为CCD_ 9。但是,当您打印出来时,打印机会将.<serial number>
附加到共享相同作用域和名称的所有指令中,以防止混淆。
不用添加,删除后你会得到这个:
%0 = load i32* %b, align 4
%mul = load i32* %0, align 4
ret i32 %mul.1
并且CCD_ 11是指一个缺失的值。
简言之,您不能依赖指令名称来做任何事情,它只是为了帮助调试并使IR的文本表示更可读。