| 1 | LocalRef |
| 2 | ======== |
| 3 | |
| 4 | <:LocalRef:> is an optimization pass for the <:SSA:> |
| 5 | <:IntermediateLanguage:>, invoked from <:SSASimplify:>. |
| 6 | |
| 7 | == Description == |
| 8 | |
| 9 | This pass optimizes `ref` cells local to a <:SSA:> function: |
| 10 | |
| 11 | * global `ref`-s only used in one function are moved to the function |
| 12 | |
| 13 | * `ref`-s only created, read from, and written to (i.e., don't escape) |
| 14 | are converted into function local variables |
| 15 | |
| 16 | Uses <:Multi:> and <:Restore:>. |
| 17 | |
| 18 | == Implementation == |
| 19 | |
| 20 | * <!ViewGitFile(mlton,master,mlton/ssa/local-ref.fun)> |
| 21 | |
| 22 | == Details and Notes == |
| 23 | |
| 24 | Moving a global `ref` requires the <:Multi:> analysis, because a |
| 25 | global `ref` can only be moved into a function that is executed at |
| 26 | most once. |
| 27 | |
| 28 | Conversion of non-escaping `ref`-s is structured in three phases: |
| 29 | |
| 30 | * analysis -- a variable `r = Ref_ref x` escapes if |
| 31 | ** `r` is used in any context besides `Ref_assign (r, _)` or `Ref_deref r` |
| 32 | ** all uses `r` reachable from a (direct or indirect) call to `Thread_copyCurrent` are of the same flavor (either `Ref_assign` or `Ref_deref`); this also requires the <:Multi:> analysis. |
| 33 | |
| 34 | * transformation |
| 35 | + |
| 36 | -- |
| 37 | ** rewrites `r = Ref_ref x` to `r = x` |
| 38 | ** rewrites `_ = Ref_assign (r, y)` to `r = y` |
| 39 | ** rewrites `z = Ref_deref r` to `z = r` |
| 40 | -- |
| 41 | + |
| 42 | Note that the resulting program violates the SSA condition. |
| 43 | |
| 44 | * <:Restore:> -- restore the SSA condition. |