2. コンパイラ・ドライバ


 コンパイラ・ドライバはコンパイラの部品をつなぎ合わせてコンパイラを構成する ためにものである。COINSには標準のコンパイラ・ドライバとして

  coins.driver.Driver

というクラスが用意されている。このDriverはCコンパイラを構成するものであるが、 COINSの標準ドライバという意味でCOINS コンパイラ・ドライバとも呼ばれる。

 新しい言語のコンパイラ・ドライバを得るためには、この Driverのサブクラスを作って、フロントエンドの呼び出し部分だけをオーバライドして その言語のフロントエンドを呼び出すようにすればよい。実際に、COINSのFortranコンパイラ (5. フロントエンドの5.2)、 PL0コンパイラ、 のフロントエンドはそのようにして作られている。

 したがって、これらのコンパイラでは標準のDriverで使える各種のオプション機能が ほとんどそのまま使える。

 以下では、COINS コンパイラ・インフラストラクチャに興味があるが、ま だ使用したことはないという方に向けて、 COINS のドライバ部分の設計方針、 構成、使い方などを解説している。

 COINS コンパイラ・インフラストラクチャは、主に、新しいコンパイラを作 りたい人が簡単にそれをできるように支援するためのフレームワークであるの で、ドライバ部分もそれを支援することを主目的としている。このため、ドラ イバ部分は、コンパイラ・ドライバを作成するための Java 言語 API と、そ れを利用して作られたコンパイラ・ドライバから成っている。

現在 のリリースには、コマンド・ライン・インタフェース(CLI)を利用した、オー ソドックスなスタイルのコンパイラ・ドライバ(CLI ドライバ)が含まれてい る。それを以下では、たんにコンパイラ・ドライバと呼んでいる。

2.1 コンパイラ・ドライバの設計

2.1.1 設計方針

 COINS のユーザは、次の2種類に分かれると想定した。
 前者のユーザは、次のような目的を持っているかもしれない。
これらを可能とするために、「新しいコンパイラ」は、「新しいコンパイラ・ ドライバ」を必要とするであろう。 COINS は、コンパイラ・ドライバを簡単 にプログラミングするためのドライバ API を提供している。

 後者のユーザを、以下では「オペレータ」と呼ぶ。また、断りなく「ユーザ」 と書かれている場合、それはオペレータ以外のユーザを指す。

 オペレータはコンパイラを使うために複雑な手順を踏むことはしたくなかろ う。可能ならば Makefile の CC 変数を変更するだけで済ませたいに違いない。 このため、 COINS は、上記のドライバ API を使用して、コマンド・ライン・ インタフェース(CLI)を利用したオーソドックスなスタイルのコンパイラ・ ドライバ(CLI ドライバ)を提供している。 CLI ドライバは、コマンド文法 や基本的なオプションの意味について、 gcc と多くの共通点を持っている。

2.1.2 構成

 COINS コンパイラ・ドライバが提供するフレームワークの全体構成を図1に 示す。
     ユーザ ┏━━━━━━┓┏━━━━━━━┓┏━━━━━━━┓
     記述層 ┃ドライバ実装┃┃ドライバU/I┃┃サフィクス規則┃
         ┗━━━━━━┛┗━━━━━━━┛┗━━━━━━━┛
         ┏━━━━━━━━━┓ ┏━━━━━━━━━━━━┓
     API層┃ トレースAPI ┃ ┃ コンパイル仕様API ┃
         ┃ 警告API   ┃ ┃            ┃
         ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━┛
         ┏━━━━━━━━━━━━━━━━━━━━━━━━┓
         ┃          エンジン          ┃
         ┗━━━━━━━━━━━━━━━━━━━━━━━━┛

	   図1 COINS コンパイラ・ドライバのフレームワーク
ユーザは、次の3種類のものを(必要ならば)準備する。
ドライバ・ユーザ・インタフェース(ドライバ U/I)
ドライバ U/I とは、次のことを行うものである。 コンパイル仕様オブジェクトとは、その提供する方法にした がってオペレータが明示的または暗黙に指定した、コンパイ ル対象のファイル名やコンパイル・オプションを保持するオ ブジェクトである。「方法」とは、 CLI かもしれないし、 GUI かもしれない。
ドライバ実装
ドライバ実装は、エンジンから呼び出される次のサービスを 実装するものである。 ドライバ実装には、エンジンからコンパイル仕様オブジェク トが引き渡されるので、上記の実現のためにこれを参照する。
サフィクス規則
サフィクス規則とは、「どのサフィクスを持つファイルに対 してどの処理を行なうとどのサフィクスを持つファイルが生 成されるか」を記述した規則である。 COINS は、 C, Fortran, Java に対応しているデフォルトの サフィクス規則ファイルを提供している。ユーザはこれを変 更することで、異なるサフィクス規則を実現して良い。
各 API およびエンジンは次の機能を提供している。
エンジン
ドライバ U/I から受けとったコンパイル仕様を元に、サフィ クス規則を解釈して、ドライバ実装の対応するサービスを、 順に呼び出す。生成されたファイルは、サフィクス規則に従っ て命名される。
コンパイル仕様 API
コンパイル仕様の作成と参照のための API である。コンパ イル対象のファイル名、およびオプションの指定/解除/参照 が可能である。
ユーザが自由にオプションを定義できるように、「COINS オ プション」と呼ばれるオプション体系が用意されている。 ドライバ U/I は、自由に COINS オプションを定義して値を 設定することができ、ドライバ実装は、それを参照すること ができる。
トレース API
オペレータが指定したトレース・オプションを解釈し、特定 のトレース・メッセージを出力をするかどうかを判断し、出 力する機能を持つ。
警告 API
オペレータが指定した警告オプションを解釈し、特定の警告 メッセージを出力するかどうかを判断し、出力する機能を持 つ。

2.2 コンパイラ・ドライバの使い方

 COINS のリリースで提供されているクラス coins.driver.Driver は、ドラ イバ API を使用して作られた、 CLI ベースのコンパイラ・ドライバである。 gcc と多くの点で共通のインタフェースになるように注意して作られている。

 クラス coins.driver.Driver は、図1で言うところの「ドライバ実装」で あり、クラス coins.driver.CommandLine が「ドライバ U/I」である。

