技術

3.2. コード生成の準備

LLVMによるプログラミング言語の実装チュートリアル日本語訳
第3章 万華鏡: LLVM IRコードの生成
第2節 コード生成の準備

LLVM IRを生成するために、いくつかのちょっとした準備を行いたい。
まず、virtualなコード生成(codegen)メソッドを各ASTクラスに定義する。

/// ExprAST - 式ノードのためのクラス。
class ExprAST {
public:
  virtual ~ExprAST() {}
  virtual Value *Codegen() = 0;
};

/// NumberExprAST - "1.0"のような数値リテラルのための式クラス。
class NumberExprAST : public ExprAST {
  double Val;
public:
  NumberExprAST(double val) : Val(val) {}
  virtual Value *Codegen();
};
...

Codegen()メソッドは、ASTノードとその依存しているもの全てのためのIRを発行するということを表現していて、それら全てはLLVM Valueオブジェクトを返す。
“Value”は、LLVMにおいて”静的単一代入(Static Single Assignment: SSA)レジスタ”や”SSA値”を表現するために利用されるクラスである。
一番注目すべきSSA値の特徴は、SSA関連の命令の実行によって計算され、そしてその命令が再実行されるまで新しい値を得ない点である。
言い換えれば、SSA値を”変更(change)”する方法はないということである。
詳しくは http://en.wikipedia.org/wiki/Static_single_assignment_form を読んでみよう。
SSAについて理解できたら、そのコンセプトが実に理にかなったものであることが分かるだろう。
訳注: SSA(静的単一代入)については日本語の記事もたくさんあるので調べてみると良い。

ExprASTクラスの階層に仮想関数を追加する代わりに、Visitorパターンや他の方法によって同じようなことが実現出来得ることに注意。
再度になるが、このチュートリアルではソフトウェア工学上の良い習わしについてクドクド述べるようなことはしない。
このチュートリアルのような場合だと、仮想関数を使うのがいちばん簡単である。

次は、構文解析器で使ったような、コード生成中に見つかったエラー(例えば、未定義のパラメータを使用したとか)を通知するための”Error”メソッドを追加したい。

Value *ErrorV(const char *Str) { Error(Str); return 0; }

static Module *TheModule;
static IRBuilder<> Builder(getGlobalContext());
static std::map<std::string, Value*> NamedValues;

各静的変数はコード生成中に使用される。
TheModuleは、コードの中にある全ての関数とグローバル変数を含む、LLVMの構成物である。
多くの場合、LLVM IRがコードを収容するために使用するトップレベルの構造物となる。

Builderオブジェクトは、LLVM命令を生成するのを簡単にするためのヘルパオブジェクトである。
IRBuilderテンプレートクラスは、命令を挿入すべき現在位置を追い続ける。
また、新たな命令を生成するためのメソッドも備えている。

NamedValuesマップは、現在のスコープにおいてどの値が定義されているか、そしてそのLLVM表現(LLVM representation)は何なのかについて追い続ける。
(別の言葉でいうと、これはシンボルテーブルである。)
現在の万華鏡の構造だと、これによって参照されるのは関数の引数のみである。
なので、関数本体がコード生成処理の対象となってる最中は、その関数の引数はこの変数(NamedValues)の中に存在する事になるだろう。

さて、以上の基本的な事項によって、色んな式のためのコードを生成する方法について考え始める準備が出来た。
Builderについてはすでにセットアップ済みと仮定している事に注意。
ここでは、すでにセットアップが済み、後はコードを生成するために使うのみということを仮定している。
訳注: Builderがどうセットアップされるかについては、第3章の最後にある完全に動作するコードのソースを見ると良い。

コメントを残す

メールアドレスが公開されることはありません。



※画像をクリックして別の画像を表示

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください