2013-03-01 82 views
23

只是好奇,GCC或Clang工具集目前是否實現了MSVC的identical COMDAT folding(ICF)的等價物?如果不是,有沒有計劃?除了舊的GCC郵件列表消息外,我似乎無法找到有關此主題的最新權威鏈接。GCC(/ Clang):使用相同指令合併函數(COMDAT摺疊)

如果不是,這是否意味着對於不同類型的模板實例在結果二進制文件中(即它們沒有完全內聯的情況下)通常是不同的函數,即使它們是二進制兼容的,在其他層面處理這個問題?

另外,是否有人發現ICF在最小化實際生成的可執行文件的大小方面有很大的不同?我沒有任何大的MSVC項目可以方便地進行測試。 (我猜這只是真的有幫助,如果你碰巧通過許多不同的vtable-layout兼容類型實例化模板)。

最後,它是C++ 11標準兼容的兩個函數指針,以不同的函數比較相等在運行時? This link似乎暗示它不是,但它是爲C99。編輯:found previous question on this topic

+1

找到[MSFT的Larry Osterman引用](http://blogs.msdn.com/b/oldnewthing/archive/2005/03/22/400373.aspx):「這個特性[ICF]是什麼使得C++模板是應用程序的可行解決方案...否則,模板會導致代碼大小的充分膨脹,以至於它們幾乎無法用於生產軟件。「......好奇GCC/Clang如果不執行此操作,該如何處理 – 2013-03-02 00:09:03

+3

他們確實很順利,很多軟件都使用標準庫中的模板,所以顯然不是模板「幾乎不可用」 – 2013-03-02 00:12:34

+0

@JonathanWakely哈,我喜歡GCC,這只是他的引用:) – 2013-03-02 00:16:04

回答

16

GCC和Clang都不是鏈接器,並且ICF需要由鏈接器完成,或者至少與鏈接器進行合作。編輯: 他們不做ICF,所以是的,不同的實例產生不同的代碼。 GNU gold鏈接器支持ICF和--icf選項,該選項需要使用GCC選項-ffunction-sections

不同的函數必須有不同的地址......我不記得ICF是否對任何有地址的函數禁用,但如果不是這樣,應該可以在組合之前加載一個非操作指令函數,並使每個不同的實例在不同的指令上開始,因此它們具有不同的地址。編輯:黃金的--icf=safe選項只啓用ICF的功能,可以證明沒有他們的地址,所以依賴於不同地址的代碼仍然可以工作。

ICF是一個整潔的優化,但不是必需的。通過一點努力,您可以將非相關代碼提取到非模板或具有較少參數的模板,以減少可執行文件中重複代碼的數量。關於這一點,我在幾年前做了一次Diet Templates的演講。

+0

對不起,我意識到我有點鬆散的術語......我應該怎麼稱呼這個鏈接器 - 通常打包的,但是與GCC-on-linux-x86/64? (它是特定於平臺的,對吧?) – 2013-03-02 00:20:32

+1

這個鏈接器通常被稱爲「GNU ld」或者GNU鏈接器,整套工具通常被稱爲GNU工具鏈(意思是GCC,GNU as,GNU ld,有時包括GNU libc中)。連接器通常是操作系統的一部分,例如Solaris有自己的鏈接器,但GNU鏈接器是跨平臺的,支持很多可執行格式並可以在很多不同的操作系統上運行,所以例如Solaris上的GCC可以配置爲使用本地Solaris鏈接器或GNU鏈接器。 – 2013-03-02 00:24:59

+0

感謝您的澄清。鐺仍默認使用GNU ID,對吧?實際上,我想這取決於你的配置,好像他們也有自己的配置。 – 2013-03-02 00:28:27