2006/11/02 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎

Slides:



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

コンパイラ演習 第 6 回 (2011/11/17) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴 潮田 資秀 小酒井 隆広 山下 諒蔵 佐藤 春旗 大山 恵弘 佐藤 秀明 住井 英二郎.
コンパイラ演習 第 12 回 (2012/01/05) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴 潮田 資秀 小酒井 隆広 山下 諒蔵 佐藤 春旗 大山 恵弘 佐藤 秀明 住井 英二郎.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第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 飯塚 大輔, 後藤 哲志, 前田 俊行
第11回 整列 ~ シェルソート,クイックソート ~
ソフトウェア基礎科学 授業資料: 論理関係(logical relations)のお話
2006/10/5 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2006/11/30 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
コンパイラ演習番外編 (その2): JVM コンテスト
コンパイラ演習番外編 (その1): min-rt 改 コンテスト
最適化ソルバーのための Python言語入門
2006/10/12 山下 諒蔵 佐藤 春旗 前田俊行 大山 恵弘 佐藤 秀明 住井 英二郎
コンパイラ演習 第 8 回 (2011/12/01) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴
2012年度 計算機システム演習 第4回 白幡 晃一.
プログラミング演習II 2004年10月19日(第1回) 理学部数学科・木村巌.
コンパイラ演習 第 9 回 (2011/12/08) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴
コンパイラ演習 第12回 2006/1/26 大山 恵弘 佐藤 秀明.
2006/12/7 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2007/1/18 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2006/10/19 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井英二郎
2006/11/16 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月10日、H.15(‘03)] 今日のメニュー 1 前回の課題の復習
コンパイラ演習 第 4 回 (2011/10/27) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴
2007/1/11 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
二分探索木によるサーチ.
型付きアセンブリ言語を用いた安全なカーネル拡張
プログラミング言語入門 手続き型言語としてのJava
情報工学演習I 第12回 C++の演習4(インライン展開).
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
第10回関数 Ⅱ (ローカル変数とスコープ).
最適化の方法 中田育男著 コンパイラの構成と最適化 朝倉書店, 1999年 第11章.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第2回 ファイル処理 情報・知能工学系 山本一公
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
高度プログラミング演習 (08).
レジスタの割付け 中田育男著 コンパイラの構成と最適化 朝倉書店, 1999年 第12章5節.
第7回課題 フィボナッチ数列 (コード:p.171) について,fib(4) を呼び出したときの起こる出来事は以下の通りである.
25. Randomized Algorithms
コンパイラ演習 第11回 2006/1/19 大山 恵弘 佐藤 秀明.
第5回放送授業.
コンパイラ資料 実行時環境.
オブジェクト指向プログラミングと開発環境
11.再帰と繰り返しの回数.
演習0 func0, func1, func2を作成せよ. main()関数の中で,func0()を呼び出しを実行せよ.
JAVAバイトコードにおける データ依存解析手法の提案と実装
2007/6/12(通信コース)2007/6/13(情報コース) 住井
アルゴリズムとプログラミング (Algorithms and Programming)
補講:アルゴリズムと漸近的評価.
コンピュータアーキテクチャ 第 2 回.
実装について 前田俊行.
コンピュータアーキテクチャ 第 2 回.
コンピュータアーキテクチャ 第 5 回.
情報工学概論 (アルゴリズムとデータ構造)
~sumii/class/proenb2010/ml2/
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
2006/6/27(通信コース)2006/7/5(情報コース) 住井
コンピュータアーキテクチャ 第 5 回.
~sumii/class/proenb2009/ml6/
18. Case Study : Imperative Objects
X64 函数呼び出し規約 長谷川啓
プログラミング演習I 2003年6月11日(第9回) 木村巌.
データ構造と アルゴリズムI 第三回 知能情報学部 新田直也.
プログラミング 3 ポインタ(1).
6.5 最終コード生成 (1)コードの形式 ①絶対2進コード(AB : absolute binary) 命令後のオペランドが絶対番地指定。
Presentation transcript:

2006/11/02 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎 コンパイラ演習 第 5 回 2006/11/02 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎

今回の内容 レジスタ割り当て Interference Coalescing (レジスタ合わせ) 生きている変数の save/restore レジスタ溢れ (spilling) 関数呼び出し 条件分岐 相互に依存していて厄介!

MinCamlの方針 そこそこの速さ & そこそこの易しさ MinCaml 方式 regAlloc.target-latespill.ml をもとに説明 各自アルゴリズムを工夫してみてください

レジスタ割り当ての方針 Interference 生きている変数を上書きしない Coalescing (targeting) 無駄な mov はできるだけ減らす

レジスタ割り当ての表現構造 変数からレジスタへの写像として実装 RegMap(x) = Rn 処理の進行とともに写像を逐次更新

レジスタ割り当て写像の操作 …… a ← 1; b ← 2; c ← b; d ← func(a, c); RegMap(a) = R1 RegMap(b) = R2 …… a ← 1; b ← 2; c ← b; d ← func(a, c); RegMap(a) = R1 RegMap(c) = R2 RegMap(d) = R1

