diff options
Diffstat (limited to 'chapter10/README.ja.md')
| -rw-r--r-- | chapter10/README.ja.md | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/chapter10/README.ja.md b/chapter10/README.ja.md index efc4f0ea..e81fbdc9 100644 --- a/chapter10/README.ja.md +++ b/chapter10/README.ja.md @@ -229,16 +229,16 @@ Load(Phi(r, m0, m1), p.x) メモリの Phi が、ロードされた値の Phi になります。このピープホール変換は Node の総数を増やすので、利益のヒューリスティックは、少なくとも1つの Load が畳み込まれることを要求します。ループの場合、この Load は**後退エッジ**でなければなりません。入口だけで畳み込むと、サイクルに沿って無限に押し上げ続けられるロードが残るためです。算術の書き換えと同じく、畳み込みを露出させることは、変換後の後片付けに期待するものではなく、グラフを変換する判断の一部です。[`LoadNode.idealize()`](src/main/java/com/seaofnodes/simple/node/LoadNode.java) を参照してください。 -逆方向は[第5章の共通演算の引き下げ](../chapter05/README.ja.md#例3)を拡張します。「Load の Phi は、Phi の Load になる」。対応する Load や Store の Phi は、合流後の1つの演算にできます。たとえば、次の2つの書き込みは、 +逆方向は[第5章の共通演算の引き下げ](../chapter05/README.ja.md#例3)を拡張します。「Load の Phi は、Phi の Load になる」。対応する Load の Phi は、合流後の1つの Load にできます。メモリやポインタも含め、異なる各オペランドについて正しく型付けされた別々の Phi を作ります。結果の型を保ち、メモリのユーザーに競合する書き込みやメモリの合流があれば変換を断念します。読み出しを遅らせると値が変わり得るためです。後の章では反依存を加えますが、ここでは保守的にチェックします。 + +Store は GVN とこの Phi の書き換えから除外します。簡単な GVN の失敗例は、3経路のうち2経路に同じ Store がある場合です。 ```java -if (arg) s.x = arg+1; -else s.x = arg+2; +if (arg == 1) s.x = 9; +else if (arg == 2) s.x = 9; ``` -`s.x = Phi(arg+1,arg+2)` になり、最終的には `s.x = arg+Phi(1,2)` にできます。一般的な書き換えでは、メモリやポインタも含め、異なる各オペランドについて正しく型付けされた別々の Phi を作ります。メモリ演算にはさらに注意が必要です。型の精度が失われる可能性があるので、それも利益判定の一部としてチェックします。 - -また、Store を移動したときに元の作用が消えるように、Store にほかのユーザーがあってはいけません。Load については、そのメモリのユーザーに、競合する書き込みやメモリの合流が生じる可能性があってはいけません。そうでなければ、読み出しを遅らせると値が変わり得ます。ずっと後に反依存を追加しますが、今は保守的にチェックします。 +この2つを共有すると、スケジューラは `s.x` を変更しないはずの経路も含め、3経路すべてで書き込む位置に Store を置いてしまいます。共有には、元の Store がすべての出口経路を覆うという証明、または共有した Store を元の経路に分割し直せるスケジューラが必要です。どちらも実装していないので、Store の等価性にはノードの同一性を使います。これにより一般的な Phi による Store の共通化も無効になります。連続する Store の除去は引き続き有効です。第17b章では、閉じたループの Store をループ出口に移す専用のピープホール変換を追加します。 ### 簡単な最適化を見逃す |
