2017-02-03 117 views
0

我想看到一個非常簡單的循環的IRLLVM如何O2優化

for (int i = 0; i < 15; i++){ 
    a[b[i]]++; 
} 

同時使用-O0和潛水到.ll文件編譯,我可以通過一步看一步的書面說明define i32 @main()功能。但是,使用-O2編譯並查看.ll文件時,define i32 @main()函數中只有ret i32 0。並且由-O0編譯的.ll文件中顯示的一些call指令在由-O2編譯的.ll文件中更改爲tail call

任何人都可以提供一個相當詳細的解釋如何llvm做-O2編譯?謝謝。

牛逼

+0

如果您想逐步查看優化,請嘗試:'clang -mllvm -print-after-all' – Joky

回答

0

我們可以使用編譯器Explorer訪問godbolt.org看你的例子。我們將使用下面的測試平臺代碼:

int test() { 
    int a[15] = {0}; 
    int b[15] = {0}; 

    for (int i = 0; i < 15; i++){ 
    a[b[i]]++; 
    } 

    return 0; 
} 

Godbolt顯示x86彙編,不是LLVM字節碼,但我總結了一點,以顯示這是怎麼回事。這是在-O0 -m32

test():        
     # set up stack 
.LBB0_1:         
     cmp  dword ptr [ebp - 128], 15   # i < 15? 
     jge  .LBB0_4        # no? then jump out of loop 
     mov  eax, dword ptr [ebp - 128]   # load i 
     mov  eax, dword ptr [ebp + 4*eax - 124] # load b[i] 
     mov  ecx, dword ptr [ebp + 4*eax - 64] # load a[b[i]] 
     add  ecx, 1        # increment it 
     mov  dword ptr [ebp + 4*eax - 64], ecx # store it back 
     mov  eax, dword ptr [ebp - 128] 
     add  eax, 1        # increment i 
     mov  dword ptr [ebp - 128], eax 
     jmp  .LBB0_1        # repeat 
.LBB0_4: 
     # tear down stack 
     ret 

這看起來像我們預期:環清晰可見,它所有我們列出的步驟。如果我們編譯在,我們看到了循環仍然存在,但它的簡單得多:

test():        # @test() 
     # set up stack 
.LBB0_1:        
     mov  ecx, dword ptr [esp + 4*eax] # load b[i] 
     inc  dword ptr [esp + 4*ecx + 60] # increment a[b[i]] 
     inc  eax        # increment i 
     cmp  eax, 15       # compare == 15 
     jne  .LBB0_1       # no? then loop 
     # tear down stack 
     ret 

鏘現在使用inc指令(有用的),發現它可以使用eax寄存器循環計數器i(純) ,並將條件檢查移到循環的底部(可能更好)。不過,我們仍然可以識別我們的原始代碼。現在讓我們試試-O2 -m32 -march=i386

test():        
     xor  eax, eax # does nothing 
     ret 

就是這樣嗎?是。

clang檢測到a數組永遠不能在函數之外使用。這意味着執行增量操作不會影響程序的其他任何部分 - 也不會在程序失效時錯過它。

刪除增量會留下一個for循環,其中包含一個空體並且沒有副作用,也可以將其刪除。反過來,去除循環留下了(爲了所有意圖和目的)空函數。

這個空函數可能是你在LLVM字節碼中看到的(ret i32 0)。


這並不是一個非常科學的描述,clang花費可能會有所不同的步驟,但我希望示例清除它一點。如果你願意,你可以在as-if rule上閱讀。例如,我還建議在https://godbolt.org/附近玩一下:看看將ab移到該函數外面會發生什麼。

0

不同的開關指定在LLVM IR上運行的不同轉換通道組。您可以使用opt工具上的開關--debug-pass=Structure查看通行證列表。

例如,我的機器上打印opt -O0 test.ll --debug-pass=Structure >> /dev/null/到stderr:

Pass Arguments: -tti -verify Target Transform Information FunctionPass Manager Module Verifier Pass Arguments: -targetlibinfo -tti -assumption-cache-tracker -profile-summary-info -forceattrs -basiccg -always-inline -barrier -verify -print-module Target Library Information Target Transform Information Assumption Cache Tracker Profile summary info ModulePass Manager Force set function attributes CallGraph Construction Call Graph SCC Pass Manager Inliner for always_inline functions A No-Op Barrier Pass FunctionPass Manager Module Verifier Print module to stderr

