使用LLVM

时间:2019-01-31 11:59:07

标签: llvm llc

我正在创建LLVM前端模块通道。因此,基本上,我需要复制所有加载指令并将其存储在其他寄存器中。对于clang,opt和llc工具,在-O0处删除了此重复的加载指令。我使用objdump查看了最终程序集,可以看到删除了重复的加载指令。我想要一个不删除重复加载指令的解决方案。

实际的C程序是

int main(){
    int* p = (int *)(0x600000);//Some address
    int x=0x01, y=0x01;
    int z;
    z=x+y;
    *p=z;
}

相应的IR是

define i32 @main() #0 {
entry:
  %p = alloca i32*, align 8
  %x = alloca i32, align 4
  %y = alloca i32, align 4
  %z = alloca i32, align 4
  store i32* inttoptr (i64 6291456 to i32*), i32** %p, align 8
  store i32 1, i32* %x, align 4
  store i32 1, i32* %y, align 4
  %0 = load i32, i32* %x, align 4
  %1 = load i32, i32* %y, align 4
  %add = add nsw i32 %0, %1
  store i32 %add, i32* %z, align 4
  %2 = load i32, i32* %z, align 4
  %3 = load i32*, i32** %p, align 8
  store i32 %2, i32* %3, align 4
  ret i32 0
}

但是,启用通行证后,此IR将会更改,并且即使重复加载,我也只能复制加载地址为相同内存的加载指令。

更改后的IR为

define i32 @main() #0 {
entry:
  %p = alloca i32*, align 8
  %x = alloca i32, align 4
  %y = alloca i32, align 4
  %z = alloca i32, align 4
  store i32* inttoptr (i64 6291456 to i32*), i32** %p, align 8
  store i32 1, i32* %x, align 4
  store i32 1, i32* %y, align 4
  %0 = load i32, i32* %x, align 4
  %1 = load i32, i32* %y, align 4
  %2 = load i32, i32* %x, align 4 //Added
  %3 = load i32, i32* %y, align 4 //Added
  %add = add nsw i32 %0, %1
  store i32 %add, i32* %z, align 4
  %4 = load i32, i32* %z, align 4
  %5 = load i32*, i32** %p, align 8
  %6 = load i32, i32* %z, align 4 //Added
  %7 = load i32*, i32** %p, align 8        //Added
  store i32 %4, i32* %5, align 4
  ret i32 0
}

在llc之后,我能够在IR级别看到已更改的IR,但在最终装配级别却看不到。我认为llc正在删除所有重复的负载。如何阻止llc移除?

注意:我尝试使所有变量都可变。为此,我可以在llc后看到重复的负载。但是,这不是一个适当的解决方案。我不能使所有的数千个变量都是volatile:(。

0 个答案:

没有答案