diff options
| author | Cliff Click <cliffc@acm.org> | 2026-10-19 10:40:35 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-10-19 10:40:35 -0700 |
| commit | e7eb2db06d1b9c529f94f2da3a087c83c0498e05 (patch) | |
| tree | 17a21219c7a28017b361bdeec011dda0afc562dc /chapter10/README.md | |
| parent | ef8d9c4630db6af79c25526c8e80c54a48df4e39 (diff) | |
| download | Simple-e7eb2db06d1b9c529f94f2da3a087c83c0498e05.tar.gz Simple-e7eb2db06d1b9c529f94f2da3a087c83c0498e05.zip | |
Turn off Store GVN with explaination
Diffstat (limited to 'chapter10/README.md')
| -rw-r--r-- | chapter10/README.md | 33 |
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 |
