最近又發現了好玩的東西,那就是LLVM (http://llvm.org/)。為什麼說它好玩呢?看看它的名稱 Low Level Virtual Machine 低階虛擬機器。它的作用在於,扮演高階語言與機器語言的中間語言,如同GCC所使用的RTL。
LLVM嚴格說起來是一個編譯器架構。怎麼說呢?編譯器的開發者僅需開發一個可以將原始碼轉換成LLVM的bitcode的格式即可(frontend),而轉換至機器語言的部份則有另一批開發人員開發(backend),這使得程式語言可以很輕鬆的跨越各種平台。
官方目前使用的編譯器便是,一個修改自GCC的編譯器名為llvm-gcc,它把GCC中RTL的backend替換成了LLVM的backend,如此就成了基於LLVM的編譯器。然而,更遠大的目標是clang編譯器,它是一個從0開始製作的編譯器,是為LLVM的frontend。clang編譯器將程式編譯成LLVM的bitcode後,再透過backend的程式,將它轉換成本地程式碼。
雖然LLVM在各個平台所使用的bitcode是一樣的,但是這並不代表它就是跨平台的。影響跨平台的因素很多,包含平台所提供的函式庫、執行檔的格式等,這些都不是LLVM的backend的範圍之內,因此你在Linux所寫得C++程序透過編譯器編譯成LLVM bitcode後,這份bitcode僅能提供Linux平台之使用。
這裡列舉了幾個LLVM的實做:
此外,目前還有一項計畫,叫做:DragonEgg,針對GCC 4.5的部份做了一個plugin。只要編譯時,將此plugin掛上去,GCC就會像llvm-gcc一樣,使用LLVM作為backend來編譯。目前還在屬於開發狀態,且預計要等GCC 4.5正式推出後,這個plugin才會正式推出。目前除了C/C++以外,其他語言仍然不支援,或是很少量的支援。
LLVM嚴格說起來是一個編譯器架構。怎麼說呢?編譯器的開發者僅需開發一個可以將原始碼轉換成LLVM的bitcode的格式即可(frontend),而轉換至機器語言的部份則有另一批開發人員開發(backend),這使得程式語言可以很輕鬆的跨越各種平台。
官方目前使用的編譯器便是,一個修改自GCC的編譯器名為llvm-gcc,它把GCC中RTL的backend替換成了LLVM的backend,如此就成了基於LLVM的編譯器。然而,更遠大的目標是clang編譯器,它是一個從0開始製作的編譯器,是為LLVM的frontend。clang編譯器將程式編譯成LLVM的bitcode後,再透過backend的程式,將它轉換成本地程式碼。
雖然LLVM在各個平台所使用的bitcode是一樣的,但是這並不代表它就是跨平台的。影響跨平台的因素很多,包含平台所提供的函式庫、執行檔的格式等,這些都不是LLVM的backend的範圍之內,因此你在Linux所寫得C++程序透過編譯器編譯成LLVM bitcode後,這份bitcode僅能提供Linux平台之使用。
這裡列舉了幾個LLVM的實做:
- Rubinius:透過LLVM動態編譯Ruby至llvm bitcode,然後轉換成機器語言後執行。
- Unladen Swallow:是一個Python的分支,原本直接解析Python程式碼執行的部份,將改為動態編譯的形式。它也是將Python動態編譯成llvm bitcode然後再執行,藉此提高它的效能。
- VMKit:透過LLVM實做一個Java與.Net的虛擬機器架構,它所做出來的是屬於高階虛擬機器。
- LDC:基於LLVM的D語言編譯器。
- Icedtea Shark:主要替代hotspot的Java虛擬機器,採用LLVM來達成跨越各種平台的JIT Compiler。
- Clang:基於LLVM的C/C++編譯器,以速度快、簡單為其特點。且對於GCC有著一定的相容性。
- Pypy:與Unladen Swallow類似,原本的主旨是利用Python寫出Python解析器,後來加入了JIT的支援,以LLVM為後端。
- 更完整的錯誤與警告描述。GCC的錯誤與警告描述十分簡潔,使得開發者不知道如何修正。然而clang所描述的錯誤與警告訊息十分完整,有時甚至提供建議修正方式,如忘記加;,還會用箭頭表示。
- 此外,由於Clang使用LLVM為backend,因此支援很多LLVM的功能。
- Clang用非常少量的記憶體以及非常快速的速度。與GCC比較,實在是快太多了。
- 提供完整API。
此外,目前還有一項計畫,叫做:DragonEgg,針對GCC 4.5的部份做了一個plugin。只要編譯時,將此plugin掛上去,GCC就會像llvm-gcc一樣,使用LLVM作為backend來編譯。目前還在屬於開發狀態,且預計要等GCC 4.5正式推出後,這個plugin才會正式推出。目前除了C/C++以外,其他語言仍然不支援,或是很少量的支援。