Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / src / XMLShrink.adoc
CommitLineData
7f918cf1
CE
1XMLShrink
2=========
3
4XMLShrink is an optimization pass for the <:XML:>
5<:IntermediateLanguage:>, invoked from <:XMLSimplify:>.
6
7== Description ==
8
9This pass performs optimizations based on a reduction system.
10
11== Implementation ==
12
13* <!ViewGitFile(mlton,master,mlton/xml/shrink.sig)>
14* <!ViewGitFile(mlton,master,mlton/xml/shrink.fun)>
15
16== Details and Notes ==
17
18The simplifier is based on <!Cite(AppelJim97, Shrinking Lambda
19Expressions in Linear Time)>.
20
21The source program may contain functions that are only called once, or
22not even called at all. Match compilation introduces many such
23functions. In order to reduce the program size, speed up later
24phases, and improve the flow analysis, a source to source simplifier
25is run on <:XML:> after type inference and match compilation.
26
27The simplifier implements the reductions shown below. The reductions
28eliminate unnecessary declarations (see the side constraint in the
29figure), applications where the function is immediate, and case
30statements where the test is immediate. Declarations can be
31eliminated only when the expression is nonexpansive (see Section 4.7
32of the <:DefinitionOfStandardML: Definition>), which is a syntactic
33condition that ensures that the expression has no effects
34(assignments, raises, or nontermination). The reductions on case
35statements do not show the other irrelevant cases that may exist. The
36reductions were chosen so that they were strongly normalizing and so
37that they never increased tree size.
38
39* {empty}
40+
41--
42[source,sml]
43----
44let x = e1 in e2
45----
46
47reduces to
48
49[source,sml]
50----
51e2 [x -> e1]
52----
53
54if `e1` is a constant or variable or if `e1` is nonexpansive and `x` occurs zero or one time in `e2`
55--
56
57* {empty}
58+
59--
60[source,sml]
61----
62(fn x => e1) e2
63----
64
65reduces to
66
67[source,sml]
68----
69let x = e2 in e1
70----
71--
72
73* {empty}
74+
75--
76[source,sml]
77----
78e1 handle e2
79----
80
81reduces to
82
83[source,sml]
84----
85e1
86----
87
88if `e1` is nonexpansive
89--
90
91* {empty}
92+
93--
94[source,sml]
95----
96case let d in e end of p1 => e1 ...
97----
98
99reduces to
100
101[source,sml]
102----
103let d in case e of p1 => e1 ... end
104----
105--
106
107* {empty}
108+
109--
110[source,sml]
111----
112case C e1 of C x => e2
113----
114
115reduces to
116
117[source,sml]
118----
119let x = e1 in e2
120----
121--