在使用LLVM编译时,有没有办法避免删除重复的加载指令

在使用LLVM编译时,有没有办法避免删除重复的加载指令,llvm,llc,Llvm,Llc,我正在创建LLVM前端模块通道。所以,基本上我需要复制所有加载指令并存储在不同的寄存器中。对于clang、opt和llc工具,在-O0处删除此重复加载指令。我使用objdump查看了最终组装,我可以看到重复的加载指令被删除了。我想要一个不删除重复加载指令的解决方案 实际的C程序是 intmain(){ int*p=(int*)(0x600000);//某个地址 int x=0x01,y=0x01; intz; z=x+y; *p=z; } 相应的IR是 define i32@main()#0{

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

实际的C程序是

intmain(){
int*p=(int*)(0x600000);//某个地址
int x=0x01,y=0x01;
intz;
z=x+y;
*p=z;
}
相应的IR是

define i32@main()#0{
条目:
%p=alloca i32*,对齐8
%x=alloca i32,对齐4
%y=alloca i32,对齐4
%z=alloca i32,对齐4
存储i32*inttoptr(i64 6291456到i32*),i32**%p,对齐8
存储i32 1,i32*%x,对齐4
存储i32 1,i32*%y,对齐4
%0=加载i32,i32*%x,对齐4
%1=加载i32,i32*%y,对齐4
%添加=添加新南威尔士州i32%0,%1
存储i32%添加,i32*%z,对齐4
%2=加载i32,i32*%z,对齐4
%3=负载i32*,i32**%p,对齐8
存储i32%2,i32*%3,对齐4
ret i32 0
}
但当我的pass被启用时,这个IR将改变,我只复制加载地址为相同内存的加载指令,即使是对于复制的加载也是如此

改变后的IR是

define i32@main()#0{
条目:
%p=alloca i32*,对齐8
%x=alloca i32,对齐4
%y=alloca i32,对齐4
%z=alloca i32,对齐4
存储i32*inttoptr(i64 6291456到i32*),i32**%p,对齐8
存储i32 1,i32*%x,对齐4
存储i32 1,i32*%y,对齐4
%0=加载i32,i32*%x,对齐4
%1=加载i32,i32*%y,对齐4
%2=加载i32,i32*%x,对齐4//已添加
%3=加载i32,i32*%y,对齐4//已添加
%添加=添加新南威尔士州i32%0,%1
存储i32%添加,i32*%z,对齐4
%4=加载i32,i32*%z,对齐4
%5=负载i32*,i32**%p,对齐8
%6=加载i32,i32*%z,对齐4//已添加
%7=加载i32*,i32**%p,对齐8//已添加
存储i32%4,i32*%5,对齐4
ret i32 0
}
我能够在IR级别看到已更改的IR,但在llc之后在最终装配级别看不到。我认为llc正在移除所有重复负载。如何阻止llc删除


注意:我试图使所有变量都不稳定。为此,我可以在llc之后看到重复的负载。但是,这不是一个合适的解决方案。我不能让所有的变量都不稳定:(.

让所有变量都变为易变的听起来像是一个简单的搜索和替换,而
volatile
是对你想要的语义的准确描述。是的,我已经这样做了。但是,你认为除了让变量变为易变的之外还有什么别的方法吗。也许,如果你解释一下你想要什么以及它与使用易变变量有什么不同。编程l语言(perl除外)对于每个目标往往只有一种机制。我认为,删除这些指令是因为它们未使用。尝试以某种方式“使用”它们。我使用了。即使这样,它也会被删除。编译器在偶数-O0级别上足够聪明,可以删除重复的负载。