2017-09-08 62 views
0

我变换以下LLVM-IR理解LLVM-IR至组件,用于x86_64的未知-Linux的GNU

; Function Attrs: noinline norecurse nounwind uwtable 
define i32 @main() #0{ 
entry: 
%sub = sub nsw i32 5, 3 
%cmp = icmp slt i32 %sub, 3 
br i1 %cmp, label %if.then, label %if.else 

if.then:           ; preds = %entry 
%mul = mul nsw i32 %sub, 2 
br label %if.end 

if.else:           ; preds = %entry 
%sub1 = sub nsw i32 %sub, 3 
br label %if.end 

if.end:           ; preds = %if.else, 
%if.then 
%y.0 = phi i32 [ %mul, %if.then ], [ %sub1, %if.else ] 
%sub2 = sub nsw i32 %sub, %y.0 
%add = add nsw i32 %sub, %y.0 
ret i32 0 
} 

到汇编代码用于使用llc sample.ll 生成的汇编代码x86_64-unknown-linux-gnu

.text 
    .file "phi.cpp" 
    .globl main     # -- Begin function main 
    .p2align  4, 0x90 
    .type main,@function 
main:         # @main 
    .cfi_startproc 
# BB#0:         # %entry 
    pushq %rbp 
.Lcfi0: 
    .cfi_def_cfa_offset 16 
.Lcfi1: 
    .cfi_offset %rbp, -16 
    movq %rsp, %rbp 
.Lcfi2: 
    .cfi_def_cfa_register %rbp 
    xorl %eax, %eax 
    testb %al, %al 
    xorl %eax, %eax 
    popq %rbp 
    retq 
.Lfunc_end0: 
    .size main, .Lfunc_end0-main 
    .cfi_endproc 
            # -- End function 

上述代码中的寄存器:%rbp是基指针,它指向当前堆栈帧的底部,而%rsp是堆栈指针,它指向顶部o F中的当前堆栈帧和操作数是店%eax%al为arithmatic操作,但在找不到指令,其中的值是负载%eax%al寄存器 我也想知道

  1. 如何LLC正在处理组装级别的phi节点

回答

1

lli默认为-O2并且您的代码以常量表达式sub nsw i32 5, 3开头。因此,你的函数基本上什么都不做,LLVM应该保留的唯一东西就是使EAX无效。

如果你运行lli -O0 your.ll,你会得到很多详细的代码,执行堆栈和寄存器加载溢出。

顺便说一句,有一对通行证称为mem2regreg2mem,它们将来自SSA表单的代码来回转换。具体而言,这些通行证会将phi节点转换为分支,并在IR中引入显式存储和加载。

相关问题