2017-09-08 113 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中引入顯式存儲和加載。

相關問題