質問に答えるのに最適な本は、おそらくCooper and Torczon、 "Engineering a Compiler、" 2003です。大学図書館にアクセスできる場合は、コピーを借りることができます。
O(n2)n
O(n)O(n)
O(n)O(1)O(s)s
次に、解析ツリーは通常、制御フローグラフに「フラット化」されます。制御フローグラフのノードは3アドレス命令(RISCアセンブリ言語に類似)である可能性があり、制御フローグラフのサイズは通常、解析ツリーのサイズに比例します。
O(d)dO(n)n
より高度な最適化を行うには、より高度な分析を行うことをお勧めします。この時点で、トレードオフに陥り始めます。解析アルゴリズムによりもはるかに少ない時間がかかることを望むO(n2)プログラム全体のフローグラフのサイズの時間ですが、これは、証明するのに費用がかかる情報(およびプログラムを改善する変換)なしで行う必要があることを意味します。この典型的な例はエイリアス分析です。ここでは、メモリ書き込みのいくつかのペアについて、2つの書き込みが同じメモリ位置を決してターゲットにできないことを証明したいと考えています。(エイリアス分析を実行して、1つの命令を他の命令の上に移動できるかどうかを確認することもできます。)しかし、エイリアスに関する正確な情報を取得するには、プログラム内のすべての制御パスを分析する必要があります。プログラム内(したがって、制御フローグラフ内のノード数の指数関数的)
次に、レジスタの割り当てに入ります。レジスターの割り当ては、グラフの色付けの問題として表現することができ、最小数の色でグラフを色付けすることはNPハードであることが知られています。そのため、ほとんどのコンパイラーは、レジスターのスピル数を合理的な時間内にできる限り減らすことを目的に、レジスターのスピルと組み合わせたある種の貪欲なヒューリスティックを使用します。
最後に、コード生成に入ります。コード生成は通常、一度に最大の基本ブロックで実行されます。この場合、基本ブロックは、単一のエントリと単一の出口を持つ線形接続された制御フローグラフノードのセットです。これは、カバーしようとしているグラフが基本ブロック内の3アドレス命令のセットの依存グラフであり、使用可能なマシンを表すグラフのセットでカバーしようとしている問題をカバーするグラフとして再定式化できます。指示。この問題は、最大の基本ブロックのサイズが指数関数的であるため(原則として、プログラム全体のサイズと同じ順序になる可能性があります)、これは通常、可能性のあるカバーのごく一部のみが発見的手法で行われます調べた。