簡體   English   中英

GCC中-O0和-O1之間的差異

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM