コンパイラ演習 第 6 回 2005/11/17 大山 恵弘 佐藤 秀明. 今回の内容 実マシンコード生成 – アセンブリ生成 (emit.ml) – スタブ、ライブラリとのリンク 末尾呼び出し最適化 – 関数呼び出しからの効率的なリターン (emit.ml) –[ 参考 ]CPS 変換 種々の簡単な拡張.

Slides:



Advertisements
Similar presentations
1 B10 CPU を作る 1 日目 解説 TA 高田正法
Advertisements

コンパイラ演習 第 6 回 (2011/11/17) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴 潮田 資秀 小酒井 隆広 山下 諒蔵 佐藤 春旗 大山 恵弘 佐藤 秀明 住井 英二郎.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
2006/10/26 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第5回 関数(1) 情報・知能工学系 山本一公
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
2006/11/9 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
ML 演習 第 1 回 佐藤 春旗, 山下 諒蔵, 前田 俊行 May 30, 2006.
ML 演習 第 8 回 2007/07/17 飯塚 大輔, 後藤 哲志, 前田 俊行
2006/10/5 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2006/11/30 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
2006/10/12 山下 諒蔵 佐藤 春旗 前田俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2012年度 計算機システム演習 第4回 白幡 晃一.
プログラミング演習II 2004年10月19日(第1回) 理学部数学科・木村巌.
2006年度 計算機システム演習 第4回 2005年5月19日.
情報処理Ⅱ 2005年12月9日(金).
コンパイラ演習 第12回 2006/1/26 大山 恵弘 佐藤 秀明.
2006/12/7 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2007/1/18 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2006/10/19 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井英二郎
2006/11/02 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2006/11/16 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月10日、H.15(‘03)] 今日のメニュー 1 前回の課題の復習
コンパイラ演習 第 4 回 (2011/10/27) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴
第4回放送授業.
の まとめ 2007/04/02 (Mon) / d;id:hzkr
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
2007/1/11 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
Tokuda Lab. NISHIMURA Taichi
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
型付きアセンブリ言語を用いた安全なカーネル拡張
コンパイラの解析 (4) 例外処理.
プログラミング言語入門 手続き型言語としてのJava
関数の定義.
第10回関数 Ⅱ (ローカル変数とスコープ).
アルゴリズムとデータ構造1 2006年6月16日
プログラミング言語入門.
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
依存型で型付けされた 副作用のある関数のための 型保存コンパイラ
コンパイラ演習 第11回 2006/1/19 大山 恵弘 佐藤 秀明.
コンパイラ資料 実行時環境.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
オブジェクト指向プログラミングと開発環境
演習0 func0, func1, func2を作成せよ. main()関数の中で,func0()を呼び出しを実行せよ.
2007/6/12(通信コース)2007/6/13(情報コース) 住井
コンピュータアーキテクチャ 第 2 回.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
計算機プログラミングI 木曜日 1時限・5時限 担当: 増原英彦 第1回 2002年10月10日(木)
コンピュータアーキテクチャ 第 2 回.
コンピュータアーキテクチャ 第 5 回.
コンピュータアーキテクチャ 第 4 回.
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
2006/6/27(通信コース)2006/7/5(情報コース) 住井
コンピュータアーキテクチャ 第 5 回.
~sumii/class/proenb2009/ml6/
X64 函数呼び出し規約 長谷川啓
コンパイラ 第12回 実行時環境 ― 変数と関数 ― 38号館4階N-411 内線5459
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
関数と再帰 教科書13章 電子1(木曜クラス) 2005/06/22(Thu.).
プログラミング演習I 2003年6月11日(第9回) 木村巌.
第10回 関数と再帰.
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
情報処理Ⅱ 小テスト 2005年2月1日(火).
プログラミング言語論 プログラミング言語論 演習5 解答と解説 演習5 解答と解説 1 1.
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
6.5 最終コード生成 (1)コードの形式 ①絶対2進コード(AB : absolute binary) 命令後のオペランドが絶対番地指定。
Presentation transcript:

コンパイラ演習 第 6 回 2005/11/17 大山 恵弘 佐藤 秀明

今回の内容 実マシンコード生成 – アセンブリ生成 (emit.ml) – スタブ、ライブラリとのリンク 末尾呼び出し最適化 – 関数呼び出しからの効率的なリターン (emit.ml) –[ 参考 ]CPS 変換 種々の簡単な拡張 –MinCaml にない機能

実マシンコード生 成

アセンブリ生成 save/restore をストア / ロードとして明示 化 – スタックの状態を追跡 (stackmap, stackset) if 文の合流後は両方のスタックの積集合をとる 関数呼び出し規約の明示化 – 引数を正しいレジスタにセット (shuffle 関数 ) – リターンアドレスの save/restore – スタックポインタの管理 条件分岐の明示化 – 分岐用・合流用のラベルを導入 他は単純

外部ファイル スタブ (stub.c) – ヒープとスタックを確保 – その後 MinCaml のエントリポイントを call ライブラリ (libmincaml.s) – 外部関数を定義 入出力 配列操作 数値計算 自作 CPU 向けの外部ファイルも必要かも – アーキテクチャ次第

ビルドの流れ stub.c MinCaml ソー ス SPARC アセンブ リ MinCaml コンパ イラ 自作 CPU アセンブ リ 自作アセンブ ラ 自作リンカ 自作 CPU バイナ リ SPARC バイナ リ libmincaml. s ( 自作スタ ブ ) ( 自作ライブラ リ )

末尾呼び出し最適化

末尾呼び出し let rec fact x r = if x <= 1 then r else fact (x – 1) (r * x) 関数の最後の処理が call

単純にコンパイルすると … let rec fact x r = if x <= 1 then r else fact (x – 1) (r * x) save(R ret ) add R sp, 4, R sp call fact nop sub R sp, 4, R sp restore(R ret ) retl nop 返り番地だけから なるフレームを構成 返り番地を pop して 直ちにリターン

その結果 main 関数のフレーム return address 無駄なフレームが 積みあがる!

何がいけなかったのか ? どうすればよいのか ? 問題の元凶 : 末尾呼び出し直後の地点に 律義にリターン – 時間的に無駄 何もしない地点へわざわざリターン – 空間的にも無駄 リターンするために、返り番地を余分に退避 することがないなら、呼び出し元に直接 返ればよい ! – コンパイラが末尾呼び出しを認識

let f x = … (g 8) - 3 … let g y = h (y+1) let h z = z * 2

末尾呼び出し最適化 末尾呼び出し時の無駄なジャンプ・退避 を除去 cf. 末尾再帰 – 関数の最後の処理が自分自身の再帰呼び出 し – 末尾呼び出し最適化により、ループに変換

「 if の直後に return 」する場合 合流する必要がない cmp x, y bg L 1 nop... ( then 節)... b L 2 nop L 1 :... ( else 節)... L 2 :retl nop cmp x, y bg L 1 nop... ( then 節)... retl nop L 1 :... ( else 節)... retl nop

「 call の直後に return 」する場 合 call をただの goto にできる save( R ret ) add R sp, n, R sp call L f nop sub R sp, n, R sp restore( R ret ) retl nop b L f nop

実装 変換中の式が末尾かどうかを管理 –Tail: 末尾 末尾呼び出し最適化を実行、または 結果を返り値用のレジスタにセットしてリター ン –NonTail(r): 末尾でない 結果をレジスタ r にセット

[ 参考 ]CPS 変換 すべての call や if を tail にしてしまう ! –nontail な関数適用 / 条件分岐の継続を生成 「その後にすること」をクロージャで表現 – すべての関数定義 / 関数適用に 仮引数 / 実引数として継続を追加 – 関数の戻り値は継続に渡す α 変換および A 正規化の完了した K 正規形 に対して行うと簡単

CPS 変換のイメージ let rec f x = let a = p 100 in let b = q 200 in x + a + b + r 300 この部分を実行する関数(クロージャ)を 新たに導入。 p の引数として渡す p は実行が終わったら、引数にもらった 関数(クロージャ)を呼び出すことにより 「復帰」する

CPS 変換の利点 / 欠点 利点 : 以降の処理が容易 – 関数呼び出し時の save/restore が不要 – 「リターンアドレス」の概念が不要 – スタックも不要 欠点 : クロージャが頻繁に生成 / 適用され る – 効率的なヒープ管理の必要性 inter-procedural なレジスタ割り当て エスケープ解析 generational garbage collection

種々の簡単な拡張

レコード、 Variant レコード : フィールドがアルファベット 順に並んだ tuple とみなす { foo = 3; bar = 7 } = { bar = 7; foo = 3 } ⇒ (7, 3) Variant: コンストラクタを整数で表し、 それを第 1 要素とする tuple にする type  list = Nil | Cons of  *  list として Nil ⇒ (0) Cons(x, y) ⇒ (1, x, y)

λ 抽象、部分適用 λ 抽象 : let rec に置換 fun x → M ⇒ let rec f x = M in f ( f は fresh な変数名) 部分適用 : let rec と完全適用に置換 たとえば let rec f x y = x - y なら f 3 ⇒ let rec g y = f 3 y in g ( g は fresh な変数名) – 関数の型情報が必要

共通課題 (1/3) 以下のプログラムはどのようなアセン ブリにコンパイルされるか、末尾呼び 出し最適化をしない場合とする場合、 それぞれについて説明せよ。 ヒント : 末尾呼び出し最適化をする場合、手続 き型言語でループを用いて書いた gcd と同じア センブリになる(はず) let rec gcd m n = if m <= 0 then n else if m <= n then gcd m (n – m) else gcd n (m – n) in print_int (gcd )

共通課題 (2/3) 以下のプログラムを手動で CPS 変換せよ。 K 正規化はしてもしなくてもよい 余裕があれば、 CPS 変換した場合としなかった 場合でどのようなアセンブリにコンパイルされ るか、両者を比較してみよう let rec ack x y = if x <= 0 then y - -1 else if y <= 0 then ack (x - 1) 1 else ack (x - 1) (ack x (y - 1)) in print_int (ack 3 10)

共通課題 (3/3) 「種々の簡単な拡張」 ( の一部 ) を用いる ML プログラムを書け。それを既存の ML コンパイラがどうコンパイルするか調べ、 解説せよ。 – 同程度以上に複雑な他のプリミティブについ て調べてもよい

課題の提出先と締め切り 提出先 : 締め切り : 2 週間後( 12/1 )の午後 1 時 Subject: report 6 本文にも氏名と学籍番号を明記のこと

課題の提出についての注意 プログラムだけでなく、説明・考察・感 想なども書くこと 基本的にはメールの本文に解答を記述 多くのソースを送る必要がある課題では、 ソースを tar ファイルなどに固めてメール に添付のこと

今後の予定 次回からは応用編です 11/24: 休講 12/1: 休講 12/8: Garbage Collection 12/15: オブジェクト 12/22: Polymorphism 1/12: 例外処理 1/19: エスケープ解析 1/26: リージョン推論 ?