2006/10/26 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎 コンパイラ演習 第 4 回 2006/10/26 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
今日の内容 仮想マシンコード生成 よりアセンブリに近い、 計算機のメモリを意識したコードに変換 関数呼び出し規約
仮想マシンコード 生成
クロージャ変換後のコード アセンブリ言語とはまだ隔たりがある データ構造の操作に伴うメモリ操作が 明示的でない レジスタが明示的でない データ構造の操作に伴うメモリ操作が 明示的でない レジスタが明示的でない 関数呼び出しに伴う変数の退避・回復が明示的でない if-then-else がある
MinCaml における今後の変換 データ構造の操作に伴う メモリ操作の明示化 → virtual.ml レジスタの明示化 → regalloc.ml 関数呼び出しに伴う 変数の退避・回復の明示化 → regalloc.ml if-then-else をラベルとブランチに変換 → emit.ml
MinCaml の仮想マシンコード (virtual.ml と regalloc.ml の間) メモリ操作が明示的 レジスタが非明示的 レジスタが無限個 変数の退避・回復が非明示的 if-then-else あり
MinCaml における 仮想マシンコード生成 (1) 以下の処理を行う命令列を生成 クロージャ作成 クロージャからの値の読み出し タプル作成 タプルからの値の読み出し 配列の値の読み出し・書き込み let 式を命令の列に変換
MinCaml における 仮想マシンコード生成 (2) 関数の引数を浮動小数とそれ以外に分離 後のフェーズのための準備 等号・不等号プリミティブを浮動小数用とそれ以外用に分離 型情報を利用 浮動小数定数テーブルを作成
関数呼び出し規約
関数呼び出し規約 関数を呼び出すコードと 呼び出される関数のコードとの間の約束事 関数呼び出し時に各レジスタが保持すべき値 関数を呼び出すコードと 呼び出される関数のコードとの間の約束事 関数呼び出し時に各レジスタが保持すべき値 関数呼び出し時の、あるべきメモリの状態 呼び出された関数によるレジスタ・メモリへの変更の仕方 各コンパイラ・アーキテクチャごとに 大体決まっている
関数呼び出し規約 (例): レジスタの使い方 汎用レジスタ: R0 から Rn-1 まで n 個 返り番地用レジスタ: Rret ヒープポインタ用レジスタ: Rhp スタックポインタ用レジスタ: Rsp
関数呼び出し規約 (例): 呼び出す側 生きている変数の値をスタックに退避する 呼び出される関数のクロージャのアドレスを R0 に入れる (クロージャを通じて呼び出す場合) 引数を R1, R2, R3, … に入れる 返り番地を Rret に入れる クロージャから、呼び出される関数のアドレスを取り出す (クロージャを通じて呼び出す場合) 呼び出される関数のアドレスにジャンプする 生きている変数の値をスタックから回復する
関数呼び出し規約(例): 呼び出される側 R0 の指すクロージャから自由変数の値を取り出す(自由変数がある場合) R1, R2, R3, … を引数として関数本体を実行する 返り値を R0 に入れる Rret にジャンプする
レジスタの使い方の例: SPARC g0 不使用: 常に値が0なので g1~g7 不使用: ライブラリの都合 o0~o5 一般レジスタとして使用(R13~R18) o6 不使用: OSやデバッガのため o7 Rret l0~l7 一般レジスタとして使用(R5~R12) i0, i1 Rsp, Rhp i2~i5 一般レジスタとして使用(R1~R4) i6, i7 不使用: OSやデバッガのため (※ 標準とは異なるので、main 関数や外部関数 にはスタブが要る)
レジスタの使い方の例: POWER r0 不使用: 命令によっては値が0なので r2 不使用: ライブラリの都合 r3~r30 一般レジスタとして使用(R1~R28) r1,r31 Rsp, Rhp LR Rret (※ 標準とは異なるので、main関数や外部関数 にはスタブが要る)
Callee-save register を導入する手もある 各レジスタを caller 側で保存・復元するかcallee 側で保存・復元するかは規約しだい Callee-save register は 小さい関数、leaf 関数で特に効く
メモリの使い方(例) ヒー プ Rhp 未使 用 Rs p Rretの退避 先 スタッ ク 汎用レジスタの退避 先 関数フレーム lo w hig h
共通課題 Web 検索エンジンや GCC などを利用してPOWER 以外のアーキテクチャで 標準の関数呼び出し規約が どうなっているか、 (少なくとも)一つ調べて述べよ。
課題の提出先と締め切り 提出先: compiler-enshu@yl.is.s.u-tokyo.ac.jp 締め切り: 2 週間後 (11/9) の午後 1 時 Subject: Report 4 <学籍番号> <アカウント> 本文にも氏名と学籍番号を明記のこと