2009-06-09 6 views
0

inline expansionの実装方法がわかりました。インライン展開の実装

私は楽しく教育するために自分のコンパイラを書いています。

私はたくさんの例を学ぶので、誰かが私にインライン展開を行うアルゴリズムを提供できれば、私は多くの助けになります。

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

私がインライン展開を行っているターゲット言語は、JavaScriptです。

編集: わかりやすくするために、私はShrinkSafeを改善する方法を探しています。
GWTはJavaScript関数をインライン化するので、可能です。 GWTはコードを実行する前にインライン展開します。

答えて

1

一般的な実装は、最適化フェーズで書き換えルールとして実行することです。実際の関数呼び出し命令は、呼び出された命令で置き換えられます(自然にreturn文は使用されません)。

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

これの最大の利点は、命令シーケンスがメモリ内で連続していることです。ピープルオプティマイザは、通常、スタックプッシュ/ポップの束を保存します。

+0

私はどのヒューリスティックを使用すべきですか? コードはどのように見えますか? 式が定数式であるかどうかを確認するにはどうすればよいですか? –

+0

あなたは基本的に "PUSH Reg1; PUSH Reg2; POP Reg3; POP Reg1;"というような一般的なパターンを探しています - PUSH命令は呼び出し元引数の設定から残るものです。 POPはインラインプロローグからのものです。これらの4つのインは、MOV Reg2→REG3のように書き直すことができます。オプティマイザで見つかるパターンの正確な種類はもちろん、*あなたのコンパイラによって生成される命令ストリームによって決定されるので、あなたはそれについての専門家です。 – MSalters

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のツリーの複製を作成する必要があります。その後、ツリーを解析して、関数呼び出しで使用されたパラメータへのすべての参照を変数(この場合はループ)に置き換えます。一度これが行われます。上記のツリーの[呼び出し]ノードを、作成したばかりの新しいツリーに置き換えます。

関連する問題