HCl コンパイラ
HCl のコンパイラサポートはCommon Lispの標準組み込み関数、
compile及び
compile-fileによります。
compileはインタプリテイブに定義された個々の関数
をコンパイルし再定義するために、compile-fileはファイルに記述された
関数群を一括コンパイルしobject file(*.fasl)
を作成します。compile-fileによってコンパイルされたファイルを
実行するためには、さらにloadによって読み込まなければなりません。
compile-fileは第一引数をpathnameとみなし、
まずそのファイルを探索します。
それが存在すればそれをソースファイルとしてコンパイルを行い、結果として
typeが".fasl"であるオブジェクトファイルを作成します。(*)
また、ソースファイルが存在せず、かつpathnameがtypeフィールドを持たない
場合には".lsp" ".lisp" ".cl" ".l"の順でtypeフィールドを追加したpathname
を作成し、ソースファイルを捜します。
compile-fileはキーワード引数として:output-file
を取ることがあります。この時には出力ファイル名はその引数がそのまま
使われ、typeを".fasl"に強制することはありません。
compile-fileはコンパイル中間ファイルとしてtypeが *.$ftmp$, *.$init$"の
ファイルを作成します。もし同一名のファイルが既に存在する場合は
上書きしますので、そういったファイル名は使わないでください。
(*)HCl ver1.6,
rel 1.1以前の版ではコンパイル結果を常にカレントデイレクトリに作りました
がrel 1.1以降ではソースファイルが存在するデイレクトリに出力します。
HCl コンパイラは変数の型宣言、optimize宣言によって
高速のコードを生成することができます。その内、特に重要と思われる点に
ついて解説します。
- (optimize (speed 3))宣言
-
速度を最重視したコードを生成します。このモードでは、単純な関数の
インライン展開、内部関数にレジスタインターフェイスなどが行われ、
エラーチェックも可能な限り行われません。コンパイルされた関数内部のトレース
は出来なくなります。
(optimize (safety 0))も同様のコードを生成します。
- (optimize (speed 2))宣言
-
関数の呼び出し時に引数の個数のチェックを行うコードを作成します。
関数内部は(optimize (speed 3))と同じ水準のコードです。
(optimize (safety 1))も同様のコードを生成します。
- (optimize (safety 3))宣言
-
コードの安全性を最優先したコードを生成します。このモードでは引数の
チェック、インライン展開の抑制、トレース可能なコードを生成します。
(optimize (speed 0))も同様のコードを生成します。
- fixnum宣言
-
HCl 内部では24bitで表現可能な整数はイミデイエイト表現されていて、
それを用いた加減算はインライン展開することができます。加減算をインライン
展開させるためにはその変数をtype宣言するか、(the fixnum form)によって
型宣言すればいいです。しかし引数を宣言しても計算結果がfixnumの範囲を越
えることがあるため単純なfixnum宣言では最高速度のコードを出せません。
そのためさらに高速のコードを生成するためには値域を積極的に宣言すること
が望まれます。例えば、代表的ベンチマーク問題、TAKなどでは
(type (integer -65536 65535) x y z)
の宣言が最速のコードを生成します。
- simple-vector宣言
-
HCl では高速の配列アクセスをサポートするためsimple-vectorは単純な構造
で内部表現されています。そのため、配列がsimple-vectorで型宣言された場合、
それへのアクセス関数はインライン展開されます。(type vector x)ではxが
汎用形式かsimple形式かの判定ができないためインライン展開されません。
HCl コンパイラは十分注意して作成されていますがまだ完全であるという
保証はありません。そこで、ある関数がコンパイルされる過程をモニタする
機能が組み込まれています。コンパイラパッケージにある変数
compiler:*debug-level*
はその値(0-5)によってコンパイラのメッセージレベルを定義します。
defaultは1です。値による振舞いは以下の通りです。
- 0. 最低限のメッセージ
- 1. 現在コンパイル中の関数名の表示、optimize情報の一部
- 2. 1より少し細かいメッセージ
- 3. 2より更に細かいメッセージ
- 4. 3よりもっと細かいメッセージ
- 5. コンパイラの中間形式を含む全情報
*debug-level* = 5はコンパイラの全処理過程を印刷しますので極めて大量の
情報を出力します。これをコンソールから把握することはほとんど不可能で
すからdribbleによって一旦ファイルに書き出しエデイタで調べることが賢明
かと思います。
もくじ