1

インライン展開を実装する方法を知りたいです。

私は楽しみと教育のためだけに独自のコンパイラを書いています。

私は例によって多くのことを学んでいるので、インライン化を行うアルゴリズムを誰かが提供してくれれば、とても助かります。

私は C++ の方が好きですが、言語は関係ありません。

インライン化を記述しようとしているターゲット言語は JavaScript です。

編集: 明確にするために、 ShrinkSafeを改善する方法を探しています。
GWT は JavaScript 関数をインライン化するので、それが可能です。GWT は、コードが実行される前にインライン化を行います。

4

2 に答える 2

2

一般的な実装は、書き換えルールとして最適化フェーズで行うことです。実際の関数呼び出し命令を、呼び出された命令に置き換えます (もちろん、return ステートメントは除きます)。

次に、ピープホール オプティマイザーが呼び出し命令の前にあるスタック セットアップと、現在インライン化されている呼び出し先のプロローグを削除できることを確認します。同様に、ピープホール オプティマイザーが呼び出し先のエピローグと呼び出し元の戻り値の処理を最適化できることを確認する必要があります。

これの最大の利点は、命令シーケンスがメモリ内で連続するようになり、通常、ピープホール オプティマイザによって一連のスタック プッシュ/ポップが節約されることです。

于 2009-06-09T11:33:01.200 に答える
1

インライン化は、コードがツリーに解析された後に行われます。

for(int loop=1;loop <= 10;++loop)
{
    f(loop);
}

for-|
    --- (Init Code)---Assign--|
    |                         --- loop
    |                         |
    |                         --- 1
    --- (Condition)--- <= |
    |                     --- loop
    |                     |
    |                     --- 10
    --- (Post) --- ++ |
    |                 --- loop
    |
    --- (Body) Call |
                    --- (Function Name) f
                    |
                    --- (Parameter List)---Node1 -- loop
                                             |
                                           NULL

関数 f の構文木も作成します。
関数をインライン化するには、関数 f のツリーの複製を作成する必要があります。次に、ツリーを解析して、関数呼び出しで使用されるパラメーターへのすべての参照を変数に置き換えます (この場合はループ)。これが完了したら。上記のツリーの「Call」ノードを、作成したばかりの新しいツリーに置き換えます。

于 2009-06-09T15:26:06.097 に答える