私が知りたいのは、インタープロシージャル データ フロー分析中の IR のメモリ管理における現在の最新技術です。分析中に完全なコードの IR がメモリに存在するか、または任意の時点で IR をロードおよびアンロードするためにいくつかのメモリ管理手法が適用されるかを知りたいです。llvm/gcc インフラストラクチャのコンテキストでは、分析を何百万行ものコードにスケーリングする方法を教えてください。
1 に答える
プログラム全体の IR を保持することが問題であることは正しいです。現在の最新技術は、GCC と LLVM の両方でプログラム全体の最適化を可能にするゴールド リンカーです。初期のプログラム全体の最適化の設計案は、2007 年以降多くの変更が加えられていますが、その仕組みについて私が見つけた最良の説明です。
一般に、次の 3 つの段階があります。
各コンパイル ユニットは、オブジェクト ファイルに個別にコンパイルおよび最適化されます*。ここでの最適化には、手続き間の最適化を含めることができますが、それらはコンパイル単位の境界を超えません。
リンカーはすべてのオブジェクト ファイルを分析し、プログラム全体の制御フロー グラフを作成します。これはメモリを集中的に使用しますが、管理しやすいため、ここでは完全な関数コードは必要ありません。次に、リンカーが実行する必要がある変換について決定が行われます。
リンカーは、手順 (2) で決定されたとおりに変換を実行します。これらはそれぞれローカライズされているため、プログラム コード全体の限られたサブセットのみをロードする必要があります。
手順 (1) と (3) は、並行して実行できる多くのタスクで構成されています。
* 通常のオブジェクト ファイルよりもコンパイラ IR を使用すると、最適化が向上します。GCC では、オブジェクト ファイル内に IR を埋め込むことで機能します。LLVM では、LLVM IR ファイルをオブジェクト ファイルとしてリンカーに提供するだけで機能します。どちらの場合も、これはリンカーへのプラグインを使用することで有効になります。