Scheme to x86コンパイラ

3,198 views

Published on

Schemeコードをx86アセンブリにコンパイルする、トイコンパイラの紹介
https://github.com/nobutaka/nanopass

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,198
On SlideShare
0
From Embeds
0
Number of Embeds
60
Actions
Shares
0
Downloads
12
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Scheme to x86コンパイラ

  1. 1. Scheme to x86 コンパイラ 多久島 信隆
  2. 2. 経緯tracing GCを作ったことがない ⇒ せっかくなので処理系のGCを作りたい ⇒ Lispinterpreter OR compiler ⇒ 黒魔術感のあるcompiler ⇒ ターゲットは資料の多いx86
  3. 3. 経緯SICP, PAIP, 3imp.pdf, Tiger book, EoPL,MinCaml, etc. を参考にはじめる。実装も沢山ある ⇒ An Incremental Approach to CompilerConstructionに出会う ⇒ さくさく作れて楽しいこの論文および関連資料を基礎にして進めてきた
  4. 4. Schemeの紹介極めてシンプル (ストイック) な言語仕様予約語はありませんすべては式です必要な構文は5つ (define quote if set! lambda)
  5. 5. S式z1 → ((a . (b . ())) . ())S式は最小限の労力で、グラフをテキストにシリアライズする手段LispのプログラムコードはS式a = 1 + 1 は (set! a (+ 1 1)) となる
  6. 6. Program as Data 他の言語ならコンパイラが構文解析して内部に作られる構文木を、Lispでは 直接プログラムとして書き下すわけだ。しかも、この構文木はプログラムか らアクセスできるから、構文木自身を操作するプログラムを書くことができ る。Lispではそのようなプログラムをマクロと呼ぶ。いわば、プログラムを 生成するプログラムだ。 ポール・グレアム⇒ 処理系が必要になれば、S式からS式のトランスレータを書けばよく、それは簡単、ということです。
  7. 7. 特徴的な言語要素レキシカルスコープ無限のエクステント1st class lambda, 1st class continuationマクロGC
  8. 8. nanopassコンパイラR5RSサブセット 伝統的マクロx86=32bit register Exact copying GCmachine FFI callout, callback3bit tagged value Schemeで実装CPS変換による parser, 最適化はなしcontinuationhttps://github.com/nobutaka/nanopass
  9. 9. fixnum if
  10. 10. flonum string vector
  11. 11. let map list
  12. 12. vararg FFI call/cc
  13. 13. 方針コンパイルフェーズを細かく分け、小さな変換を繰り返す ⇒ nanopassmicro schemeを実装してその上にfull schemeを実装する数値をコンパイルできるところからはじめ、ボトムアップに拡張する
  14. 14. コンパイルフェーズ約10フェーズ (parserはGaucheのreadで代用)ライブラリ追加 ⇒ マクロ展開 ⇒ 内部define除去 ⇒ begin構文単純化 ⇒ CPS変換 ⇒ 代入, free変数, ヒープリテラル解析 ⇒ 代入boxing/un-boxing ⇒ ヒープリテラルlifting ⇒ lambdalifting ⇒ プロローグ追加, コード生成
  15. 15. マクロ展開詳しくはLisp in Small Piecesコンパイル時に評価器が必要マクロもコンパイルして実行 OR interpreterを実装しておく OR 外部プログラムを呼び出すGaucheのevalを呼んで実装
  16. 16. 継続の実装スタックコピー OR CPS変換スタックコピーの実装についてはfault oncontinuation (Gauche-devel-jp)でぐぐるコード変換だけで実装できることから、CPS変換を選択
  17. 17. CPS変換詳しくはThe 90 minute Scheme to C compilerなんらかの簡約を行うか、素朴な変換を止めないとコードがとても大きくなります継続がない場合はSSAと等価だそうCPS変換するとすべて末尾呼び出しになります
  18. 18. クロージャの実装プログラミング言語の進化を追え: 第4回 大人のためのブラックボックス読解講座interpreterならstatic linkをたどる実装が簡単クロージャの自由変数を引数に追加して除去する、lambda liftingで実装
  19. 19. Code Generation Architecturehttp://www.cs.indiana.edu/eip/compile/back.htmlframe, closure, allocation, accumulator,temporary*3 registers + 独自のスタックDestination-driven Code Generation: 単純かつトップダウンのアプローチ
  20. 20. GCCheney’s two-finger collectorをCで実装current frame pointer, current closure pointer,accumulator, temporary registersをrootとする当初の目的だったGCの実装はわずか300行……
  21. 21. FFI calloutデータ変換とメモリ管理が要点C friendlyな型 (null終端文字列や32bit word)を保持できるようにして、Scheme側で自動変換。stable pointerではありません(dlsym asciiz) (foreign-call fptr args size)libffiなどは使えないのでOSXのABIに従いcall
  22. 22. FFI callbackScheme↔Cの相互呼び出しがあり得るtall callのみでなくなる (フレームが伸びる)コンテキストスイッチのため実行時にtrampolineコードを生成いつGCが動いてもよいような配慮
  23. 23. デモ
  24. 24. 振り返ると1 word 64bitにすべき モデルと実装のギャッだった プが埋まったinterpreterなら簡単な 竹内先生の最終講義をことが難しい 聞きに行ったり脳がとけるかと思った ちょっと草植えときまGCのバグ すね型言語 Grassが分 かるようになったり ま、とにかく楽しかったです

×