レジスタの割付け • • • • 中田育男著 コンパイラの構成と最適化 朝倉書店, 1999年 第12章5節 様々な問題 • レジスタ割付けのタイミング – 命令語の選択の後 • レジスタは無限にあると仮定して命令語を作る。 – 命令語の選択の前 • 中間コードの変数をレジスタに割り当ててから 目的コードを生成。 – 命令語を作るたびにレジスタ割付け • レジスタ割付けの範囲 – プログラム全体 – 1つのサブルーチン – ループ(多重ループの内側から) 様々な問題 • どのレジスタを割付けの対象とするか。 – できる限り範囲を広げる。 – レジスタの役割を決めてしまう。 • 大域的なレジスタ・局所的なレジスタ • サブルーチンの引数や結果の値 簡単な割付け法 • 変数の参照回数 変数 … 中間コードの変数や命令語のレジスタ • 参照頻度の高いものから順次に割り付ける。 • n-1までこれで割付ける。 n: レジスタの数 • それ以外の変数は残したレジスタにLoadする。 簡単な割付け法(その二) • プログラムの先頭から順次割付ける。 • 空いているレジスタがなくなったら… – その場所以降で次に使われる場所が最も 遠い変数が入っているレジスタ – その場所以降でその値が使われる回数が 最小のもの – その値が最近使われたところから その場所までの長さが最も長いもの • を選んでその内容を退避して利用。 生存区間の干渉グラフを使った レジスタ割付け • 生存区間の干渉グラフ – 生存区間をノードとし、生存区間に重なりのある 2つの生存区間を辺で結んだ無向グラフ • 変数の生存区間 – 変数が生きている区間 – 生きているとは、その値が使われる可能性が あるということ。 – 大域的にはデータの流れの解析が必要。 生存区間 do i = 1: a = 2: b = 3: c = 4: d = end do … c d a b * + – * d a 5 c 1 2 3 4 a b c d 干渉グラフ a 1 2 3 4 a b d b c d c 生存区間の干渉グラフを使った レジスタ割付け • 干渉グラフにおいて、ノードxとyが辺で 結ばれていたら、同じレジスタに割付け することはできない。 • 同じレジスタ番号=同じ色 • レジスタ数=色の数 • 彩色問題 • NP困難 Chatinのアルゴリズム 生存区間から干渉グラフGを作る spill_listを空とする while Gは空でない do if deg(x)<Nなるxが存在する then x(およびxからのすべての辺)をGから取り除く else Gのノードxを選びxをspill_listに加える x(およびxからのすべての辺)をGから取り除く end if end while if spill_listが空 then 取り除いた順序の逆順にノードに彩色する。 else spill_listの各ノードxの生存区間を分割する このアルゴリズムの先頭に戻る end if 例(N=3) a c h b d f e g 例(N=3) a c h b d e g f d,e 例(N=3) a h b d e g c b,a f d,e 例(N=3) a h g b e d* h,g,b,e c b,a f d,e 例(N=3) dの生存区間を分割 このためには、 生存区間のグラフを 参照しなければならない。 a c h b d d’ g f e スピル 分割の遅延 a h g b e d* h,g,b,e c b,a f d,e 分割の遅延 a h b g e d* c f b,g h,g,b,e b,a d,e 分割の遅延 a h g b e d* c f a b,g h,g,b,e b,a d,e 分割の遅延 h g a b e d* c f g,h a b,g h,g,b,e b,a d,e 分割の遅延 g h a b e d* c f g g,h a b,g h,g,b,e b,a d,e 分割の遅延 g h a b e d* c f g g,h a b,g h,g,b,e b,a d,e 分割の遅延 g g h a b e d* c f 1 g g,h a b,g h,g,b,e b,a d,e 分割の遅延 h g g h a b e d* c f 1 2 g,h a b,g h,g,b,e b,a d,e 分割の遅延 a h g g h a b e d* c f 1 2 3 a b,g h,g,b,e b,a d,e 分割の遅延 a h b g g h a b e d* c f 1 2 3 1 b,g h,g,b,e b,a d,e 分割の遅延 a h g b e g h a b e d* c f 1 2 3 1 2 h,g,b,e b,a d,e 分割の遅延 a h b d e g g h a b e d* c f 1 2 3 1 2 3 b,a d,e 分割の遅延 a c h b d e g g h a b e d* c f 1 2 3 1 2 3 2 d,e 分割の遅延 a c h b d f e g g h a b e d* c f 1 2 3 1 2 3 2 1 生存区間の合併 • コピー命令 a = b があるときに、 aとbに同じレジスタを 割り付けて、コピー命令を不要とする。 • 積極的な合併 – スピルの原因 • 保守的な合併 • 繰り返し合併 保守的な合併(MCIiJ Chapter 11) • Briggs – 合併ノードabと隣り合うノードのうち、 K個以上のノードと隣り合うものの数は Kより小さい。 • George – aと隣り合う任意のノードtに対して、 tはbと干渉しているか(tとbは隣り合うか)、 tはKより少ない数のノードとしか隣り合わない K: 使えるレジスタ数 繰り返し合併の例 使えるレジスタ数は4 f e j k b m d h g c Briggsによると 合併はできない。 まず単純化 使えるレジスタ数は4 f e j k b d h g c m まず単純化 使えるレジスタ数は4 f e j k b d g c m まず単純化 使えるレジスタ数は4 f e j k b d c m まず単純化 使えるレジスタ数は4 f e j b d c m まず単純化 使えるレジスタ数は4 e j b d c m まず単純化 使えるレジスタ数は4 j b d c m まず単純化 使えるレジスタ数は4 j b d c 合併 使えるレジスタ数は4 jb d c 合併 使えるレジスタ数は4 jb dc
© Copyright 2024 ExpyDoc