第 4 章 既存のコンパイラをベースとするコンパイラフレームワークの構築 24
4.3 GCC 内部での RTL
4.3.1 RTL を表現するデータ構造
GCC内部におけるRTLの表現にはrtx def構造体とrtunion def共用体が使用され る.rtx def構造体はRTXそのものを表わし,rtunion def共用体は各オペランドを表 わすために使われる.
rtx def構造体
以下にrtx def構造体のメンバのうち,式コード,マシンモード,オペランドに関係す
るものは表4.10に示すとおりである.フラグに関するメンバは,フラグ1つに対して1つ ずつ用意されているので,ここでは省略する.
メンバ 型 説明
code rtx code (16ビット幅) 式コード mode machine mode (8 ビット
幅)
マシンモード
fld rtunion[] オペランドを格納する
表 4.10: rtx def構造体のメンバ
rtunion def共用体
rtunion def共用体はRTXのオペランドを表わす.各メンバはRTLのデータオブジェ
クトである整数,文字列,ベクトル,RTXに対応する.rtunion def共用体のどのメンバ が実際に使用されているかを知るためにはRTXの式コードごとに定められたフォーマッ ト文字列を参照する必要がある.
表4.11にrtunion def共用体のメンバの一部を示す.rtunion def共用体には,これ 以外にもメンバがあるが,GCCの最適化パスの一部で使用されるメンバであるためここ では省略する.
図4.9に示した関数とそれを構成するINSNによる双方向連結リストは第2,第3オペ ランドの型がフォーマット文字’u’で表わされているため,GCCの内部ではrtunion def 共用体のrtxメンバが用いられる.したがってこれらのオペランドはそれぞれ一つ前と一 つ後のINSNへのポインタとなる.
メンバ 型 格納するrtlオブジェクト
rtwint HOST WIDE INT 幅広整数
rtint int 整数
rtstr const char * 文字列
rtx struct rtx def * RTX rtvec struct rtvec def * ベクトル
表 4.11: rtunion def共用体のメンバ
i u u e i e e
rtunion fld[]
rtx_def
fld[0].rtint
fld[1].rtx
fld[2].rtx
fld[3].rtx
fld[4].rtint
fld[5].rtx
fld[6].rtx
図 4.12: フォーマット文字列がiuueieeの場合に参照されるメンバ
4.3.2 RTX オペランドの読み出し
RTXに対してそのオペランドを読み出すためには,まず最初にそのRTXの式コードを 確認し,式コードに対応するフォーマット文字列を決定する.フォーマット文字列によっ てこれから参照しようとするオペランドの型を決定する.これによってはじめて参照する ことができる.
rtl.def
rtl.defには全てのRTX式コード,式の属する式クラス,式のオペランドのフォーマッ
ト文字列が定義されている.また,テキストダンプ用の式コードの名前文字列も定義され ている.
rtl.defでRTXを定義する書式は以下のとおり.GCCの他のソースコードではrtl.def をインクルードし,DEF RTL EXPRを再定義して使用する.
DEF_RTL_EXPR(式コード,
"名前",
"フォーマット文字列",
’式クラス’)
マクロ
rtl.hにはRTXのオペランドにアクセスするためのさまざまなマクロが定義されている.
これらのマクロの多くは基本となる4つのマクロRTL CHECK1,RTL CHECK2,RTL CHECKC1,
RTL CHECKC2を用いて定義されている.この4つの基本となるマクロはフォーマット文字
列に基づいてアクセス使用とするオペランドの型をチェックする.
RTL CHECK1(RTX, N, C1) RTXのN番目のオペランドを返す.そのと きオペランドの型に対応するフォーマット 文字がC1に等しく,かつ,Nがその式の式 コードに対して定められているオペランド の個数に収まっていることをチェックする.
RTL CHECK2(RTX, N, C1, C2) RTL CHECK1に同様だが,参照しようと するオペランドのフォーマットがC1もしく はC2であることをチェックする.
RTL CHECKC1(RTX, N, C1) Nに対してオペランドの個数のチェックを
しない以外はRTL CHECK1と同じ.
RTL CHECKC2(RTX, N, C1, C2) Nに対してオペランドの個数のチェックを しない以外はRTL CHECK2と同じ.
表 4.13: RTXを操作する基本となる4つのマクロ
以下は,RTX CHECKXを使った代表的なマクロ.この他にも多くのマクロが定義されて いる.
/* N番目のオペランドを幅広整数として返す. */
#define XWINT(RTX, N) (RTL_CHECK1(RTX, N, ’w’).rtwint) /* N番目のオペランドを整数として返す. */
#define XINT(RTX, N) (RTL_CHECK2(RTX, N, ’i’, ’n’).rtint) /* N番目のオペランドを文字列として返す. */
#define XSTR(RTX, N) (RTL_CHECK2(RTX, N, ’s’, ’S’).rtstr) /* N番目のオペランドをRTXとして返す. */
#define XEXP(RTX, N) (RTL_CHECK2(RTX, N, ’e’, ’u’).rtx) /* N番目のオペランドをベクトルとして返す. */
#define XVEC(RTX, N) (RTL_CHECK2(RTX, N, ’E’, ’V’).rtvec)