2.2.1 コマンド文法

    java [java-option ...] coins.driver.Driver [option | filename]...
 コマンド名の「java」は、環境によっては、「jre」などの別の名前かもし れない。  java-option には、 java 実行環境に対する適切なオプションを指定できる。

 COINS を使用するためには、 COINS をビルドしたディレクトリに対して java のクラスパスが通っている必要がある。 CLASSPATH 環境変数か、または、 -cp オプションを適切に設定しなければならない。  例えば、 /usr/local/coins にビルドしたのであれば、
    java -cp /usr/local/coins coins.driver.Driver [option | filename]
と指定すれば良い。

2.2.2 基本オプション

次のオプションを指定できる。
-E
プリプロセスのみ。例えば C プログラムの場合であれば、 foo.c をプリプロセスして foo.i を生成する。出力ファイルは、入力ファ イル (上の例で言えば foo.c) があったディレクトリに生成される。 (gcc では標準出力に出力される。)
-S
狭義のコンパイル(アセンブリ言語出力)まで。例えば C プログ ラムの場合であれば、 foo.c をプリプロセスし、コンパイルして foo.s を生成する。出力ファイルは、入力ファイル (上の例で言え ば foo.c) があったディレクトリに生成される。 (gcc では、カレント・ワーキング・ディレクトリに出力される。)
-c
リンクしない。例えば C プログラムの場合であれば、 foo.c をプ リプロセス、コンパイル、アセンブルして foo.o を生成する。出 力ファイルは、入力ファイル (上の例で言えば foo.c) があったディ レクトリに生成される。 (gcc では、カレント・ワーキング・ディレクトリに出力される。)
-help
ヘルプ・メッセージを出力する。
-o file
出力ファイルを指定する。出力ファイルとは、 -E オプションが指 定されている状況ではプリプロセス後のファイルを、 -S オプショ ンが指定されている状況ではアセンブリ言語ファイルを、 -c オプ ションが指定されている状況ではオブジェクトファイルを、それら が指定されていない状況では実行形式ファイルを指す。
-barch または -b arch
ターゲットアーキテクチャを指定する。 -coins:target=arch を指 定するのと完全に同等である (-coins:target=arch の項を参照)。
-pipe
一時ファイルの代わりにパイプラインを使う。
-Wcategory
警告カテゴリが category である警告メッセージを出力させる。
-Wno-category
警告カテゴリが category である警告メッセージを出力させない。
-C
プリプロセスによってコメントを削除しない。
-Dmacro[=definition]
プリプロセッサ・マクロ macroを定義する。 definition が指定 された場合、それをmacro の値とする。
-Ipath
インクルード・パスを定義する。
-P
#line ディレクティブを出力しない。
-Umacro
プリプロセッサ・マクロ macro の定義を取り消す。
-O
-O1 に等しい。
-Olevel
最適化レベルを level に設定する。 level は非負整数。各レベル で実施される最適化は以下の通り。
-O0
何もしない(-coins:hirOpt=noSimplify に等しく、HIRの単純化もしない)。
-O1
-coins:hirOpt=cf,ssa-opt=prun/cpyp/cstp/dce/ebe/srd3,loopinversion
に等しい。
-O2
-coins:hirOpt=cf,ssa-opt= prun/divex/cse/cstp/hli/osr/hli/cstp/cpyp/preqp/cstp/rpe/dce/srd3,loopinversion
に等しい。ただし,coins-1.4.4.3より後のバージョンでは,これに
-coins:regpromote,schedule-after
が加わる。
-O3
-coins:hirOpt=inline/cf/pre,ssa-opt= prun/divex/cse/cstp/hli/osr/hli/cstp/cpyp/preqp/cstp/rpe/dce/srd3,loopinversion
に等しい。ただし,coins-1.4.5.2より後のバージョンでは,これに
-coins:regpromote-ex,schedule,pipelining
が加わる。
-O4
-coins:hirOpt=inline/loopexp/cf/cpf/pre,ssa-opt= prun/divex/cse/cstp/hli/osr/hli/cstp/cpyp/preqp/cstp/rpe/dce/srd3,loopinversion
に等しい。ただし,coins-1.4.5.2より後のバージョンでは,これに
-coins:regpromote-ex,schedule,pipelining
が加わる。
-g
実行形式ファイル中にデバッグ情報を残す。
-v
サブプロセスを起動するごとに、その起動形式を表示する。
-Lpath
path を、 -l オプションで指定されるアーカイヴ・ファイルの検 索パスに追加する。
-dynamic
共有ライブラリを使用する。
-static
静的リンクする。
-larchive
libarchive.a ファイルをリンクする。
-coins:options
COINS オプション。この詳細は次節に述べる。

2.2.3 COINS オプション

COINSオプションはCOINS特有のオプションである。それは次の形で指定する。
   -coins:options
