2016-11-24 37 views
0

我已經看到,使用優化級別3的GCC編譯器內聯靜態函數,但在一種情況下不內聯非靜態函數。而在其他情況下,它將函數內聯,而不管是靜態的還是非靜態的。 我想知道哪些參數會選擇靜態或非靜態函數進行內聯。C編譯器優化(gcc):自動內聯非靜態函數vs靜態函數

+0

我很肯定你沒有在GCC的源代碼之外找到完整的列表。當然,這可以因編譯器和編譯器的不同而不同。但是,該標準包含一些限制。 –

+0

如果因爲編譯器知道如何使用它的地址而永遠不會返回其地址,則可以內聯一個靜態函數。非靜態函數不一定是內聯的,因爲其他源文件中的代碼可能會調用它。或者,至少必須定義非內聯函數,以便可以從其他翻譯單元調用它,即使本地使用是內聯的。 –

回答

0

從GCC手冊:

-O3執行最多的優化。 -O3打開由-O2指定的所有優化,並打開-finline函數, -funswitch-loops,-fpredictive-commoning,-fgcse-after-reload,-ftree-loop-vectorize,-ftree-loop- distribution-patterns, -fsplit-paths -ftree-slp-vectorize,-fvect-cost-model,-ftree-partial-pre和-fipa-cp -clone選項。

好像你的話來自-finline-功能選項:

-finline函數

考慮所有功能內聯,即使他們不聲明爲inline。編譯器試探性地決定哪些功能值得以這種方式進行集成。

如果對給定函數的所有調用都被集成,並且該函數被聲明爲「靜態」,那麼函數通常不會輸出爲彙編代碼本身。

在-O3級別啓用。

其實所有的功能都受到在-O3優化模式由GCC被內聯,無論是聯聲明,靜態的,沒有或兩者兼而有之。

這裏的gcc的手冊頁(-Winline選項)的另一大塊:

編譯器使用各種啓發式,以確定是否要內聯函數。例如,編譯器 考慮了內聯函數的大小以及當前函數中已經完成的內聯量。

因此,gcc使用函數的大小和函數中的內聯函數來選擇內聯還是不內聯。如果你想知道更多關於這些啓發式的知識,恐怕你可能需要查看gcc的源代碼:)

+0

這裏的重要啓發是「靜態」單一調用函數,並且通過所有體面的優化C編譯器。內聯實際上是一種尺寸與速度的折衷方案,但如果實際上沒有任何東西丟失,因爲非內聯版本無法訪問可能會被丟棄。自然有皺紋和特殊情況,但這是一般的想法。 – doynax