libgccjit和LLVM相比,有哪些優點?


感謝 @bhuztez 大大邀請。

水平有限,不知道從哪裡寫起、按什麼線索寫好。而且要說libgccjit跟LLVM相比,「優點有哪些」這明顯比「缺點有哪些」難寫啊?

只能又記流水賬了。

先堆些libgccjit的鏈接:

  • libgccjit - GCC 5 Release Notes

  • JIT-compilation using GCC 5

  • libgccjit v5.1.0 documentation

  • https://gcc.gnu.org/wiki/JIT

  • Just-In-Time compilation using GCC (libgccjit.so)

下面分方面來對比一下。先列些點,細節回頭慢慢補充(希望能邊討論邊補充上來)

1、黑箱API(libgccjit) vs 黑箱/白箱混合API(LLVM IR)

各有千秋。總體看我覺得libgccjit的可控性還是有所欠缺。一旦到需要精密控制的時候它就不能行了。

libgccjit提供了兩套API,一套是C的,一套是C++的,兩者的實質功能一模一樣,後者只是前者的非常輕量級的包裝,讓C++代碼寫起來稍微舒服一點。

libgccjit的API提供的抽象程度跟C語言的的語義類似。換句話說基本上用這組API能達到的效果跟人肉拼接出C源碼然後一股腦扔給GCC去編譯是差不多的。

LLVM也提供了兩套API,同樣一套是C的一套是C++的。但是這兩者不是一回事:

LLVM C++ API是真正的核心API,可以對LLVM進行非常精密的控制,但因為暴露了LLVM的很多實現細節所以版本間不保證兼容。這個是白箱API;

LLVM C API則是在此之上的一層封裝,並不怎麼暴露LLVM的內部實現,因而API穩定性較高。這個跟libgccjit的API類似,是黑箱API。LLVM: LLVM-C: C interface to LLVM

LLVM IR的抽象程度在C語言以下,更接近底層一些。編譯流程中的很多要素可控,例如說calling convention在需要精密控制的時候可以控制得了。

這在實現VM runtime的JIT時尤其重要,因為很多VM為了一些特殊需求會想用特殊的calling convention提高性能。

2、API穩定性

這裡毫無疑問是libgccjit在將來會更佔優;LLVM C API也可以算在同一層面上吧。

3、API的易用性(糖的多少)

用一個超簡單的例子來對比一下這些JIT庫的易用性。

要實現的函數是C語義的:

int foo(int x, int y, int z) {
return x + y * z;
}

用libgccjit的話,構建IR的部分需要:

/* 待補充 */

這裡我想拿GNU的另一個項目——LibJIT——亂入進來對比一下。

要實現上面的例子,用libjit的話只需要:

jit_value x = func.get_param(0),
y = func.get_param(1),
z = func.get_param(2);

// use overloaded operators to build expressions
func.insn_return(x + y * z);

有沒有看起來很爽?完整代碼請看:這裡

可惜libjit的代碼生成質量太差,完全放不上桌面。它在x86上支持0和1兩個優化級別,但感覺生成的代碼也差不了多少。在這裡例子里,兩個級別生成的都是:(Mac OS X/x64)

push %rbp
mov %rsp,%rbp
sub $0x20,%rsp
mov %edi,-0x8(%rbp)
mov %esi,-0x10(%rbp)
mov %edx,-0x18(%rbp)
mov -0x10(%rbp),%eax
imul -0x18(%rbp),%eax
mov -0x8(%rbp),%ecx
add %ecx,%eax
mov %rbp,%rsp
pop %rbp
retq

呃?

4、控制流、SSA

libgccjit

需要顯式構造基本塊來形成控制流圖。IR不暴露出SSA的特徵。

LLVM

需要顯式構造基本塊來形成控制流圖。IR暴露出SSA的特徵,但是有辦法不用前端自己生成SSA。

libjit

通過branch+label表示控制流,

5、編譯速度

天啊,拿兩隻烏龜來比有意思么?

這倆都不是天然適合做輕量級JIT編譯器的料。

6、對GC的支持

兩者都不咋。相比之下肯定是LLVM更勝一籌,有總比沒有好!

7、待續


優點是它是一個JIT,缺點是它不是一個編譯器後端

我認真的.


libgccjit簡直就只是一個玩具,根本沒有辦法拿來做即時編譯器。


推薦閱讀:

LLVM相比於JVM,有哪些技術優勢?
過程間和過程內的數據流分析演算法在類似LLVM的IR或HotSpot C1的HIR中,是如何實現的?

TAG:即時編譯JIT | GCC | 編譯器 | LLVM |