options にはコンマ記号 (`,') を含まない任 意の文字列を指定できる。 複数の COINS オプションは、コンマ記号 (`,') で区切って連続し て与えることができる。例えば、
   -coins:debug,trace=Driver.8,suffix=/tmp/mysuffixes
は、下記と同等である。
   -coins:debug -coins:trace=Driver.8 -coins:suffix=/tmp/mysuffixes
COINSオプションには、上記の例の"debug"のように名前だけからなるものと、 "trace=Driver.8"のように"name=spec"の 形のものがある。後者の形で複数個のspecを指定する場合は、
   name=spec1/spec2/spec3
のようにそれらを"/"で区切って並べる必要がある。なお、上記の"suffix"オプションの"/"は これとは違ってディレクトリの区切りを示すものである。
たとえば、"/"で区切らずに
   -coins:trace=HIR.1,trace=Driver.8
のようにすると、最後の"trace=Driver.8"だけが有効になる。両方を有効にするためには
   -coins:trace=HIR.1/Driver.8
のように指定しなければならない。

標準的な(CLI ドライバまたはドライバ API によって解釈される) COINS オプションには下記のものがある。
ターゲットアーキテクチャ指定
ターゲットアーキテクチャを指定するオプションは次の形である。
   -coins:target=arch
または
   -coins:target=arch-convention
このオプションは、 -b archまたは、-b arch-conventionを指定するのと完全に同等である。 最初の形の指定は
   -coins:target=arch-standard
を指定するのに等しい。また2番目の指定は
   -coins:target-arch=arch,target-convention=convention
を指定するのに等しい。

ターゲットアーキテクチャの種別を指定するオプションは次の形である。
   -coins:target-arch=arch
現在は、arch には、次のいずれかを指定できる。 いずれも、多くのテストプログラム(COINSのソース・アーカイブのcoins/test/c 以下の約700個、現在は約1000個ある)で動くことを確認している。 さらに、sparcとx86については、約8,000個のテストプログラムと、SPEC2000が通ることを 確認している。 その他のマシンのうち、armとx86_64についてはかなりテストが行われており、 SPEC2000の多くのテストが動くことを確認している。

sparcとx86, x86sse2, x86_64, x86_64-macでは、C言語の"long long"型をサポートしているが、 その他のマシンのコード生成系ではそれをサポートしていない。

x86_64-macでは、fprintfなどの、引数にFILE*を指定する関数の呼出しをサポートしていない。

target-arch オプションが指定されると、標準ドライバは、プリプロ セッサに与えるオプションとして -D__arch__ を追加し、 LIR モジュールを起動する際のターゲットアーキテクチャ名 として arch を指定する。このオプションが指定されない場 合、 LIR モジュールにはアーキテクチャ名として sparc が 与えられる。
ターゲットアーキテクチャのコンベンションを指定するオプションは次の形である。

     -coins:target-convention=convention
現在は、 target-arch=arch の値に応じて、次のいずれかを指定できる。 このオプションが指定されると、標準ドライバは、 LIR モジュー ルを起動する際のターゲットコンベンション名として convention を指定する。このオプションが指定されない場合、 LIR モジュールにはコンベンション名として文字列 "standard" が与えられる。
プレプロセサとアセンブラとの指定

プレプロセサを指定するオプションは次の形である。

  -coins:preprocessor=prep

アセンブラを指定するオプションは次の形である。

  -coins:assembler=asm

リンカーを指定するオプションは次の形である。

  -coins:linker=link

デフォルトでは,プレプロセサは"cpp",アセンブラは"as",リンカーは"gcc"である. (coins-1.4.4.4まではアセンブラのデフォルトは"gas"であったが,それより後の バージョンでは,アセンブラのデフォルトは"as"になる.)

アーキテクチャの指定によって,これらのデフォルトの名前と違う名前のプレプロセサやアセンブラが使われる場合は, 上記のオプション指定でその名前を指定する必要がある.
クロスコンパイルの場合は,オプションで"-S"を指定して, アセンブラコードを出力し,それを実機でアセンブルして実行するか, クロスアセンブラを指定してオブジェクトコードを生成すればよい.

いずれにしても,COINS のコンパイラではアーキテクチャの指定によってアセンブラを決めて, そのアセンブラ用のコードを生成するから,実機ではそれに合ったコマンドを使う必要がある.

以下では,デフォルトの名前と違う場合,あるいはプレプロセサやアセンブラに対して オプション指定をする必要がある場合,および実機でのコマンドなどを列挙する.

以下のような場合はヘッダファイルを指定する必要がある.
stdarg.h
COINSで,引数の個数不定の関数を使うプログラムをコンパイル する場合は,COINSの
  lang/c/include/stdarg.h
をヘッダファイルとして使う必要がある.そのためには
 -coins:preprocessor="cpp -I../lang/c/include"
などとすればよい.
ただし,これが使えるのは,アーキテクチャが
 sparc, x86, x86_64, arm
の場合だけである.
ヘッダファイルによるエラーの回避
たとえば,x86_64-macのマシンで,
  #include <stdio.h>
を含むプログラムをコンパイルするとstdio.hで 使われている拡張機能のためにシンッタクスエラーとなって コンパイルできない.
そのような場合には,簡素化したstdio.hを使う必要がある. COINSの
  lang/c/include/samples/
にはいくつかの簡素化したヘッダファイルが置いてある.
HIRでの最適化
HIRでの最適化を指定するオプションは次の形である。
  -coins:hirOpt=hiroptspec
  -coins:hirOpt=hiroptspec/hiroptspec/...
hiroptspec は、次のいずれかである。 これらの最適化の意味については、 6. HIRでの最適化を参照されたい。
粗粒度並列化
HIRから粗粒度並列化モジュールを生成する粗粒度並列化コンパイラCoCoを呼び出すことを指定するオプションは次の形である。
 -coins:coarseGrainParallel
または
  -coins:cgParallel
詳しくは、7.2 粗粒度並列化コンパイラCoCo を参照されたい。
ループ並列化
HIRでループ並列化したものをopenMPのソースとして出力することを指定するオプションは次の形である。
  -coins:parallelDoAll=OpenMP 
これによって、OpenMP指示文を付加したCファイルが生成される。

forループを解析して並列化の条件に合うものに対して 並列実行用のアセンブリ言語プログラムを生成することを指定するオプションは次の形である。
  -coins:parallelDoAll=n -S
ここで n は並列度を表す整定数である。

openMPコンパイラが使える環境で、openMPのソースとして出力したものを直ちに コンパイルしてしまうためには、 次のように、それ用のドライバを起動すればよい。
  java coins.lparallel.LoopPara -coins:hir2c foo.c
詳しくは、 英語のドキュメントの 6. Parallelization for HIRを参照。
SSA最適化
LIRでのSSA最適化を指定するオプションは次の形である。
  -coins:ssa-opt=ssa_opt
  -coins:ssa-opt=ssa_opt/..
ssa_opt は、次のいずれかである。 coins-1.4.4.2より後のバージョンでは,SSA形式ではない,通常形式LIRに対する最適化も ssa-optの中のオプションとして指定できる(詳細は「8.1.2.1 SSA最適化部の使い方」参照)。 その最適化機能には次のものがある。 coins-1.5以降のバージョンでは,通常形式最適化の一種として、SSAのスカラ置換(変数のレジスタ化を進める)最適化向けに次のオプションが使える。(詳細は「8.1.2.1 SSA最適化部の使い方」参照)。
LIR最適化
coins-1.4.4.2より後のバージョンでは,SSA形式ではない通常形式LIRに対する最適化も指定できるように なったので,SSA形式最適化と通常形式最適化を合わせて「LIR最適化」として書けるようにした(coins-1.4.4.3より後)。 それを指定するオプションは次の形である。
  -coins:lir-opt=lir_opt/..
  -coins:lirOpt=lir_opt/..
lir_opt に書けるものは,いまのところssa_opt に書けるものと同じである。

LIRでのその他の最適化機能には次のものがある。
これらを指定するには,たとえば次のように書けばよい。
  -coins:loopinversion,schedule
いままでは
  -coins:loopinversion,schedule,attach=coins.backend.sched.Schedule
のように指定していたが,coins-1.4.4.3より後ではattachを指定する必要がない. なお,pipeliningを指定すると,scheduleも指定したものと見なされる.
SIMD並列化
LIRでSIMD並列化を指定するオプションは次の形である。
  -coins:target=x86simd,simd
詳しくは、 8.2 SIMD並列化を参照されたい。
バックエンドの拡張最適化
バックエンドの拡張最適化機能を指定するオプションには次のものがある。
  -coins:schedule,attach=coins.backend.sched.Schedule
命令スケジューラをマシン命令選択後のレジスタ割り付け前とレジスタ割り付け後の 2ヶ所で起動する。 より詳しくは、9.2 バックエンドの付加機能 の「9.2.3. 命令スケジューラ」を参照されたい。
  -coins:regpromote
大域変数は通常メモリに割り付けられるが、それをレジスタに割り付けようとするレジスタプロモーションの基本版を起動する。
  -coins:regpromote-ex
大域変数は通常メモリに割り付けられるが、それをレジスタに割り付けようとするレジスタプロモーションの拡張版を起動する。
コンパイル過程の情報出力
デバッグ用、またはコンパイル過程の情報を出力するオプションには 次のものがある。まず最初に、分かりやすい形で表示する、いわゆる 可視化ツールをあげる。
可視化ツールCoVis
これは、ソースプログラム、HIR、HIRの制御フローグラフ、LIR、 LIRの制御フローグラフなどの対応をグラフィカルに表示するものである。 この表示をするためには、コンパイル時に
  -coins:snapshot
というオプション指定をする必要がある。その結果、xmlファイルが生成されるので、 それをCoVisで開けば良い。なお、CoVisでのグラフ表示にはATTの研究所で開発されたgraphviz というソフトを使っている。詳しくはCoVisUsersGuide.pdfを参照されたい。
コード生成過程のトレース情報表示ツール
バックエンドでのコード生成過程をソースプログラムやバックエンドの 各フェーズと対応させながら見るためには、
  -coins:debuginfo,trace=xxx
のようなオプション指定をする必要がある。その出力結果を
  java coins.driver.Driver -coins:debuginfo,... > trace.java
  perl trace2html.pl -o trace -c  trace.java
のようにperlのファイルtrace2html.plで処理すればtrace.htmlファイルが 作成されるので、それをブラウザで表示すれば良い。

traceオプションの指定の仕方は以後の記述の中にあるが、バックエンドに関係する ものには以下のものがある。
-coins:trace=LIR[.number]
バックエンドの入口と出口で、LIRの内部状態を標準出力に表示する。 「.number」はなくても良い。numberは数値であり、その意味は以後の記述で説明される。
-coins:trace=TMD[.number]
コード生成部のトレース情報を標準出力に表示する。
-coins:trace=phasename[.number]
変換ステップの名前phasenameを指定して、その変換作業の前後のLIRの状態を表示する。 phasenameとしては、以下のものが指定出来る。

ToCFG, ToLinear, ToMachineCode, EarlyRewriting, LateRewriting, Restruct, InstSel, AggregateByReference, ConvToAsm, NamingFloatConst, ReplaceFloatConst, RewriteConvUF, AugmentCFG, IntroVirReg, JumpCanon, JumpOpt, LoopInversion, PreHeaders, SimpleOpt, Ssa(pruned), Ssa(minimal), LiveRange, RegisterAllocation
コンパイル過程のトレース情報表示
上記の2つの可視化ツールの他に、コンパイル過程のトレース情報を 出力するための以下のオプション指定がある。
-coins:debug
コンパイラそのもののデバッグをしていることを示す。 -coins:preserveFiles,testHir,testSym に等しい。
-coins:preserveFiles
一時ファイルを削除しない。
-coins:trace=tracespec
-coins:trace=tracespec/tracespec/..
トレース・オプション。
トレース・メッセージには、メッセージ・カテゴリつきトレー ス・メッセージと、メッセージ・カテゴリのないトレース・ メッセージの2種類が存在する。 トレース・メッセージには、メッセージ・レベルを指定して 良い。メッセージ・レベルは非負整数である。メッセージ・ レベルが指定されていないトレース・メッセージは、 0 が指 定されているものとして扱われる。 上記の形式の中で、 tracespec は、次のいずれかである。
     level
     category.level
level にはトレース・レベルを非負整数で、 category には トレース・カテゴリを英数字列で指定する。
前者の形式は、 メッセージ・カテゴリのないトレース・メッセージのトレー ス・レベルを指定する。指定されたトレース・レベル以下の メッセージ・レベルを持つ、メッセージ・カテゴリのないト レース・メッセージが出力される。
後者の形式は、メッセー ジ・カテゴリがcategory であるトレース・メッセージのト レース・レベルを指定する。指定されたトレース・レベル以 下のメッセージ・レベルを持つメッセージ・カテゴリが category であるトレース・メッセージが出力される。例えば、
     -coins:trace=2
は、メッセージ・レベルが 2 以下であるメッセージ・カテゴ リなしトレース・メッセージを出力する。
     -coins:trace=HIR.4
は、メッセージ・レベルが 4 以下であるメッセージ・カテゴ リが HIR のトレース・メッセージを出力する。
出力先は標準出力である。
COINS が提供している各コンパイラ部品に対して有効なトレー ス・カテゴリの種類には、 などがある。 これらを利用すると、コンパイラで行っている内容を容易に理解できる とともに、コンパイル結果に不審な点がある場合にその原因をつきとめる ことができる。
異なるカテゴリーのトレースを / で区切って指定すると、指定された各カテゴリーの トレース情報が出力される。たとえば、
     -coins:trace=Sym.1/HIR.1
と指定すると、バックエンドに渡される直前の記号情報とHIRがトレース出力される。
    -O3 -coins:trace=Sym.1/HIR.2/Flow.1/Opt1.4
のように、最適化レベルを指定してFlow, Opt1カテゴリーのトレース指定をすると、 記号やHIRのほかに、制御フロー解析、データフロー解析の情報とHIR最適化の コンパイル過程の情報が出力される。

複数のトレース・カテゴリのないトレース・レベルが指定さ れた場合、および、同じトレース・カテゴリに対して複数の トレース・レベルが指定された場合、後から指定された方が 優先される。例えば、
     -coins:trace=4/8
は、メッセージ・レベルが 8 以下のメッセージ・カテゴリな しトレース・メッセージを表示する。 4 以下ではない。
     -coins:trace=HIR.6/HIR.3
の例では、メッセージ・レベルが 3 以下の、メッセージ・カ テゴリが HIR のトレース・メッセージを表示する。 6 以 下ではない。
特別なトレース・カテゴリ default は、他の tracespec で 明示的にトレース・レベルを指定されていないすべてのトレー ス・カテゴリのトレース・レベルを指定するための ものである。例えば、
     -coins:trace=default.2/HIR.4
は、メッセージ・カテゴリがHIRのものについてはレベルが 4 以下、それ以外のカテゴリのものについては レベルが 2 以下のトレース情報を表示する。
大きなトレース・レベル(例えば 7, 8, 9 など)を指定する と、膨大な量のトレース・メッセージが出力されるかもしれ ないので注意が必要である。
その他
その他のオプションには、以下のものがある。
-coins:libdir=path
ライブラリ・ディレクトリのパス名を path に変更する。 ライブラリ・ディレクトリの詳細については、 4.6 節を参照。 複数の -coins:libdir オプションが指定された場合、最後に 指定されたものが有効である。
-coins:property=path
プロパティ・ファイルのパス名を path に変更する。デフォ ルトでは、ライブラリ・ディレクトリにある `properties' とういファイルがプロパティ・ファイルであるが、このオプ ションを指定して変更できる。
プロパティ・ファイルは、 COINS オプションを指定するため の方法の一つである。詳細については、 2.3.7 節を参照。
複数の -coins:property オプションが指定された場合、最後 に指定されたものが有効である。
-coins:suffix=path
サフィクス規則ファイルのパスを path に変更する。デフォ ルトでは、ライブラリ・ディレクトリにある `suffixes' と いう名前のファイルがサフィクス規則ファイルであるが、こ のオプションを指定して変更できる。 サフィクス規則ファイルの詳細については、 2.3.8 節を参照。 複数の -coins:suffix オプションが指定された場合、最後に 指定されたものが有効である。
-coins:suffixoption=option
サフィクス・オプションを指定する。 サフィクス・オプションの詳細については、 2.3.8 節を参照。 複数の -coins:suffixoption オプションが指定され、それら が矛盾する場合、より後に指定されたものが有効となる。
-coins:hir2c=t1
-coins:hir2c=t1/t2/.../tn
指定されたタイミングで、 HIR を C 言語ソースに変換して ファイルに出力する。 t1, t2, ..., tn には、次の 3 種類 のタイミング指定子のうちのいずれかを指定できる。 複数のタイミング指定子が指定されると、指定されたすべて のタイミングで変換と出力が行われる。
生成された C 言語ソース・ファイルは、r-hir-t.c という ファイル名を持つ。ここで、 r はコンパイル対象のソース・ ファイルのファイル名 (拡張子より前の部分) であり、 t は、 指定されたタイミング指定子である。例えば、
    java coins.driver.Driver -coins:hir2c=new foo.c
は、 foo-hir-new.c というファイルを生成する。不正なタイ ミング指定子は無視され、ファイルは生成されない。
-coins:lir2c=t1
-coins:lir2c=t1/t2/.../tn
指定されたタイミングで、 LIR を C 言語ソースに変換して ファイルに出力する。 t1, t2, ..., tn には、次の 2 種類 のタイミング指定子のうちのいずれかを指定できる。 生成された C 言語ソース・ファイルは、 r-lir-t.c という ファイル名を持つ。ここで、r はコンパイル対象のソース・ ファイルのファイル名 (拡張子より前の部分) であり、 t は、 指定されたタイミング指定子である。例えば、
     java coins.driver.Driver -coins:lir2c=new foo.c
は、 foo-lir-new.c というファイルを生成する。不正なタイ ミング指定子は無視され、ファイルは生成されない。
-coins:stopafterhir2c
-coins:stopafterlir2c
各コンパイル単位のコンパイルを、 hir2c/lir2c オプション で指定されたすべてのタイミングで C 言語ソース・ファイル を生成した時点で終了する。コード生成、アセンブルおよび リンクは行われない。ただし、 hir2c/lir2c オプションに不 正なタイミング指定子が指定された場合の動作は不定である。
-coins:testHir
HIR 上での最適化が終了し、 HIR to LIR 変換を行う直前に、 HIR の一貫性を検査する。
-coins:testSym
HIR 上での最適化が終了し、 HIR to LIR 変換を行う直前に、 シンボル・テーブルの一貫性を検査する。
-coins:preprocessor=preprocessor-command
-coins:assembler=assembler-command
-coins:linker=linker-command
プリプロセッサ、アセンブラ、リンカの代替コマンドを指定 する。
COINS の CLI ドライバは、プリプロセッサ、アセンブラ、リ ンカとして、それぞれ、 cpp, gas, gcc を起動するが、別の コマンドを使用したい場合にこのオプションを使用する。次 の例では、アセンブラとして `as' を使用する。
    -coins:assembler=as
コマンド名の中に空白文字が現れる場合、それは単語の区切 りとして扱われる。例えば、次のオプションは、プリプロセッ サとして gcc を -E オプションつきで起動することを指定す る。
    -coins:preprocessor=gcc -E
このとき、コマンド・インタプリタから空白文字をエスケー プすることを忘れてはならない。多くの Unix のシェルでは、 引用符を使って空白文字をエスケープできる。例えば下記は その例である。このうち、二重引用符を使う方法は Windows でも使用可能であろう。
     -coins:preprocessor="gcc -E"
     -coins:preprocessor='gcc -E'
     '-coins:preprocessor=gcc -E'
CLI ドライバは、コマンド名の中に引用符記号 (' および ") が現れる場合、その引用符記号と、その次に現れる同じ引用 符記号を文字列から取り除き、その間の文字列を、次のよう に解釈する。 この規則は、上述の、空白文字を単語の区切りとして認識す る規則から逃れるために使用できる。例えば、ファイルやディ レクトリ名に空白文字を含むことができる環境の場合、次の ようにしてそれらをエスケープできる。
    -coins:preprocessor='my cc' -E
この例では、プリプロセッサとして、プログラム `my cc' が、 `-E' というオプションつきで起動される。このとき、コマン ド・インタプリタから引用符記号や空白をエスケープするの を忘れてはならない。例えば、 Windows であれば、下記のよ うに二重引用符を使用する必要があろう。
    -coins:preprocessor="'my cc' -E"
CLI ドライバは、コマンド名の中に現れるバックスラッシュ 記号 (`\') に続く文字を、その文字そのものとして扱う。バッ クスラッシュ記号自身も、バックスラッシュ記号に続けて記 述することで、バックスラッシュ記号そのものとして記述で きる。引用符も、バックシュラッシュ記号に続けて記述する と、上述の意味を失い、引用符そのものとして解釈される。
このエスケープ規則も、上述の、空白文字を単語の区切りと して認識する規則から逃れるために使用できる。例えば、ファ イルやディレクトリ名に空白文字を含むことができる環境の 場合、次のようにしてそれらをエスケープできる。
    -coins:linker=c:\\Program\ Files\\bin_utils\\ld
この例では、 `c:\Program Files\bin_utils\ld' がリンカと して使用される。ここで、もし必要なら、 `\' と空白を、コ マンド・インタプリタからエスケープするのを忘れないよう に。例えば、 Windows であれば、下記のように二重引用符を 使用する必要があろう。
    -coins:linker="c:\\Program\ Files\\bin_utils\\ld"
-coins:max-recovered-errors=n
ひとつのコンパイル単位の、ひとつのコンパイル・ステップ におけるリカヴァード・コンパイル・エラーの数がnを越え た場合、コンパイル・エラーとして扱われる。または、n が 0 の場合、リカヴァード・コンパイル・エラーの数がいくつ になってもコンパイル・エラーとして扱わない。ここで、コ ンパイル・ステップとは、プリプロセス、コンパイル、アセ ンブル、リンクのことである。
-coins:max-warnings=n
ひとつのコンパイル単位の、ひとつのコンパイル・ステップ における警告の数がn を越えた場合、コンパイル・エラーと して扱われる。または、 n が 0 の場合、警告の数がいくつ になってもコンパイル・エラーとして扱わない。ここで、コ ンパイル・ステップとは、プリプロセス、コンパイル、アセ ンブル、リンクのことである。
-coins:compile-parallel
各コンパイル単位のコンパイルを並行して実行する。スレッ ド・セーフに実装されていないコンパイラ部品を使用する場 合、このオプションを指定してはならない。
-coins:gprof
gprofによるプロファイルを可能にするオプション(coins-1.4.3.3より後のバージョンで使える)。現在、sparc,x86x,86sse2のみ対応している。 -coins:linker='gcc -pg'と共に用いる必要がある(x86sse2の場合はそれを指定しなくてもよい)。testdriver_gprof.sh、testdriverw_gprof.sh を用いることで、テストとまとめてプロファイル作業を行うことができる。 gccと同様に、コンパイルした実行ファイルを実行すると、gmon.outが出力されるので、「gprof 実行ファイル」でプロファイルできる。
参考
gprofのマニュアル
'gprof: A Call Graph Execution Profiler' by S. Graham, P. Kessler, M. McKusick
新しいオプションの追加
COINSオプションを新たに追加するには、次のようにすれば良い。
オプションの名前は任意につけることが出来る。たとえば、その名前を"newOption" としたとすれば、それを指定するには、
     -coins:newOption
とすればよい。
そのオプションがコンパイル時に指定されているかどうか調べるには、
  if (ioRoot.getCompileSpecification().getCoinsOptions().isSet("newOption")) {
      // newOptionの処理
  }
とすればよい。
ここで、ioRootはクラスIoRoot(入出力情報のルート)のインスタンス・オブジェクトであり、 いろいろなところでアクセス出来るようになっている。たとえば、 coins.driver.Driverやそれを継承しているドライバではアクセス出来るようになっている。 また、クラスSymRoot(シンボル情報のルート)やクラスHirRoot(HIR情報のルート) のインスタンスからもioRootにアクセス出来る。
バックエンドの情報のルートはクラスcoins.backend.Rootのインスタンスから得られるが、 そのインスタンスはioRoot.getCompileSpecification()で得られるCompileSpecificationクラスのオブジェクトを持っている。
これらの情報を使えば、いろいろなところで、オプションが指定されていたかどうかを調べることが出来る。その例が、 5. フロントエンド の「5.2.2 Fortranフロントエンドの使い方」にある。
なお、IoRootのインスタンスが簡単に得られるようになっていない場合にも、
   ((coins.driver.CompileThread)Thread.currentThread()).getIoRoot()
でそれを得ることが出来る。

2.2.4 入力ファイル

 オプションに混じって、入力ファイルを記述することができる。エンジンは、 サフィクス規則を参照しながら、どのファイルにどの処理を行うかを決定し、 ドライバ実装の対応するメソッドを起動する。サフィクス規則の詳細について は、 2.1.4.8 節を参照。

 各出力ファイルは、 -o オプションが指定されない限り、ソース・ファイル があるディレクトリに作られる。

2.2.5 終了ステータス

 CLI ドライバは、下記の方針で終了ステータスを返す。  異常終了には、入出力エラーやコンパイル・エラーなどが含まれる。

2.2.6 ターゲットアーキテクチャの指定

  ドライバは、ターゲットアーキテクチャを指定する方法として、下記の 3 種類の方法を用意している。
 これらはすべて等価であり、ひとつを指定することは他のすべてを指定する ことと等しい。

 conventionが省略されると、 "standard" が指定されたものとみなす。  ターゲットアーキテクチャが指定されない場合のデフォルトは"sparc" である。  cygwin 上でコンパイルするユーザは、 -b x86-cygwin を指定するとともに、 (通常の場合は、)次を指定する必要がある。
    -coins:assembler=as
その他、 cygwin のインストールの状況によって、下記を必要とするケースも あるようである。
    -coins:preprocessor="cpp-3 -I/usr/include"
    (-coins:preprocessor="cpp -I/usr/include" -- java 1.6より前のバージョンの場合)

2.2.7 使い方の例

 下記の例すべてについて、 CLASSPATH 環境変数が適切に設定されているも のとする。
    java coins.driver.Driver foo.c
は、 foo.c をコンパイルして a.out を生成する。
    java coins.driver.Driver -o foo foo.c
は、 foo.c をコンパイルして、実行形式ファイル foo を生成する。
    java coins.driver.Driver -c foo.c
は、 foo.c をコンパイルして、オブジェクト・ファイル foo.o を生成する。
    java coins.driver.Driver -E foo/bar.c baz/boo.c
は、 foo/bar.c と baz/foo.c をプリプロセスして、 foo/bar.i と baz/boo.i を生成する。ここで、 `.i' は、プリプロセスされた C プログラ ムのサフィクスとして、デフォルトのサフィクス規則に記述されている。
    java coins.driver.Driver -S foo.c bar.i
は、 foo.c と bar.i をコンパイルして、アセンブリ言語ファイル foo.s と bar.s を生成する

いくつかの例外的なケースを除き、 `java coins.driver.Driver' を `cc' に alias することで、 COINS C コンパイラを普通の C コンパイラと同様に使用 できる。例外的なケースとは、例えば、 `cc -E' は cpp とまったく同様には 使えない、などである。

2.3 ドライバ API の使い方

 ドライバ API の使い方については、対応するクラスの JavaDoc に詳しい。  本文書では、どのクラスの JavaDoc を読めば良いかが分かる程度の概要の みを説明する。

2.3.1 ドライバ U/I

 ドライバ U/I とは、次のことを行うものである。
 「コンパイル仕様オブジェクト」は、 coins.driver.CompileSpecification インタフェースを実現するように作らなければならない。

 CLI ドライバにおいては、 coins.driver.Driver クラスの main メソッド および go メソッドがドライバ U/I に相当する。これは次のように記述され ている。
  protected void go(String[] args) {
    CompileSpecification spec = new CommandLine(args);
    int status = new CompilerDriver(spec).go(this);
    System.exit(status);
  }

  public static void main(String[] args) {
    new Driver().go(args);
  }
coins.driver.CommandLine クラスは、 CLI ドライバのためのコンパイル仕様 クラスである。 coins.driver.CompilerDriver クラスが、エンジンである。 coins.driver.Driver クラスはドライバ実装も兼ねているので、自分自身をイ ンスタンシエートしてエンジンに与えている。  もしも CLI ドライバと同じユーザ・インタフェースを持つドライバを作る のであれば、この部分はそのまま使用できる。

2.3.2 ドライバの実装

 ドライバ実装は、エンジンから呼び出される次のサービスを実装するもので ある。  coins.driver.CompilerImplementation クラスが、ドライバ実装が実装すべ きインタフェースを定義している。

 CLI ドライバの場合は、 coins.driver.Driver クラスがドライバ実装の役 割を担っている。 CLI ドライバは上記の 4 種類のメソッドを提供しているが、 プリプロセス、アセンブル、リンクについては、外部プロセスを呼び出すだけ である。

2.3.3 コンパイル仕様

 コンパイル仕様は、 coins.driver.CompileSpecification インタフェース を実装しなければならない。  CLI ドライバでは、 coins.driver.CommandLine クラスがこれに当たる。

2.3.4 トレース API

 オペレータが指定したトレース・オプションを解釈し、特定のトレース・メッ セージを出力をするかどうかを判断し、出力する機能を持つ。

 ドライバ実装、および、そこから呼び出されるコンパイラ部品は、メッセー ジ・カテゴリ(文字列)と、メッセージ・レベル(非負整数)を指定して、ト レース・メッセージを出力する API を呼び出す。メッセージ・カテゴリは、 英数字列でありさえすれば、ユーザが任意に指定できる。

 トレース・オプションには、トレース・カテゴリとトレース・レベルの対の 集合を指定できる。トレース API は、指定されたトレース・オプションに照 らして、いずれかのトレース・カテゴリと同じメッセージ・カテゴリを持ち、 そのトレース・レベル以下のメッセージ・レベルを持つトレース・メッセージ だけを出力する。

 オペレータが指定したトレース・オプションを格納した coins.driver.Trace クラスのオブジェクトを取得するには、 CompileSpecification#getTrace() メソッドを使用する。

2.3.5 警告 API

 オペレータが指定した警告オプションを解釈し、特定の警告メッセージを出 力するかどうかを判断し、出力する機能を持つ。

 ドライバ実装、および、そこから呼び出されるコンパイラ部品は、警告カテ ゴリ(文字列)を指定して、警告メッセージを出力する API を呼び出す。警 告カテゴリは、ユーザが任意に指定できる。

 警告オプションには、出力すべき警告カテゴリ、および出力すべきでない警 告カテゴリを指定できる。警告 API は、指定された警告オプションに照らし て、出力すべきと指定された警告メッセージだけを出力する。

 CompileSpecification#getWarning() メソッドで、 coins.driver.Warning クラスのオブジェクトを取得できる。ここに、オペレータが指定した警告オプ ションが格納されている。

2.3.6 ライブラリ・ディレクトリ

 コンパイラ部品の動作をカスタマイズ可能にする場合、オペレータにコンフィ ギュレーション・ファイルを用意させる方法を採ることがあり得る。例えば、 ドライバ API は、オペレータが次の 2 種類のファイルを準備することができ るように設計されている。
 ライブラリ・ディレクトリは、このようなコンフィギュレーション・ファイ ルを置くためのディレクトリである。

 COINS ドライバ API は、コンパイラ部品に対して、ライブラリ・ディレク トリのパス名を提供する機能がある。すなわち、 CompileSpecification#getCoinsOptions() メソッドによって得られる coins.driver.CoinsOptions オブジェクトの CoinsOptions#getLibDir() メソッ ドを呼び出すことで得ることができる。 COINS のユーザは、オペレータに対 して、コンフィギュレーション・ファイルをライブラリ・ディレクトリに置く ように指示しておいて、上記 API を使ってディレクトリのパス名を得て、必 要なファイルを読み込むことができる。

 COINS オプションである -coins:libdir=path が指定された場合、ドライバ API は、ライブラリ・ディレクトリのパス名として path を返す。このオプショ ンが指定されていない場合、オペレータのホーム・ディレクトリ (Java 実行 環境が返す、 user.home プロパティの値) に `coins' という名前のディレク トリがあれば、そのパス名を返す。それもない場合、カレント・ワーキング・ ディレクトリを示す相対パス名を返す。

2.3.7 プロパティ・ファイル

 コンパイラの開発のために COINS を使用する場合、トレースや警告の設定、 オリジナルのオプションなどの指定などで、長い COINS オプションを毎回指 定する状況になることが考えられる。この状況を改善する目的で、 COINS オ プションをファイルに入れ、それを参照させることができるようになっている。 このファイルが「プロパティ・ファイル」である。

 デフォルトでは、ライブラリ・ディレクトリの下の `properties' というファ イルがプロパティ・ファイルとして参照される。

 プロパティ・ファイルの位置は、オペレータが指定したいこともあるかもし れないので、コンパイル仕様を生成するときに設定できるようになっている。  プロパティ・ファイルの解釈と反映は、コンパイル仕様の生成の際に、 coins.driver.CoinsOptions クラスが行う。

 properties ファイルの書式は、 java.utils.Properties#load() メソッド が読み込めるものであれば良い。下記に記述例を示す。
    debug:
    trace:        Driver.8
    suffix:       /tmp/mysuffixes
上記は、コマンドラインから次のように指定したのと同等である。
    -coins:debug,trace=Driver.8,suffix=/tmp/mysuffixes
 プロパティ・ファイルとコマンドラインの両方にオプション指定があった場合は、 前者のオプション指定の後ろに後者のオプション指定があった場合と同じことになる。 たとえば、両方にtraceオプション指定がある場合は、後者だけが有効になる。

2.3.8 サフィクス規則

 サフィクス規則とは、「どのサフィクスを持つファイルに対してどの処理を 行なうとどのサフィクスを持つファイルが生成されるか」を記述した規則であ る。 COINS は、 C, Fortran, Java に対応しているデフォルトのサフィクス 規則ファイルを提供している。

 デフォルトでは、ライブラリ・ディレクトリの下の `suffixes' というファ イルがサフィクス規則ファイルとして参照される。サフィクス規則ファイルが 見つからない場合は、下記の内容がデフォルトとして使用される。
#SRD, 2, Suffix rule DB file, format version 2
c,		C,		C source,				i,s,o
c(out-newlir),	C,		C source,				i,lir,-
i,		C,		preprocessed C source,			-,s,o
cc/cpp/cxx/C,	C++,		C++ source,				ii,s,o
ii,		C++,		preprocessed C++ source,		-,s,o
java,		Java,		Java source,				-,class,-
java(native),	Java,		Java source (native compile),		-,s,o
f,		FORTRAN,	FORTRAN source,				-,s,o
f(out-newlir),	FORTRAN,	FORTRAN source,				-,lir,o
lir,		LIR,		new LIR,				-,s,o
S,		Assembler,	assembly source (need preprocess),	s,-,o
s,		Assembler,	assembly source,			-,-,o
 このファイルの文法の詳細は、 coins.driver.SuffixFactory.java に記述 されているが、おおむね、
 サフィクス, 言語名, 意味, プリプロセス後/コンパイル後/アセンブル後のサフィクス
という構造になっている。

 同じサフィクスを持つファイルであっても、コンパイラの動作モードに応じ て、異なるサフィクスのファイルに変換したい場合があり得る(例えば、ある Java コンパイラは、バイト・コードにコンパイルする場合は .class ファイ ルを、ネイティブ・コンパイルする場合は、 .o ファイルを生成するかもしれ ない)。このように、適用するサフィクス規則をコンパイラの動作時に変更し たい場合、サフィクス・オプションを使用できる。

 サフィクス規則ファイルには、同じサフィクスに対して、複数の規則を定義 することができるが、その場合、そのうちのひとつを除いた残りの規則には、 それぞれに異なるサフィクス・オプションを与えなければならない。

 コンパイル仕様にサフィクス・オプションが指定されなかった場合は、サフィ クス・オプションのないサフィクス規則が使用され、サフィクス・オプション が与えられた場合は、そのサフィクス・オプションと一致するサフィクス・オ プションを持つサフィクス規則が使用される。

 サフィクス規則ファイルの位置は、オペレータが指定したいこともあるかも しれないので、コンパイル仕様を生成するときに設定できるようになっている。

 サフィクス規則ファイルの解釈と反映は、コンパイル仕様の生成の際に、 coins.driver.SuffixFactory クラスが行う。

2.3.9 settings ファイル

 コンパイルは複雑な処理であり、その過程ではいろいろの情報が参照される。 それらの中には、必ずしもすべてのユーザが同じ情報を指定するとは限らない ものがあり、その場合にはサイト独自の設定が必要となる。この例には、例え ば、コンパイラがリンクするライブラリファイルの置き場所、 OS の名称や版 番号などが考えられる。settings ファイルは、そのような、サイト独自の設 定を記述するべきファイルとして設計されたものである。

 ライブラリディレクトリに settings という名前のファイルがあると、 coins.driver.Driver はこれを読み込み、 defaultSettings という Driver オブジェクトのメンバ変数に格納する。

 settings ファイルの書式は、 java.utils.Propertis#load() メソッドが読 み込めるものであれば良い。

 coins.driver.Driver にとって、 settings に記述して有効なのは、次のプ ロパティである。
 COINS を利用して作るコンパイラ部品や、 coins.driver.Driver 以外のド ライバも、サイト独自の設定を読み込むのに settings ファイルを利用して良 い。

2.4 既知の障害と制限事項

 リリース 1.0 における既知の障害と制限事項は下記の通り。

2.4.1 既知の障害

 なし。

2.4.2 制限事項

2.5 コンパイラ・ドライバの実現

コンパイラ制御部の実現(pdf)を参照されたい。