生きている変数の save/restore

save 命令、restore 命令 save(x): x の値をスタックに退避 xが他の値で上書きされるおそれのある時 restore(x): x の値をスタックから復帰 いま使いたい変数がレジスタにない時

命令挿入の方針 レジスタ溢れ レジスタが足りないときに適当な変数を save 関数呼び出し 関数を呼び出す前に、生きている変数を save 条件分岐 各分岐先で異なるレジスタに割り当てられた変数は、合流後は改めて restore してから使用

レジスタ溢れの例 (1/2) (汎用レジスタは R0、R1、R2 の3つだけとする) y に割り当てるレジスタは? let rec f a b = let x = -a in let y = -b in x - y - a - b ↓ let rec f R1 R2 = let x = -R1 in let y = -R2 in x - y - R1 – R2 let R0 = -R1 in let y = -R2 in R0 - y - R1 – R2 関数の引数にまず割り当てる 次に最初の変数 x に割り当てる y に割り当てるレジスタは?

レジスタ溢れの例(2/2) 変数 b を一時的にスタックへ退避 let rec f a b = let x = -a in let y = -b in x - y - a - b ↓ let x = -a in save(b); let y = -b in x - y - a - (restore(b); b)

関数呼び出しの例 let x = ... in let y = ... in let z = f x y in if z≦0 then x - 1 else y - 2 ↓ let x = ... in let y = ... in save(x); save(y); let z = f x y in if z≦0 then restore(x); x - 1 else restore(y); y - 2

条件分岐の例 (1/2) ↓ 合流後のレジスタ割り当ては? let a = if f () then x – y else y – x in a + x + y ↓ let a = save(x); save(y); if f () then (restore(x); x) - (restore(y); y) (* regenv = { x→R1, y→R2 } *) else (restore(y); y) - (restore(x); x) (* regenv = { x→R2, y→R1 } *) in a - x + y 合流後のレジスタ割り当ては?

条件分岐の例 (2/2) 合流時にレジスタ割り当てが異なっている変数は RegMap から削除する ↓ 合流後に x、y を改めて restore することになる let a = if f () then x – y else y – x in a + x + y ↓ let a = save(x); save(y); if f () then (restore(x); x) - (restore(y); y) (* regenv = { x→R1, y→R2 } *) else (restore(y); y) - (restore(x); x) (* regenv = { x→R2, y→R1 } *) in a - (restore(x); x) + (restore(y); y)

regAlloc.target-earlyspill.ml regAlloc.ml と同様 どうせ後で save する変数は 定義直後に save ややこしいので参考程度に

regAlloc.target-earlyspill.ml (1/3) regAlloc.ml と同様 どうせ後で save する変数は 定義直後に save ややこしいので参考程度に

regAlloc.target-earlyspill.ml (2/3) 変数 x の退避が必要になったら、 現在の位置に forget 命令を挿入 x のレジスタ割り当てを削除 式を ToSpill コンストラクタに入れて返す 退避の必要な変数がなかったら、 式をレジスタ割り当て NoSpill コンストラクタに入れて返す

regAlloc.target-earlyspill.ml (3/3) ToSpill コンストラクタを受け取ったら、 退避する変数 x の定義までさかのぼる 定義の直後に save(x) を挿入 式のレジスタ割り当てをやり直す NoSpill コンストラクタを受け取ったら、 式をそのまま返す

spill が多すぎるときは... ヒープポインタを (専用レジスタではなく) 汎用レジスタにとる 関数の引数や返値として付け加える ヒープポインタを (専用レジスタではなく) 汎用レジスタにとる 関数の引数や返値として付け加える (x, h)  CallCls(y, h, z1, ..., zn) (x, h)  CallDir(Lf, h, z1, ..., zn) return(x, h) ヒープポインタをメモリ (固定) におく MakeCls 等が稀ならば得 リターンアドレスを (専用レジスタではなく) 汎用レジスタにとる 関数からの return に「戻り先」として付け加える return x to r

共通課題 (1/2) 例にならい、 次式へ save/restore を挿入してみよ どのように入れるのが「より良い」だろうか let x = ... in let y = (if x≦0 then f 1 else 2) in let z = (if y≦3 then x - 4 else g 5) in x - y - z

共通課題 (2/2) 適度に簡単な関数 (フィボナッチ数列、 アッカーマン関数、最大公約数など) に対し、例にならって 手でレジスタ割り当てを行ってみよ。 良いレジスタ割り当てをした結果と 悪いレジスタ割り当てをした結果の両方を提出 レジスタ移動回数に差を作る 少ないレジスタ数を仮定し、spill回数に差を作る etc

課題の提出先と締め切り 提出先: compiler-enshu@yl.is.s.u-tokyo.ac.jp 締め切り: 2 週間後 (11/16) の午後 1 時 Subject: Report 5 <学籍番号> <アカウント> 本文にも氏名と学籍番号を明記のこと