我有一些重用代碼,我希望GCC進行積極優化。但我也想用幾個地方調用的(inlinable)函數來編寫乾淨的,可重用的代碼。有些情況下,在內聯函數中,我知道可以刪除的代碼因爲條件永遠不會發生。有沒有辦法告訴GCC參數的範圍?
讓我們看一個具體的例子:
#include <assert.h>
static inline int foo(int c)
{
if (c < 4)
return c;
else
return 4;
}
int bar(int c)
{
assert(c < 2);
return foo(c);
}
隨着-DNDEBUG -O3
,GCC仍然會生成(C < 4),即使我知道這比較是沒有必要的,因爲bar
功能的前提條件是, c
是0或1.沒有-DNDEBUG
,GCC 確實刪除比較,因爲它是由斷言暗示 - 但當然你有斷言的開銷(這是更多)。
有沒有辦法將可變範圍傳達給GCC,因此可用於優化?
如果CLANG可以做得更好,我也可以考慮切換編譯器。
Clang 4.0/Zapcc做的比GCC 7.1 - 4的指令略好,而不是x64上的5 - 但它們都不夠聰明,不願選擇foo的c <4。你可以通過https://godbolt.org/g/3Hp4ZA查看各種編譯器,我沒有檢查過它們能夠優化它(這是有道理的)。理想情況下,會有一些神奇的用法指定c的範圍,但我認爲任何人都還沒有想出這樣的pragma ......或者某些聰明的assert內建函數,它可以從生成的代碼中移除它自己,但被優化者認可。 – valiano
@Mike:斷言只是一個例子,我只是刪除第一個,因爲它在這裏不相關(不用於優化)。 – Arnout
@valiano:事實上,我正在尋找一個聰明的斷言。 GIMPLE(海灣合作委員會的內部表示)跟蹤變量範圍,這就是它可以如何優化(c <4)以防止斷言存在。我想要一種方式來明確地表達這樣的範圍,而不是讓編譯器進行分析。 – Arnout