フロントエンドとバックエンドのインターフェース

Slides:



Advertisements
Similar presentations
1 全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える 処理後のデータを出力ファイルに書き出す 画像データ用に確保したメモリを解放.
Advertisements

情報処理Ⅱ 第7回:2003年12月2日(火). 問題(授業がつまらない人のため に) ぷよ連結問題 前提 : フィールドを2次元 配列で定義し,各マスの 「ぷよ」を int 型の値で表現 する. ある地点を入力に取り,そ れと連結する「ぷよ」の個 数を求めよ. 消去できる「ぷよ」 (N 個以上 連結するぷよと,それに隣接する特.
アルゴリズムとデータ構造 第2回 線形リスト(復習).
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
データ構造とアルゴリズム 第10回 mallocとfree
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
プログラミング基礎I(再) 山元進.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
12: コマンドライン引数 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
アルゴリズムとデータ構造 2011年6月13日
条件式 (Conditional Expressions)
プログラミング演習II 2004年12月 21日(第8回) 理学部数学科・木村巌.
情報処理Ⅱ 2007年12月10日(月).
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
演習問題の答え #include #include #define NUM 5 typedef struct { // 構造体の定義 float shincho; // 身長 float taiju; // 体重 } shintai; void hyouji(shintai.
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
プログラミング論 関数ポインタ と 応用(qsort)
第9章 例外処理,パッケージ 9.1 例外処理 9.2 ガーベッジコレクション.
情報処理Ⅱ 第2回 2007年10月15日(月).
精密工学科プログラミング基礎 第10回資料 (12/18実施)
プログラミング 4 記憶の割り付け.
画像処理プログラムの説明.
プログラミング演習I 2003年5月7日(第4回) 木村巌.
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラミング入門2 第11回 情報工学科 篠埜 功.
もっと詳しくArrayクラスについて調べるには → キーワード検索
一時的な型 長谷川啓
2013年度 プログラミングⅡ ~ 計算してみよう ~.
2015年度 プログラミングⅡ ~ 計算してみよう ~.
型の compatibility とポインタ演算
情報処理Ⅱ 第2回:2003年10月14日(火).
記号表の検索と登録 長谷川啓
プログラミング演習I 2004年5月19日(第5回) 理学部数学科・木村巌.
精密工学科プログラミング基礎Ⅱ 第5回資料 今回の授業で習得してほしいこと: 構造体 (教科書 91 ページ)
プログラミング入門2 第9回 ポインタ 情報工学科 篠埜 功.
アルゴリズムとプログラミング (Algorithms and Programming)
C++ 構文解析 構文解析器の状態保存と復元
参照されないリテラル 長谷川啓
コンパイラ 2012年10月29日
アルゴリズムとデータ構造 2012年6月11日
12: コマンドライン引数 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
情報処理Ⅱ 第2回 2005年10月14日(金).
情報処理Ⅱ 第2回 2006年10月13日(金).
アルゴリズムとデータ構造1 2009年6月15日
情報処理Ⅱ 第7回 2004年11月16日(火).
ドキュメントジェネレータ 詳細仕様 長谷川啓
オブジェクト指向言語論 第二回 知能情報学部 新田直也.
X64 函数呼び出し規約 長谷川啓
コンパイラ 2012年10月11日
プログラミング 4 文字列.
Inline 展開のアルゴリズム 長谷川啓
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
アルゴリズムとデータ構造 2010年6月17日
演算子のオーバーロード.
Tacsim の実装 - 実行部分 長谷川啓
PROGRAMMING IN HASKELL
全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える
:: の扱い 長谷川啓.
情報処理Ⅱ 第2回 2004年10月12日(火).
情報処理Ⅱ 2005年11月25日(金).
プログラミング演習II 2004年11月 16日(第5回) 理学部数学科・木村巌.
情報処理Ⅱ 小テスト 2005年2月1日(火).
C言語講座 四則演算  if ,  switch 制御文.
プログラミング演習II 2003年10月29日(第2,3回) 木村巌.
デフォルト引数 長谷川啓.
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
Presentation transcript:

フロントエンドとバックエンドのインターフェース 長谷川啓 2019.03.08

コード生成するために最低限必要なバックエンドの函数 (1) コード生成するために最低限必要なバックエンドの函数 (1) int generator_seed(); フロントエンドをコンパイルしたコンパイラと同じコンパイラによってバックエンドがコンパイルされていることを確認するための函数。また、Cコンパイラのバックエンドが、例えばC++コンパイラのバックエンドとして誤って使われないようにするための函数。 他の動作しているバックエンドと同じ値を返すようにしてください。 int generator_open_file(const char* fn); コード生成の結果を書き込むファイルをオープンするための函数。正常にオープンできた場合は 0 を、そうでなければ 0 以外を返す。

コード生成するために最低限必要なバックエンドの函数 (2) コード生成するために最低限必要なバックエンドの函数 (2) struct interface_t { const scope* m_root; // 記号表 fundef* m_func; // 函数(名前、型等)とパラメータスコープ vector<tac*> m_code; // 函数の 3 番地コード }; void generator_generate(const interface_t* info); 函数のコード生成が必要なタイミングで呼び出される。 あるいは、ファイルの最後で記号表をコードに反映しなければならないときに呼び出される。この場合は interface_t::m_func は 0 で呼び出される。 m_func が 0 でないならば m_root->m_children.back() == m_func->m_param がフロントエンドによって保証される。 m_root->m_children.size() == 1 は C++ コンパイラでは成立しない

コード生成するために最低限必要なバックエンドの函数 (3) コード生成するために最低限必要なバックエンドの函数 (3) int generator_close_file(); generator_open_file でオープンしたファイルをクローズする。正常にクローズできた場合は 0 を、そうでなければ 0 以外を返す。

コード生成するためのオプショナルな函数 (1) void generator_option(int argc, const char** argv, int* error); バックエンドにオプションを受け渡すための函数。argv[0] はジェネレータのパス名が指定され、argv[1] 以降にオプションの文字列がセットされる。 error[0], ..., error[argc-1] に 0 以外の値を書き込むことによってオプションの処理でエラーが発生したことをフロントエンドに伝える。

コード生成するためのオプショナルな函数 (2) void generator_spell(void*); 以前は全く別の目的で使用されていた。VC++6.0時代のソースを参照。 現状では、フロントエンドで 3 番地コードのダンプをするための函数のポインタがこの函数を使用して渡されている。 int generator_sizeof(int id); 引数 id の表す型のサイズをバックエンドに問い合わせる。この呼び出しはコード生成に先立って連続して行われる。id は以下のいずれか: type:: SHORT, type:: INT, type:: LONG, type:: LONGLONG, type:: FLOAT, type:: DOUBLE, type:: LONG_DOUBLE, type:: POINTER この函数が定義されていない場合は、各型のサイズはフロントエンドをコンパイルしたコンパイラと同じサイズになる。

コード生成するためのオプショナルな函数 (3) int generator_sizeof_type() sizeof 演算子の結果の型を type::UINT, type::ULONG, type::ULONGLONG のいずれかを返すことによって決定する。この函数が定義されていない場合は sizeof 演算子の結果の型は unsigned int になる。generator_sizeof と同様にコード生成に先立って1回だけ呼び出される。 int generator_wchar_type() wchar_t の型を type::SHORT, type::USHORT, type::INT, type::UINT, type::LONG, type::ULONG のいずれかを返すことによって決定する。この函数が定義されていない場合は wchar_t の型は unsigned short int になる。generator_sizeof と同様にコード生成に先立って1回だけ呼び出される。 int generator_ptrdiff_type() ptrdiff_t の型を type::INT, type::LONG, type::LONGLONG のいずれかを返すことによって決定する。この函数が定義されていない場合は ptrdiff_t の型は long になる。generator_sizeof と同様にコード生成に先立って1回だけ呼び出される。 bool require_align(); 構造体のレイアウトを決める際にアラインメントが必要でない場合に false を返すようにする。定義しないか、定義して true を返せばアラインメントされてメンバのオフセットが決定される。

コード生成するためのオプショナルな函数 (4) struct long_double_t { void (*bit)(unsigned char* res, const char* str); void (*add)(unsigned char* x, const unsigned char* y); // x := x + y void (*sub)(unsigned char* x, const unsigned char* y); // x := x - y void (*mul)(unsigned char* x, const unsigned char* y); // x := x * y void (*div)(unsigned char* x, const unsigned char* y); // x := x / y void (*minus)(unsigned char* x, const unsigned char* y); // x := -y bool (*zero)(const unsigned char*); double (*to_double)(const unsigned char*); void (*from_double)(unsigned char*, double); bool (*cmp)(goto3ac::op, const unsigned char*, const unsigned char*); }; long_double_t* generator_long_double(); フロントエンドがコンパイル時に行う long double の演算をバックエンドで行うための函数。long_double_t::bit はlong double 型のリテラル(例えば 1.5L など)のビット表現を取得するときに呼び出される。

その他 struct last_interface_t { }; scope* m_root; // 記号表 vector<pair<const fundef*, vector<tac*> >* m_funcs; // 函数と三番地コードの全体 }; void generator_last(last_interface_t* info); ファイルの末尾に到達したときに呼び出される。記号表と函数全体をバックエンドで参照できるようにする。この函数を定義すると、本来解放されるはずのコンパイル時のヒープ領域は解放されない。コード生成のためだけであれば generator_generate を使用するとよい。 C コンパイラでは m_root->m_children.size() == m_funcs->size() であり m_root->children[i] は各 m_funcs[i].first->m_param になっている。

x := y x の型は不完全型ではない。また函数型ではない。 型修飾子なしの x の型がポインタでないならば、型修飾子なしの y の型と compatible である。 型修飾子なしの x の型が型 T1 へのポインタならば、 y は 0 であるか、 型修飾子なしの y の型は型 T2 へのポインタ型で、 T1 の型修飾子なしの型 T’1 と T2 の型修飾子なしの型 T’2 は compatible である。

x := y + z y の型も z の型も格上げされている。 y の型も z の型も算術型ならば、算術変換が行われている。型修飾子なしの x の型は 型修飾子なしの y の型と等価である。 型修飾子なしの y の型がポインタであれば、z の型は整数型であり、型修飾子なしの z の型がポインタであれば y の型は整数型である。前者の場合、x の型と y の型には x := y の条件 3.2 が成立する。

x := y - z 加算の 1, 2と同じ。 型修飾子なしの y の型も z の型もポインタならば、y の型と z の型で x := y の 3.2 の条件が成立している。x の型は ptrdiff_t である。 型修飾子なしの y の型がポインタで z の型が整数型であれば x の型と y の型で x := y の 3.2 の条件が成立している。

x := y * z 加算の 1, 2 と同じ。 y の型も z の型も算術型でなくてはならない。

x := y % z 加算の 1, 2 と同じ。 y の型も z の型も整数型でなくてはならない。

x := y << z, x := y >> z

x := y & z, x := y ^ z, x := y | z 加算の 1, 2 と同じ。

x := -y y の型は格上げされた型である。 y は算術型である。型修飾子なしの x の型は型修飾子なしの y の型と等価となる。

x := ~y y の型は格上げされた型である。 y は整数型である。型修飾子なしの x の型は型修飾子なしの y の型と等価となる。

x := (T)y x の型も y の型もスカラー型である。 型修飾子なしの x の型は T と 等価である。

param y y の型は函数型ではない。 y の型は不完全型も許される。バックエンドは以下のように完全型に変換することで y のサイズを求めることができる。 const type* T = y->m_type; T = T->complete_type(); int size = T->size(); 後続する call との間には param 以外の 3 番地コードが現れることはない。

x := call y, call y 修飾子なしの y の型は函数へのポインタ型か函数型である。 修飾子なしの x の型は函数の戻り値の型と compatible である。 x の型は不完全型ではない。 函数の戻り値の型が void 型以外でも x := call y ではなく call y が生成されることがある。

return y, return return y がある函数の 3 番地コードの一つであるとき、y の型はその函数の戻り値の型と compatible な型で、完全型である。

goto to, to to は 3 番地コードのうちの一つで goto により参照された to は、同じ函数の 3 番地コードの中にあることがフロントエンドによって保証される。

if y op z goto to op は ==, !=, <, >, <=, >= のいずれか 以下のいずれかが成立 y と z は算術変換されている 型修飾子なしの y の型がポインタ型ならば、y の型と z の型で x := y における条件 3.2 が成立する。 op が ==, != の場合、型修飾子なしの y の型がポインタならば z は 0 でもよい。型修飾子なしの z の型がポインタならば y は 0 でもよい。

x := &y y は定数ではない。 x の型と y の型へのポインタとの間に x := y における条件 3.2 が成立する。

*y := z, x := *y z の型、x の型は函数型以外の完全型である。この型を T とすると y の型は型 T へのポインタか、型修飾子付きの T へのポインタである。

x[y] := z (1) x := y[z] (2) オフセットを表す (1) の y と (2) の z は整数型である。

x := alloca y x の型は variable length array である。 x が参照されるのは x := alloca y の後である。 y の型は整数型である。

X := asm string, Y, R X はこの 3 番地コードにより変更される可能性のあるものすべてを表す。

x := va_start y, x := va_arg y, T, va_end y va_start(x,y), x = va_arg(y,T), va_end(y) にそれぞれ対応している。