GCC編譯優(yōu)化解析
如果不指定優(yōu)化標志,gcc會產(chǎn)生可調(diào)試的代碼
啟用優(yōu)化后,gcc會改變程序的結(jié)構(gòu),讓代碼變小或者運行得更快
-O0不優(yōu)化
-O, -O1在不影響編譯速度的情況下,盡量采取一些優(yōu)化算法降低代碼大小和加快代碼運行的速度,并啟用以下優(yōu)化選項:
fauto-inc-dec
地址訪問時,合并地址訪問指令和地址的遞增和遞減操作fbranch-count-reg
在計數(shù)寄存器中運行遞減和分支指令
而不是單獨運行遞減指令,并與零比較,然后再根據(jù)結(jié)果進行分支combine-stack-adjustments
跟蹤堆棧的push和pop,并嘗試找到合并它們的方法fcompare-elim
判斷計算結(jié)果的flag寄存器,如果可以,用flag寄存器的結(jié)果來代替現(xiàn)式地比較操作fcprop-registers
通過寄存器存有的值,通過計算變量的依賴,減少從內(nèi)存中讀取該變量的值,通過拷貝傳播,來減少變量的拷貝-fdce
消除死代碼-fdefer-pop
程序一般在函數(shù)返回時,會pop出棧中元素
而編譯器,會合并多個函數(shù)調(diào)用,并一次性pop出相關(guān)的元素-fdelayed-branch
嘗試對指令重新排序,來利用延遲分支指令后可用的指令槽-fdse
對死代碼進行消除-fforward-propagate
The pass tries to combine two instructions and checks if the result can be simplified. If loop unrolling is active, two passes are performed and the second is scheduled after loop unrolling.-fguess-branch-probability
分支預測-fif-conversion2
利用條件執(zhí)行把if條件轉(zhuǎn)化為無分支等價代碼-fif-conversion
利用moves, min, max, set, abs等手段把if條件轉(zhuǎn)化為無分支等價代碼-finline-functions-called-once
把靜態(tài)函數(shù)轉(zhuǎn)為inline函數(shù)-fipa-pure-const
發(fā)現(xiàn)函數(shù)是純函數(shù)還是常量函數(shù)-fipa-profile
對cold(僅調(diào)用一次的函數(shù))函數(shù)進行優(yōu)化-fipa-reference
-fmerge-constants
合并常數(shù)計算-fmove-loop-invariants
優(yōu)化循環(huán)的不變量-freorder-blocks
重排代碼塊-fshrink-wrap
函數(shù)的開場白僅在使用前才初始化,而不是在函數(shù)開始的時候做-fshrink-wrap-separate
把函數(shù)的開場白和結(jié)束語分開,盡在使用的時候才初始化-fsplit-wide-types
對于某些需要占用多個寄存器的變量,獨立的申請寄存器-fssa-backprop
在定義鏈上傳播相關(guān)使用的信息,來簡化定義-fssa-phiopt
優(yōu)化條件代碼-fstore-merging
合并存儲-ftree-bit-ccp
在tree上傳播稀疏條件位常量,并對齊傳播指針-ftree-ccp
在tree上傳播稀疏條件常量,并對齊傳播指針-ftree-ch
-ftree-coalesce-vars
-ftree-copy-prop
-ftree-dce
-ftree-dominator-opts
-ftree-dse
-ftree-forwprop
-ftree-fre
-ftree-phiprop
-ftree-sink
-ftree-slsr
-ftree-sra
-ftree-pta
-ftree-ter
-funit-at-a-time
會犧牲一定的編譯速度,除了執(zhí)行O1的所有編譯優(yōu)化之外,還會采取幾乎所有的目標配置支持的優(yōu)化算法,用來提高目標代碼的運行速度
-fthread-jumps
判斷是否有double jump,并進行優(yōu)化-falign-functions
把函數(shù)的開始地址對齊到2的冪-falign-jumps
把分支的起點地址對齊到2的冪-falign-loops
把循環(huán)的開始地址對齊到2的冪-falign-labels
把標簽的地址對齊到2的冪-fcaller-saves
-fcrossjumping
-fcse-follow-jumps
-fcse-skip-blocks
-fdelete-null-pointer-checks
檢查是否存在delete空指針-fdevirtualize -fdevirtualize-speculatively
用子類虛函數(shù)覆蓋虛函數(shù)函數(shù)指針-fexpensive-optimizations
-fgcse -fgcse-lm
全局的公用子表達式優(yōu)化-fhoist-adjacent-loads
-finline-small-functions
把小函數(shù)優(yōu)化為內(nèi)聯(lián)函數(shù)-findirect-inlining
-fipa-cp
過程間常數(shù)傳播-fipa-cp-alignment
-fipa-bit-cp
-fipa-sra
過程間優(yōu)化,刪除未使用的參數(shù),將值傳遞優(yōu)化為引用傳遞-fipa-icf
-fisolate-erroneous-paths-dereference
檢測由于取消空指針而觸發(fā)錯誤或未定義行為的路徑,將這些路徑隔離-flra-remat
通過上下文敏感,重用變量-foptimize-sibling-calls
優(yōu)化同級和尾部遞歸調(diào)用-foptimize-strlen
優(yōu)化strlen函數(shù)-fpartial-inlining
部分內(nèi)聯(lián)函數(shù)-fpeephole2
機器相關(guān)優(yōu)化-freorder-blocks-algorithm=stc
塊內(nèi)代碼重排優(yōu)化-freorder-blocks-and-partition -freorder-functions
重排代碼-frerun-cse-after-loop
重新運行公共表達式減少在循環(huán)后-fsched-interblock -fsched-spec
在不同塊間進行重排指令-fschedule-insns -fschedule-insns2
-fstrict-aliasing
類型嚴格轉(zhuǎn)換檢查-fstrict-overflow
檢查類型是否溢出-ftree-builtin-call-dce
-ftree-switch-conversion -ftree-tail-merge
-fcode-hoisting
-ftree-pre
-ftree-vrp
-fipa-ra
函數(shù)調(diào)用者,如果某些寄存器沒有用到,則可以不需要保存這些寄存器的值
除了執(zhí)行O2所有的優(yōu)化選項之外,一般還會采用很多向量化算法,提高程序的并行度,并利用CPU的流水線和cache來加快運行速度,
這個選項會加大代碼的大小,并降低目標代碼的執(zhí)行時間
-finline-functions
采用一些啟發(fā)式算法對函數(shù)進行內(nèi)聯(lián)-funswitch-loops
找到循環(huán)的不變條件,并移到循環(huán)外部-fpredictive-commoning
在循環(huán)間重用計算-fgcse-after-reload
執(zhí)行全局的共同子表達式消除-ftree-loop-vectorize
向量化優(yōu)化-ftree-loop-distribute-patterns
把loop的某些部分轉(zhuǎn)化為標準函數(shù),例如memset-fsplit-paths
-ftree-slp-vectorize
基本塊向量化-fvect-cost-model
-ftree-partial-pre
部分冗余代碼消除-fpeel-loops
-fipa-cp-clone
過程間調(diào)用函數(shù)克隆,讓常量傳播更有效
目的是盡量減少目標代碼的大小,這對存儲容量很小的設(shè)備尤為重要
-falign-functions
對齊-falign-jumps
對齊-falign-loops
對齊-falign-labels
對齊-freorder-blocks
重排-freorder-blocks-algorithm=stc
重排-freorder-blocks-and-partition
重排-fprefetch-loop-arrays
預取
除了啟用所有O3的優(yōu)化選項之外,還會針對某些語言啟用部分優(yōu)化
-Og目的是保留較好的可調(diào)試信息的前提下提供合理的優(yōu)化
GCC常用選項-E: 預處理
-S: 編譯
-c: 編譯 匯編 不鏈接
-g: 包含調(diào)試信息
-I: 指定include頭文件目錄
-o: 輸出編譯文件
-w: 忽略所有警告
-Werror: 不區(qū)分警告和錯誤,遇到任何警告都停止編譯
-Wall: 開啟大部分告警提示
-Wshadow: 作用域相關(guān)存在變量同名時發(fā)出告警
-Wextra: 對所有合法但值得懷疑的表達式發(fā)出告警
ref: https://gcc.gnu.org/onlinedocs/
*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。