3

レジスタ割り当て (RA) 後にも定数の伝播を行うことが推奨されないのはなぜでしょうか。いくつかの最適化パス (ポスト RA) の後、一定の伝播/デッドコードの除去などのピープホール最適化の余地があります。2 つの理由しか考えられません。

  1. これらの最適化は SSA フォームで簡単に実行できます。
  2. のぞき穴の選択。RA を投稿すると、コンパイル時間が長くなります。

他に理由はありますか?

のぞき穴を実行しても問題ない場合は、opt. ポスト RA では、データ構造/アルゴリズムはどうあるべきか (論文、参考文献などは役に立ちます)。

編集: 500 - 内部サーバー エラーのコメントへの応答。最適化が phi-elimination のようにパスした後 (たとえば、llvm-clang では、レジスタ割り当てとマージされます)、次のようなグローバル スケジューリング: 親基本ブロックへの命令のプルアップなど。

EDIT2:

パス

図に示す例: レジスタ アロケータは、v1 と v2 が同じ値であることを認識し、同じレジスタ (r1) をそれらに割り当てます。レジスタ割り当て後、共通部分式削除パスはr2 = r1基本ブロック #4 から削除できます。

4

1 に答える 1

1

参照:コンスタントフォールディング

与えられた例、

 int x = 14;
 int y = 7 - x / 2;
 return y * (28 / x + 2);

xは、定数の折りたたみ後は完全に使用されません。RAを最初に使用すると、 のレジスタが作成されxます。そのため、結果が同じであっても、 RAフェーズを実行する前に何らかの剪定を行う可能性があります。さらに多くの変数がある場合、流出は回避できます。これらは、レジスタが割り当てられた後に元に戻すのが困難です。

絶え間ない伝播の代わりに、強度の低下を考えていると思いますか? これは、のぞき穴の最適化の精神に基づいています。または、通常はバックエンド部分であるピープホールフェーズ中の絶え間ない伝播の意味がわかりません。

レジスタ割り当ての前に適用された定数フォールディングは、変数が定数にされていないか、コードが無効であることが判明していない限り、同一である必要があります。つまり、CFGが変更されました。ミスティカルあたり

レジスタ割り当て後の SSA の削除では、LLVM 構造について説明しています。私は、SSA に定数値の注釈を付けて、Phi の消去時に不要な移動を回避できると信じています。これはおそらく、 RAや他のコンパイラでこの問題が発生しなくなった後の SSA の廃止による成果物です。別のパスを使用するとコンパイルが遅くなるため、既存のパスで問題に対処することをお勧めします。次のコードは問題を示していると思いますが、

 int foo(int a, int b)
 {
    int c;
    if(a > 0)
        c = 7;
    else
        c = a * b + 10;
    return a + c;
 }

ファイを消去すると、コードは次のようになります。

 int foo(int a, int b)
 {
    int c;
    if(a > 0) {
        c = 7;
        return a + c;  /* Should reduce to "a+7" */
    } else {
        c = a * b + 10;
        return a + c;
    }
 }
于 2013-03-21T16:51:23.667 に答える