エイリアス解析は、コンパイラ理論における手法の一つで、記憶領域へのアクセス方法が複数存在するかどうかを判断するために用いられる。2つのポインタが同じ場所を指している場合、それらはエイリアスされていると言われる。
エイリアス解析手法は、通常、フロー感度とコンテキスト感度によって分類されます。これらの手法は、エイリアスである可能性のある情報と、エイリアスであるべき情報を判定することができます。エイリアス解析という用語は、特定のケースであるポインタ解析とほぼ同義で用いられることがよくあります。
エイリアスアナライザーは、プログラムにおけるエイリアシングを理解するための有用な情報を生成および計算することを目的としています。
一般的に、エイリアス解析は、複数のメモリ参照が同じメモリ領域を指しているかどうかを判定します。これにより、コンパイラはプログラム内のどの変数がステートメントによって影響を受けるかを判断できます。例えば、構造体のメンバにアクセスする以下のコード部分を考えてみましょう。
p.foo = 1 ; q.foo = 2 ; i = p.foo + 3 ;エイリアスを使う場合、考えられるケースは3つあります。
p と q がエイリアスできない場合は、i = p.foo + 3;を に変更できますi = 4。 p と q がエイリアスする必要がある場合は、=であるためi = p.foo + 3;、 を に変更できます。どちらの場合も、エイリアス情報から最適化を実行できます (同じ場所を更新する他のスレッドが現在のスレッドとインターリーブできないこと、または明示的な同期構造がない場合に言語メモリ モデルがこれらの更新を現在のスレッドからすぐには見えないことを許可していることを前提としています)。 一方、p と q がエイリアスかどうか不明な場合は、最適化は実行できず、結果を得るにはコード全体を実行する必要があります。 2 つのメモリ参照は、エイリアスが不明な場合、エイリアス関係を持つと言われます。i = 5p.foo + 3q.foo + 3
エイリアス解析では、プログラムのメモリをエイリアスクラスに分割します。エイリアスクラスは、互いにエイリアスできない、互いに素な場所の集合です。ここでの議論では、最適化はプログラムの低レベルの中間表現に対して行われるものと想定します。つまり、プログラムはバイナリ操作、ジャンプ、レジスタ間の移動、レジスタからメモリへの移動、メモリからレジスタへの移動、分岐、関数呼び出し/戻りにコンパイルされているものとします。
コンパイル対象の言語が型安全であり、コンパイラの型チェッカーが正しく、かつその言語がローカル変数を参照するポインタを作成する機能を持たない場合(ML、Haskell、Javaなど)、いくつかの有用な最適化を行うことができます。[ 1 ] 2つのメモリ位置が異なるエイリアスクラスに属している必要があることがわかっているケースは多数あります。
コードのエイリアス解析を実行する際には、メモリへのすべてのロードとストアにクラスラベルを付ける必要がある。そうすると、メモリ位置が与えられた場合に便利なプロパティが得られる。そしてとエイリアスクラス、もしそれからメイエイリアス、そしてもしそうすれば、メモリ位置はエイリアスしません。
フローに基づく解析は、参照や型キャストを使用する言語のプログラムに適用できます。フローに基づく解析は、型に基づく解析の代わりとして、または補完として使用できます。フローに基づく解析では、メモリ割り当てごと、およびアドレスが使用されたすべてのグローバル変数とローカル変数ごとに、新しいエイリアスクラスが作成されます。参照は時間の経過とともに複数の値を指す場合があり、そのため複数のエイリアスクラスに属する可能性があります。つまり、各メモリ位置には、単一のエイリアスクラスではなく、一連のエイリアスクラスが存在することになります。