[英]Differences between -O0 and -O1 in GCC
在編譯一些代碼時,我注意到在-O0和-O1之間創建的匯編程序存在很大差異。 我想要啟動啟用/禁用優化,直到我發現導致匯編程序發生某些變化的原因。
如果我使用-fverbose-asm來確切地找出O1與O0相比正在啟用哪些標志,然后手動禁用它們,為什么生成的匯編程序仍然如此大不同? 即使我用O0運行gcc並手動添加fverbose-asm所說的用O1啟用的所有標志,我也沒有得到與使用O1時相同的匯編程序。
除了'-f ...'和'-m ......'之外還有什么可以改變的嗎?
或者就是'O1'與無法關閉的'O0'相比具有一定的魔力。
對於隱秘性感到抱歉 - 這與使用GCC + ARM減少遞歸期間的堆棧使用有關,但是提及它使問題有點難以理解。
如果您只想查看在O1上啟用了哪些未在O0啟用的傳遞,您可以執行以下操作:
gcc -O0 test.c -fdump-tree-all -da
ls > O0
rm -f test.c.*
gcc -O1 test.c -fdump-tree-all -da
ls > O1
diff O0 O1
一個類似的過程,使用你發現的一組標志,可以讓你看到GCC在O1進行的不受標志控制的額外魔法傳遞。
編輯:
一種不那么混亂的方法可能是比較-fdump-pass的輸出,它將列出哪些傳遞為ON或OFF到stderr。
所以類似於:
gcc -O0 test.c -fdump-passes |& grep ON > O0
gcc -O1 test.c -fdump-passes |& grep ON > O1
diff O0 O1
並不是說這有幫助,除了提供一些證據表明你懷疑-O1
魔法無法關閉:
來自http://gcc.gnu.org/ml/gcc-help/2007-11/msg00214.html :
CAVEAT,並非所有由-O1啟用的優化都有一個命令行切換標志來禁用它們。
從Hagen的“GCC第二版的權威指南”:
注意:並非所有GCC的優化都可以使用標志進行控制。 GCC會自動執行一些優化,除了修改源代碼之外,當您使用-O請求優化時,無法禁用這些優化
不幸的是,我沒有找到關於這些硬編碼優化可能是什么的明確陳述。 希望能夠了解GCC內部人員的人可能會發布一些有關此問題的答案。
除了許多選項,您還可以更改參數,例如
--param max-crossjump-edges=1
這會影響代碼生成。 檢查所有可用參數的源文件params.def
。
但是無法通過添加選項從-O0切換到-O1,或從-O1切換到-O2,或從-O或-Os等轉換為pp,而無需修補源代碼,因為有幾個硬盤在不咨詢命令行選項的情況下檢查級別的編碼位置,例如:
return perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.