summaryrefslogtreecommitdiff
path: root/chapter10/README.md
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-19 10:40:35 -0700
committerCliff Click <cliffc@acm.org>2026-10-19 10:40:35 -0700
commite7eb2db06d1b9c529f94f2da3a087c83c0498e05 (patch)
tree17a21219c7a28017b361bdeec011dda0afc562dc /chapter10/README.md
parentef8d9c4630db6af79c25526c8e80c54a48df4e39 (diff)
downloadSimple-e7eb2db06d1b9c529f94f2da3a087c83c0498e05.tar.gz
Simple-e7eb2db06d1b9c529f94f2da3a087c83c0498e05.zip
Turn off Store GVN with explaination
Diffstat (limited to 'chapter10/README.md')
-rw-r--r--chapter10/README.md33
1 files changed, 18 insertions, 15 deletions
diff --git a/chapter10/README.md b/chapter10/README.md
index db72c4cb..8b43f2b3 100644
--- a/chapter10/README.md
+++ b/chapter10/README.md
@@ -359,25 +359,28 @@ graph, not just a hoped-for cleanup afterward. See
The reverse direction extends
[Chapter 5's common-operation pull-down](../chapter05/README.md#example-3):
-"A Phis of Loads becomes a Load of a Phi". A Phi of matching Loads or Stores
-can become one operation after the join. For example, these two writes:
+"A Phi of Loads becomes a Load of Phis". A Phi of matching Loads can become
+one Load after the join. The rewrite creates a separate, correctly typed Phi
+for each differing operand, including memory and pointers. It must preserve
+the result's type and reject any possible conflicting write or memory merge
+among the memory's users. Otherwise delaying the read could change its value.
+Later chapters add anti-dependences; here we use a conservative check.
+
+Stores are excluded from GVN and this Phi rewrite. The easy GVN failure has
+equal Stores on two of three paths:
```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;
```
-can become `s.x = Phi(arg+1,arg+2)` and eventually `s.x = arg+Phi(1,2)`. The
-general rewrite creates a separate, correctly typed Phi for each differing
-operand, including memory and pointers. We must be more careful here with
-memory ops; it is possible to lose some type precision, so we check for that as
-part of the profitability.
-
-Also, a Store must have no other users, so moving it removes the original
-effect. A Load must have no possible conflicting writes or memory merges among
-its memory's users; otherwise delaying the read could change its value. Much
-later, we will be adding anti-dependences, but for now we do a conservative
-check.
+Sharing those Stores forces the scheduler to place the write on all three
+paths, including the path that should leave `s.x` unchanged. Sharing needs a
+proof that the original Stores cover every exit path, or a scheduler that can
+split the shared Store back onto its original paths. We do neither. Store
+equality therefore uses node identity; this also disables generic Phi factoring
+of Stores. Explicit store-after-store elimination remains enabled. Chapter 17b
+adds a separate peep that sinks a closed loop's Stores to the loop exit.
### Missing an easy one