我在CPU模拟器项目中使用MCJIT,IR主要使用IRBuilder生成并且可以正常工作,但性能比旧的JIT差。我比较了生成的代码,主要问题与寄存器使用有关。在LLVM中,我通过在IR函数的开头放置allocas将5个局部变量提升为寄存器,在运行“createPromoteMemoryToRegisterPass”之后,所有5个变量都被提升为具有优化IR中的PHI节点的虚拟寄存器。但在最终的X64二进制代码中,只有2个变量被提升为寄存器,另外3个溢出。在代码中仍然有2个寄存器未使用(R11,R12)。
我尝试使用llc用greedy / 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
....
}
优化后的IR:
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