我是LLVM的新手,我正在做一些实验,比如插入一条指令。
我的main.c
如下所示:
int foo(int e, int a) {
int b = a + 1;
int c = b * 2;
b = e << 1;
int d = b / 4;
return c * d;
}
我使用下面的命令生成LLVM字节码
clang-12 -O0 -Xclang -disable-O0-optnone -emit-llvm -c main.c -o main.bc
opt-12 -S -mem2reg main.bc -o main.ll
字节码是
; Function Attrs: noinline nounwind uwtable
define dso_local i32 @foo(i32 %0, i32 %1) #0 {
%3 = add nsw i32 %1, 1
%4 = mul nsw i32 %3, 2
%5 = shl i32 %0, 1
%6 = sdiv i32 %5, 4
%7 = mul nsw i32 %4, %6
ret i32 %7
}
我使用代码在第一条指令后插入一条指令:
bool runOnBasicBlock(BasicBlock &B) {
// get the first and second instruction
Instruction &Inst1st = *B.begin();
Instruction *NewInst = BinaryOperator::Create(
Instruction::Add, Inst1st.getOperand(0), Inst1st.getOperand(0));
NewInst->insertAfter(&Inst1st);
...
}
在我运行此遍之后,字节码将更改为
; Function Attrs: noinline nounwind uwtable
define dso_local i32 @foo(i32 %0, i32 %1) #0 {
%3 = add nsw i32 %1, 1
%4 = add i32 %1, %1
%5 = mul nsw i32 %4, 2
%6 = shl i32 %0, 1
%7 = sdiv i32 %6, 4
%8 = mul nsw i32 %5, %7
ret i32 %8
}
插入的指令好像是b = a + a;
,所以指令%4 = mul nsw i32 %3, 2
变成了%5 = mul nsw i32 %4, 2
,我不明白原因,有帮助吗?
2条答案
按热度按时间fykwrbwg1#
据我所知,
NewInst->insertAfter(&Inst1st);
从块中生成以下块
因此,
b
丢弃先前值%3
并获得新值%4
,并且进一步mul
使用b
的新值。zpqajqem2#
我无法复制您的输出字节码,您是否忘记了什么?
这个问题让我很好奇,我自己也试了一下。
我使用了与问题中相同的c文件,并使用相同的命令来生成LLVM字节码,唯一的区别是我使用了LLVM 16。
正如预期的那样,我得到了与您相同的初始字节码:
我使用您提供的代码编写了以下函数pass,以便在第一条指令之后插入add指令:
然后我通过上面的函数传递运行字节码,但我得到的结果与你的不同:
我的结果字节码,与你的类似,在第一条指令之后包含新的add指令,但是尽管你输出了字节码,这个新的add指令的结果并没有取代下一条指令中变量
b
的使用。