opt -O3 test.ll --debug-pass=Structure >> /dev/null/

Pass Arguments: -tti -tbaa -scoped-noalias -assumption-cache-tracker -targetlibinfo -verify -simplifycfg -domtree -sroa -early-cse -basicaa -aa -memdep -memoryssa -gvn-hoist -lower-expect Target Transform Information Type-Based Alias Analysis Scoped NoAlias Alias Analysis Assumption Cache Tracker Target Library Information FunctionPass Manager Module Verifier Simplify the CFG Dominator Tree Construction SROA Early CSE Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Memory Dependence Analysis Memory SSA Early GVN Hoisting of Expressions Lower 'expect' Intrinsics Pass Arguments: -targetlibinfo -tti -tbaa -scoped-noalias -assumption-cache-tracker -profile-summary-info -forceattrs -inferattrs -ipsccp -globalopt -domtree -mem2reg -deadargelim -domtree -basicaa -aa -instcombine -simplifycfg -pgo-icall-prom -basiccg -globals-aa -prune-eh -inline -functionattrs -domtree -sroa -early-cse -speculative-execution -lazy-value-info -jump-threading -correlated-propagation -simplifycfg -domtree -basicaa -aa -instcombine -libcalls-shrinkwrap -tailcallelim -simplifycfg -reassociate -domtree -loops -loop-simplify -lcssa-verification -lcssa -basicaa -aa -scalar-evolution -loop-rotate -licm -loop-unswitch -simplifycfg -domtree -basicaa -aa -instcombine -loops -loop-simplify -lcssa-verification -lcssa -scalar-evolution -indvars -loop-idiom -loop-deletion -loop-unroll -mldst-motion -aa -memdep -lazy-branch-prob -lazy-block-freq -opt-remark-emitter -gvn -basicaa -aa -memdep -memcpyopt -sccp -domtree -demanded-bits -bdce -basicaa -aa -instcombine -lazy-value-info -jump-threading -correlated-propagation -domtree -basicaa -aa -memdep -dse -loops -loop-simplify -lcssa-verification -lcssa -aa -scalar-evolution -licm -postdomtree -adce -simplifycfg -domtree -basicaa -aa -instcombine -barrier -elim-avail-extern -basiccg -rpo-functionattrs -globals-aa -float2int -domtree -loops -loop-simplify -lcssa-verification -lcssa -basicaa -aa -scalar-evolution -loop-rotate -loop-accesses -lazy-branch-prob -lazy-block-freq -opt-remark-emitter -loop-distribute -loop-simplify -lcssa-verification -lcssa -branch-prob -block-freq -scalar-evolution -basicaa -aa -loop-accesses -demanded-bits -lazy-branch-prob -lazy-block-freq -opt-remark-emitter -loop-vectorize -loop-simplify -scalar-evolution -aa -loop-accesses -loop-load-elim -basicaa -aa -instcombine -scalar-evolution -demanded-bits -slp-vectorizer -simplifycfg -domtree -basicaa -aa -instcombine -loops -loop-simplify -lcssa-verification -lcssa -scalar-evolution -loop-unroll -instcombine -loop-simplify -lcssa-verification -lcssa -scalar-evolution -licm -alignment-from-assumptions -strip-dead-prototypes -globaldce -constmerge -domtree -loops -branch-prob -block-freq -loop-simplify -lcssa-verification -lcssa -basicaa -aa -scalar-evolution -branch-prob -block-freq -loop-sink -instsimplify -verify -write-bitcode Target Library Information Target Transform Information Type-Based Alias Analysis Scoped NoAlias Alias Analysis Assumption Cache Tracker Profile summary info ModulePass Manager Force set function attributes Infer set function attributes Interprocedural Sparse Conditional Constant Propagation Global Variable Optimizer Unnamed pass: implement Pass::getPassName() FunctionPass Manager Dominator Tree Construction Promote Memory to Register Dead Argument Elimination FunctionPass Manager Dominator Tree Construction Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Combine redundant instructions Simplify the CFG PGOIndirectCallPromotion CallGraph Construction Globals Alias Analysis Call Graph SCC Pass Manager Remove unused exception handling info Function Integration/Inlining Deduce function attributes FunctionPass Manager Dominator Tree Construction SROA Early CSE Speculatively execute instructions if target has divergent branches Lazy Value Information Analysis Jump Threading Value Propagation Simplify the CFG Dominator Tree Construction Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Combine redundant instructions Conditionally eliminate dead library calls Tail Call Elimination Simplify the CFG Reassociate expressions Dominator Tree Construction Natural Loop Information Canonicalize natural loops LCSSA Verifier Loop-Closed SSA Form Pass Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Scalar Evolution Analysis Loop Pass Manager Rotate Loops Loop Invariant Code Motion Unswitch loops Simplify the CFG Dominator Tree Construction Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Combine redundant instructions Natural Loop Information Canonicalize natural loops LCSSA Verifier Loop-Closed SSA Form Pass Scalar Evolution Analysis Loop Pass Manager Induction Variable Simplification Recognize loop idioms Delete dead loops Unroll loops MergedLoadStoreMotion Function Alias Analysis Results Memory Dependence Analysis Lazy Branch Probability Analysis Lazy Block Frequency Analysis Optimization Remark Emitter Global Value Numbering Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Memory Dependence Analysis MemCpy Optimization Sparse Conditional Constant Propagation Dominator Tree Construction Demanded bits analysis Bit-Tracking Dead Code Elimination Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Combine redundant instructions Lazy Value Information Analysis Jump Threading Value Propagation Dominator Tree Construction Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Memory Dependence Analysis Dead Store Elimination Natural Loop Information Canonicalize natural loops LCSSA Verifier Loop-Closed SSA Form Pass Function Alias Analysis Results Scalar Evolution Analysis Loop Pass Manager Loop Invariant Code Motion Post-Dominator Tree Construction Aggressive Dead Code Elimination Simplify the CFG Dominator Tree Construction Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Combine redundant instructions A No-Op Barrier Pass Eliminate Available Externally Globals CallGraph Construction Deduce function attributes in RPO Globals Alias Analysis FunctionPass Manager Float to int Dominator Tree Construction Natural Loop Information Canonicalize natural loops LCSSA Verifier Loop-Closed SSA Form Pass Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Scalar Evolution Analysis Loop Pass Manager Rotate Loops Loop Access Analysis Lazy Branch Probability Analysis Lazy Block Frequency Analysis Optimization Remark Emitter Loop Distribution Canonicalize natural loops LCSSA Verifier Loop-Closed SSA Form Pass Branch Probability Analysis Block Frequency Analysis Scalar Evolution Analysis Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Loop Access Analysis Demanded bits analysis Lazy Branch Probability Analysis Lazy Block Frequency Analysis Optimization Remark Emitter Loop Vectorization Canonicalize natural loops Scalar Evolution Analysis Function Alias Analysis Results Loop Access Analysis Loop Load Elimination Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Combine redundant instructions Scalar Evolution Analysis Demanded bits analysis SLP Vectorizer Simplify the CFG Dominator Tree Construction Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Combine redundant instructions Natural Loop Information Canonicalize natural loops LCSSA Verifier Loop-Closed SSA Form Pass Scalar Evolution Analysis Loop Pass Manager Unroll loops Combine redundant instructions Canonicalize natural loops LCSSA Verifier Loop-Closed SSA Form Pass Scalar Evolution Analysis Loop Pass Manager Loop Invariant Code Motion Alignment from assumptions Strip Unused Function Prototypes Dead Global Elimination Merge Duplicate Global Constants FunctionPass Manager Dominator Tree Construction Natural Loop Information Branch Probability Analysis Block Frequency Analysis Canonicalize natural loops LCSSA Verifier Loop-Closed SSA Form Pass Basic Alias Analysis (stateless AA impl) Function Alias Analysis Results Scalar Evolution Analysis Branch Probability Analysis Block Frequency Analysis Loop Pass Manager Loop Sink Remove redundant instructions Module Verifier Bitcode Writer Pass Arguments: -domtree FunctionPass Manager Dominator Tree Construction

通過名稱是自描述性的,但如果您想知道它們如何詳細操作,則可以在線查看源代碼。