微軟會把 clang 擴展到可以徹底替換 C1,並真的換掉 C1 嗎?


就算內部大全部代碼都能被clang編譯,估計還是不會丟掉自己的c1/c1xx,畢竟是內部主要軟體的基石。Clang的代碼不可控,外來的代碼導致編譯bug還得去幫他修,要不然也可能成了下面這樣。

百度的 GCC 被三體人鎖定在 3.4.5 版本是什麼典故?


用Clang的好處是,對標準的支持度更高。

用C1的好處是,能支持各種MS擴展和非標準代碼。微軟自己的產品長期用C1編譯,並不考慮標準不標準。結果就是如果直接上Clang,很多問題。這些都需要時間來清除。

不過我這裡想提供一個新思路。不是說他們會這麼做,而是希望大家不要忽視這個可能性。

目前,C1和Clang是並列的前端,只能用其一。最好的情況下,可以有的代碼用Clang,編譯不過的換C1。如果obj能達到二進位兼容,就能平穩過渡。

不過,還有一種架構,C1在Clang之上。或者說,把C1變成一個轉換器,把MS擴展和非標準代碼轉換成符合C++標準的代碼,讓Clang編譯。這麼做一來可以做到100%兼容,二來可以無縫過渡。

對於C++/CLI、C++/CX和C++/AMP這些很過分的擴展,如果用上下層的結構,也可以解決。C++/CX和C++/AMP是可以完全轉換成標準C++的,這個有人做過,不會有異議。C++/CLI和C++/CX很像,雖然沒聽說有人做過,但理論上應該沒有問題。


這要看微軟的決心,雖然有難點,但是技術是通的,若是老大拍板了這個方向,那轉型直接就是分分鐘的事情,從事編譯器的大公司只要一旦轉向,那個衝量是無比巨大的,幾十年的老代碼說丟就丟,毫不留情。這條路,也不是微軟這一家公司這麼做,業內已經有很多這樣的例子,並且已經發布了產品,都是基於Clang FE -&> LLVM IR -&> Own IR -&> Own BE。

這條路的難點不在於語法擴展,那個東西就是人力的問題,問題在於其它一些大頭。略舉幾個馬上就能想到的幾個例子,比如微軟目前推出的Clang CodeGen在某些SPEC測試速度不好(數據應該是我今年年初看到的一張C++ 大會的PPT),目前不能與C1比,然而編譯器的核心競爭力就是效率。一個很明顯的原因就是由於LLVM IR產生的for loop pattern不會與微軟目前自身的後端匹配,只要寫幾個for循環例子,加上LLVM優化一跑,微軟的人一下就能發現。所以直接這樣轉換IR的方式會造成微軟後端很難識別,這需要一些工作。而且去分析SPEC性能瓶頸也需要功夫,也不知道微軟有沒有加LLVM優化,也需要看微軟多注重優化與效率了,然而一旦加入了優化,LLVM會產生很多奇特的IR出來,如LLVM i147這樣的非常規整數,我相信微軟之前的後端也沒有直接處理這樣大整數的指令,而且這樣大整數會有相關指令,如add i147 122345533333232, i147 9899883738913,甚至ashr, trunc, zext, ult等各種大數操作指令,所以這也是加入LLVM優化進入的一個難點,這一個也是完全禁止不掉的,大量存在於LLVM GVN,SROA優化中,所以我個人傾向於認為目前微軟還沒有加入LLVM優化進來,但是若要走這條路線,LLVM優化不加,這就非常可惜,而且也失去了很多意義。另外還有Alias分析,LLVM IR TBAA轉化到微軟的Alias分析也需要大量工作量,這一個很容易出錯的地方,一般O2優化就會暴露出來。同時還有Exception Handling,早期的編譯器基本上都有自己的一套EH處理,微軟需要把Clang產生的轉化過來,好在目前Clang社區似乎很支持微軟的這一套,而且LLVM還專門加了針對微軟EH的IR。另外,還有Inline ASM,目前Clang產生的是GNU那一套,這裡面很多細節與坑,以前微軟發布第一版的時候就說不支持,因為工作量很大,但是若是最終產品,也應該做,很多產品在用(當然微軟也可以足夠強勢,找一個其他原因說這東西沒用,讓大家放棄)。其它一些小點,Hmm...比如LLVM Intrinsinc應該也有工作量,因為一些函數會被翻為@llvm.xxxx,微軟也要做。還有Debug,LLVM目前的Debug其實不穩定,但是基於某一個Clang版本也還可以,但是我不知道WinDbg的格式,LLVM支持的是不是也足夠友好,但是要作為產品,Debug不可能不做,嗯...思路一打開,發現要做的東西也還遠遠不止這一些,就不說了。

總體而言,這條路是完全可行的,業內一些公司都走過了,大家都走通過了,問題不在技術,在老大手上,與技術無關。我個人希望微軟走這一套的,把臟活累活丟給Clang去做,當然這會逐漸造成Clang / LLVM世界大一統,不過好在Clang / LLVM 是 BSD協議。這條路線線我個人認為是一條正確的道路,但是正確的道路不一定會是大家要走的路,還是大佬更重要,跟一個好大佬,大佬欽定了才可以,這就是現實與生活。


會不會不知道,能肯定是能的,反正C++/CLI、C++/CX和C++/AMP對於前端來說都是差不多的。

當然了,如果微軟只保存自己的branch的話,clang以後的修改將越來越難merge。所以除非clang官方願意讓微軟把C++/CLI、C++/CX和C++/AMP的功能合併進去,否則微軟不會扔掉C1,只在編譯native C++的時候讓你clang。


感覺C2要同時支持兩種C1比較麻煩,不如把整個工具鏈都換掉,但這在短期內是不可能的。

(其實,只要32位Windows還存在,編譯Windows就還需要一份古老的CL 7.1,因為32位Windows里有NTVDM,裡面有一大堆16位Windows的東西,只有CL7.1能編譯)


推薦閱讀:

這個程序哪裡錯了,還是G++出了問題?
為什麼儘管 C++ 早就有了很多現代功能,但是卻長期給人原始的印象呢?
GCC 下 C++ 中 new int[] 內存的額外信息在哪裡?
如何利用C++的特性,去實現C中的可變參?

TAG:C | MicrosoftVisualStudio | Clang | LLVM |