Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / src / RefFlatten.adoc
CommitLineData
7f918cf1
CE
1RefFlatten
2==========
3
4<:RefFlatten:> is an optimization pass for the <:SSA2:>
5<:IntermediateLanguage:>, invoked from <:SSA2Simplify:>.
6
7== Description ==
8
9This pass flattens a `ref` cell into its containing object.
10The idea is to replace, where possible, a type like
11----
12(int ref * real)
13----
14
15with a type like
16----
17(int[m] * real)
18----
19
20where the `[m]` indicates a mutable field of a tuple.
21
22== Implementation ==
23
24* <!ViewGitFile(mlton,master,mlton/ssa/ref-flatten.fun)>
25
26== Details and Notes ==
27
28The savings is obvious, I hope. We avoid an extra heap-allocated
29object for the `ref`, which in the above case saves two words. We
30also save the time and code for the extra indirection at each get and
31set. There are lots of useful data structures (singly-linked and
32doubly-linked lists, union-find, Fibonacci heaps, ...) that I believe
33we are paying through the nose right now because of the absence of ref
34flattening.
35
36The idea is to compute for each occurrence of a `ref` type in the
37program whether or not that `ref` can be represented as an offset of
38some object (constructor or tuple). As before, a unification-based
39whole-program with deep abstract values makes sure the analysis is
40consistent.
41
42The only syntactic part of the analysis that remains is the part that
43checks that for a variable bound to a value constructed by `Ref_ref`:
44
45* the object allocation is in the same block. This is pretty
46draconian, and it would be nice to generalize it some day to allow
47flattening as long as the `ref` allocation and object allocation "line
48up one-to-one" in the same loop-free chunk of code.
49
50* updates occur in the same block (and hence it is safe-for-space
51because the containing object is still alive). It would be nice to
52relax this to allow updates as long as it can be provedthat the
53container is live.
54
55Prevent flattening of `unit ref`-s.
56
57<:RefFlatten:> is safe for space. The idea is to prevent a `ref`
58being flattened into an object that has a component of unbounded size
59(other than possibly the `ref` itself) unless we can prove that at
60each point the `ref` is live, then the containing object is live too.
61I used a pretty simple approximation to liveness.