gccemacs

elisp

#1

GCC貢獻者Andrea Corallo宣佈了gccemacs On elisp running native,用libgccjit編譯elisp爲ELF shared objects。libgccjit在這裏沒有用作JIT,而是驅動GCC進行優化和生成ELF。

倉庫:https://gitlab.com/koral/gccemacs/commits/dev

作者創建這個專案的動機和方法:

On my side the long story short is about this:

I was already into gcc and libgccjit. I thought was cool to apply these to some lisp implementation. I decided to have Emacs as a target cause I imagined would have been useful and because I’m obviously an Emacs user and fan.

I wanted to do something with the potential to be completed and up streamed one day. Therefore I discarded the idea of writing the full lisp front-end from scratch. On the other side I considered the idea seen in previous projects of reusing the byte-compiler infrastructure quite clever.

The original plan was the to do something like Tromey’s jitter but gcc based and with a mechanism to reload the compiled code. So I did it.

I had a single pass compiler all written in C that was decoding the byte code and driving libgccjit.

I was quite unhappy with that solution for two reasons:

1- The C file was getting huge without doing anything really smart.

2- After some test and observation became clear that to generate efficient code this approach was quite limited and a more sophisticated approach with a propagation engine and the classical compiler theory data structures was needed. The idea of just driving gcc and having everything magically optimized was simply naive.

So I came up with the idea of defining LIMPLE and using it as interface between the C and the lisp side of the compiler.

In this way I had the right IR for implementing the ‘clever’ algorithmic into lisp and the C side has just to ‘replay’ the result on libgccjit. Moreover it saved me from the pain of exposing libgccjit to lisp.

I then realized I could, instead of decoding op-codes, just spill the LAP from the byte-compiler. This makes the system simpler and more robust cause I get also information on the stack depth I can double check or use during limplification.

Lastly I managed to reuse the information defined in the byte-compiler on the stack offset of every op to generate automatically or semi the code of my compiler for the translation from LAP to LIMPLE for good part of the op codes.

The rest just iterating over tests debugging and implementing.

C部分主要加了src/comp.c

% git diff master...dev --stat
 configure.ac                |   29 +
 lisp/emacs-lisp/bytecomp.el |   47 +-
 lisp/emacs-lisp/comp.el     | 1917 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/Makefile.in             |    8 +-
 src/comp.c                  | 3480 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/data.c                  |   13 +
 src/emacs.c                 |    5 +
 src/eval.c                  |    6 +
 src/lisp.h                  |    7 +
 src/lread.c                 |   38 +-
 src/pdumper.c               |    8 +-
 test/src/comp-test-funcs.el |  393 +++++++++++++
 test/src/comp-tests.el      |  487 ++++++++++++++++
 13 files changed, 6422 insertions(+), 16 deletions(-)
git clone https://gitlab.com/koral/gccemacs --branch=dev; cd gccemacs
./autogen.sh
./configure
make -j
src/emacs -Q

evaluate (native-compile "a.el")可以構建出shared object a.eln,可以用require or load-file加載。


#2

已经有相关讨论了


#3

謝謝指出。發的時候沒有注意到。那麼再加一點內容

我平常用自行構建的~/Dev/Emacs/emacs + doom-emacs。現在運行/tmp/p/gccemacs/src/emacs感覺很奇怪,doom會把load-path設置爲~/Dev/Emacs/emacs/lisp/*等目錄,而不是/tmp/p/gccemacs/lisp/*等目錄,(require 'comp)會報錯。

編輯:可能是因爲~/.emacs.d/autoloads.pkg.el包含(setq load-path ...)。怎麼嘗試一個新鮮的emacs而不影響主要用的~/Dev/Emacs/emacs呢?


#4

或许可以临时修改HOME环境变量到别的地方


#5

试试 chroot 呗,其实 Linux 的话新建个专门用来测试软件的用户也不错,X Window 支持同时使用其他用户的图形应用的。