Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
LLVM后端只能将2个alloca升级到寄存器,即使存在未使用的物理寄存器_Llvm - Fatal编程技术网

LLVM后端只能将2个alloca升级到寄存器,即使存在未使用的物理寄存器

LLVM后端只能将2个alloca升级到寄存器,即使存在未使用的物理寄存器,llvm,Llvm,我在一个CPU仿真器项目中使用MCJIT,IR主要是使用IRBuilder生成的,它可以工作,但是性能比我们以前的JIT差。我比较了生成的代码,主要问题与寄存器的使用有关。在LLVM中,我通过将alloca放在IR函数的开头,将5个局部变量提升到寄存器,在运行createPromoteMemoryToRegisterPass后,所有5个变量都提升到优化IR中具有PHI节点的虚拟寄存器。但在最终的X64二进制代码中,只有2个变量升级到寄存器,其他3个变量溢出。代码中还有两个寄存器未使用R11、R1

我在一个CPU仿真器项目中使用MCJIT,IR主要是使用IRBuilder生成的,它可以工作,但是性能比我们以前的JIT差。我比较了生成的代码,主要问题与寄存器的使用有关。在LLVM中,我通过将alloca放在IR函数的开头,将5个局部变量提升到寄存器,在运行createPromoteMemoryToRegisterPass后,所有5个变量都提升到优化IR中具有PHI节点的虚拟寄存器。但在最终的X64二进制代码中,只有2个变量升级到寄存器,其他3个变量溢出。代码中还有两个寄存器未使用R11、R12

我尝试使用llc用贪婪/pbqp编译优化的IR,结果是一样的,只有2个得到提升

我在这个问题上花了很多时间,任何建议都将不胜感激

代码段:

优化前的IR:

define void @emulate(%struct.fpga_cpu* %pcpu, i64 %pc_arg, i64 %r0_arg, i64 %r1_arg, i64 %r2_arg, i64 %r3_arg) {
entry:
  %0 = alloca i64
  %1 = alloca i64
  %2 = alloca i64
  %3 = alloca i64
  %4 = alloca i64
  %5 = alloca i64
  store i64 %r0_arg, i64* %2
  store i64 %r1_arg, i64* %3
  store i64 %r2_arg, i64* %4
  store i64 %r3_arg, i64* %5
  store i64 %pc_arg, i64* %0
....
}
  define void @emulate(%struct.fpga_cpu* %pcpu, i64 %pc_arg, i64 %r0_arg, i64 %r1_arg, i64 %r2_arg, i64 %r3_arg) {
....
  %.01662 = phi i64 [ %r2_arg, %entry ], [ %.21664, %cmp ]
  %.01648 = phi i64 [ %r1_arg, %entry ], [ %.21650, %cmp ]
  %.01640 = phi i64 [ %r0_arg, %entry ], [ %.21642, %cmp ]
  %.01636 = phi i64 [ %r3_arg, %entry ], [ %.21638, %cmp ]
  %.0 = phi i64 [ %pc_arg, %entry ], [ %.2, %cmp ]
....
}
优化后的IR:

define void @emulate(%struct.fpga_cpu* %pcpu, i64 %pc_arg, i64 %r0_arg, i64 %r1_arg, i64 %r2_arg, i64 %r3_arg) {
entry:
  %0 = alloca i64
  %1 = alloca i64
  %2 = alloca i64
  %3 = alloca i64
  %4 = alloca i64
  %5 = alloca i64
  store i64 %r0_arg, i64* %2
  store i64 %r1_arg, i64* %3
  store i64 %r2_arg, i64* %4
  store i64 %r3_arg, i64* %5
  store i64 %pc_arg, i64* %0
....
}
  define void @emulate(%struct.fpga_cpu* %pcpu, i64 %pc_arg, i64 %r0_arg, i64 %r1_arg, i64 %r2_arg, i64 %r3_arg) {
....
  %.01662 = phi i64 [ %r2_arg, %entry ], [ %.21664, %cmp ]
  %.01648 = phi i64 [ %r1_arg, %entry ], [ %.21650, %cmp ]
  %.01640 = phi i64 [ %r0_arg, %entry ], [ %.21642, %cmp ]
  %.01636 = phi i64 [ %r3_arg, %entry ], [ %.21638, %cmp ]
  %.0 = phi i64 [ %pc_arg, %entry ], [ %.2, %cmp ]
....
}
X64代码:

emulate:                         
pushq   %rbp
pushq   %r15
pushq   %r14
pushq   %r13
pushq   %r12
pushq   %rbx
subq    $72, %rsp
movq    %r9, 56(%rsp)           # 8-byte Spill
movq    %r8, 64(%rsp)           # 8-byte Spill
movq    %rcx, %r15
movq    %rdx, %r13
movq    %rdi, %r14    
....
r2_arg, r3_arg spill, but R11,R12 are never used.
....
retq    

我相信一个小的可复制的例子可以让你的问题更容易理解。很抱歉我的问题含糊不清,由于公司的政策,我不能在这里发布工作代码。这里的基本思想是让模拟CPU的寄存器变量存在于X64寄存器中。