Bringing GNU Emacs to Native Code

January 30, 2022

Emacs 28から利用できるlibgccjitによるネイティブコンパイルの解説である。 パッケージアーカイブELPAにあるelisp-benchmarksによる比較ではバイトコンパイルよりも2.3倍から42倍の高速化を実現した。 ネイティブコンパイル時は、はじめに、Emacs Lispのコードをバイトコンパイラで、Emacs VM(Lisp Assembly Program, LAP)の中間表現に変換する。 つぎに、LAPをS式で静的単一代入形式の中間表現LIMPLEに変換する。 LIMPLEは、GCCの中間表現GIMPLEに由来し、ネイティブコンパイルの中核技術にあたる。 さいごに、LIMPLEをlibgccjitの中間表現に変換し、GCCでネイティブに実行可能なプログラムにコンパイルする。

LIMPLE上の関数は、要素が(operator operands)のリストがノードであるグラフで表現される。 (operator operands)には、たとえば(set dst src), (call f a b), (jump bb)がある。 Emacs LispとGCCの中間表現のあいだにLIMPLEを導入した理由は、どの純粋関数がコンパイル時に最適化できるかや強い型付けなどのGCCの中間表現に渡せない情報が最適化に有用だからである。 ほかにも、GCCがアンボクシングをサポートしていないことや、GCCの最適化が保守的であるといった理由もある。

論文をこちらからダウンロードできます。