2008年11月28日金曜日

抽象構文

具象構文 (concrete syntax) というのは、プログラムのテキスト表現。要するに文字列。

コンパイラの中では、データ構造(内部表現)に変換される。
データ構造は文字列ではないんだけど、一対一に具象構文と対応するので、抽象構文表現 (abstract syntax representation) とも呼ばれる。
構文は木構造(ツリー)になるので、抽象構文木と言われることが多い。

プログラム ⇔ GENERIC (プログラムの抽象構文木)
アセンブリ ⇔ RTL IR (アセンブリの抽象構文木)

という対応関係がある。コンパイラにとっては、具象表現は単なる入出力フォーマットに過ぎない。
GCC のフレームワークは、対応している全ての言語のセマンティクスを表現できる。
その意味で、構文は GCC にとっては瑣末な問題となる。
どの言語で書かれていても、同じセマンティクスに対応するシンタクスからは、同じコードが出る。
セマンティクスの表現が内部表現そのものであると言える。

最適化は GIMPLE という単純な表現に変換してから行われる。

フロントエンド : GENERIC
ミドルエンド  : GIMPLE
バックエンド  : IR RTL

この構造は GCC 4.0 からで、さらに柔軟な最適化フレームワークを求めていた Redhat によって達成された。
それまでは、個別のフロントエンドで RTL を出すところまでを対応していた。言語ごとの共通表現は RTL しか無かった。
最適化も、RTL のレベルの局所的なものだけが共通化されていた。
現在の GCC では、ベクトル化や OpenMP なども、共通のミドルエンドルーチンで最適化される。

GCC の内部で、GENERICS は tree と呼ばれるデータ構造で扱われる。
IR RTL は rtx と呼ばれるデータ構造で扱われる。

RTL にも二種類があって、MD RTL と IR RTL がある。

MD は Machine Description (マシン定義)
IR は Intermediate Representation (中間表現)

MD RTL は、パターンマッチングルールの記述で、データ構造ではなく、直接 C コードに変換され、GCC 本体にコンパイル・リンクされる。
中間表現が IR RTL で記述されるのだから、変換ルールも RTL で記述すると、パターンマッチングが簡単に書ける。
MD RTL は、巨大な switch case 文も展開される。2 万行ぐらいの i386.md を変換すると、11 万行ぐらいの C プログラムになる。
./configure --targe=... で指定されるとき、どの md ファイルが組み込まれるのかが決定する。

0 件のコメント: