Let's start Scheme

2011-11-10

定数畳み込み

コンパイラの最適化をもう一歩進めてみた。
実は以前から構文としてはdefine-constantをサポートしてはいたんだけど、何もしない単なるサポートにしかなっていなかった。
っで、せっかくライブラリのインライン化とかやったので定数も畳み込んでしまおうと思い立ってやってみた。

基本方針は以下の通り。
  • 定数のみ。
  • exportで定義されていない。
  • コンパイラの最適化で定数になるものは含める。例えばこんなの
    (define a (car '(a b c))) ;; コンパイラは'aをaに定義する。
  • define-constantで定義されたものはライブラリ外でも参照する
とりあえず、なんとなく動くようになったっぽい。以下のコードでは定数が畳み込まれていることが確認できた。
(define-constant a (car '(a b c))) ;; carはコンパイル時に計算される(可能なら)

(define (test)
  (print a))
(disasm test)
;; size: 5
;; 0: CONST_PUSH a <-- シンボルaがそのまま渡されている
;; 2: GREF_TAIL_CALL(1) #<identifier print#user(0x5fd1e0)> ;; print
;; 4: RET

(library (inner)
    (export const-value)
    ;; define-constant は(sagittarius)ライブラリにて提供
    (import (sagittarius))
  (define-constant const-value 10)
)

(library (test)
    (export test2)
    (import (rnrs)
     (inner))

  (define a (+ 1 2 3)) ;; a はexportされていない

  (define (test2)
    (display a)
    (display const-value)
    (newline))
)

(import (test))
(disasm test2) 
;; size: 13
;; 0: FRAME 4
;; 2: CONSTI_PUSH(6) <-- 計算された後の定数になっている
;; 3: GREF_CALL(1) #<identifier display#|(test)|(0x73d018)> ;; display
;; 5: FRAME 4
;; 7: CONSTI_PUSH(10) <-- GREF const-valueではない
;; 8: GREF_CALL(1) #<identifier display#|(test)|(0x73efa8)> ;; display
;; 10: GREF_TAIL_CALL(0) #<identifier newline#|(test)|(0x73ef30)> ;; newline
;; 12: RET
ま、まずまずでしょう。Gambitのベンチマークにはなんら影響が出ないところが多少以上に悲しいが。(あれらはR6RSのライブラリを使ってないから、最適化がかからん)
もう少し寝かせてから0.2.2をリリースしよう。

No comments:

Post a Comment