@@ -7,17 +7,12 @@ existing translation from clambda to cmm. However, that gave very little control
7
7
to flambda in terms of unboxing, since most optimizations relating to unboxing
8
8
happens during the clambda to cmm translation.
9
9
10
- The translation from flambda2 to cmm is currently named ` un_cps ` for historical
11
- reasons (because it ` un ` does the ` cps ` form of flambda2), but it is expected to
12
- change toward a less obscure name at one point.
13
-
14
-
15
10
## Overview
16
11
17
12
See [ this file] ( term_language.md ) for a description of the flamdba2 language,
18
13
and [ the cmm doc] ( cmm.md ) for an overview of the cmm language.
19
14
20
- This section provides an overview of the main tasks of the ` un_cps `
15
+ This section provides an overview of the main tasks of the ` to_cmm `
21
16
translation. First these "tasks" are listed, and then are explained in details,
22
17
together with their motivations and requirements. The technical aspect of how
23
18
these tasks are implemented will be discussed in the following section).
@@ -70,7 +65,7 @@ and lower these operations are explicit, e.g.:
70
65
71
66
One good point compared to cmmgen is that we can assume that the flambda
72
67
simplifier will already have unboxed things that can be unboxed, so contrary to
73
- ` cmmgen ` , ` un_cps ` does not need to do the work of trying to find unboxing
68
+ ` cmmgen ` , ` to_cmm ` does not need to do the work of trying to find unboxing
74
69
optimizations.
75
70
76
71
#### "Big" and "small" values
@@ -93,7 +88,7 @@ ocaml values across functions.
93
88
94
89
"small" values are values which are strictly smaller than register, and whose
95
90
semantics usually need this smaller value space; typically, these are 32-bit
96
- integers on 64-bit platforms. For these values, ` un_cps ` need to choose one
91
+ integers on 64-bit platforms. For these values, ` to_cmm ` need to choose one
97
92
encoding into 64-bits registers, and translate the abstract operations from
98
93
flambda2 on these types to concrete operations on registers in a way that
99
94
preserve the expected semantics.
@@ -132,7 +127,7 @@ compared to generating A-normal forms; some of these reasons are:
132
127
Conversely, when this is not the case, the compiler pipeline will
133
128
automatically add a (= 0) comparison, resulting in a few more instructions.
134
129
135
- Thus ` un_cps ` does the following:
130
+ Thus ` to_cmm ` does the following:
136
131
- remove pure and co-effectful-only expressions which are never used
137
132
- substitute pure and co-effectful-only expressions which are used exactly once
138
133
- if the option is set, substitute effectful expressions which are used exactly once
@@ -178,7 +173,7 @@ not inline sets of closures across modules anymore, and thus all sharing are
178
173
restricted to the current module, there should not be any instance where
179
174
the offset computation can fail.
180
175
181
- Currently, ` un_cps ` implements a greedy algorithm for filling out sets of
176
+ Currently, ` to_cmm ` implements a greedy algorithm for filling out sets of
182
177
closures and assign offsets. It iterates over closures, assigning the lowest
183
178
offset that is free in all sets of closures where it appears, and then does the
184
179
same for all env vars. While not optimal as it may leave gaps, this should
@@ -198,24 +193,24 @@ flambda2.
198
193
199
194
### Organization of the code and main control flow of the translation
200
195
201
- ` un_cps ` translate flambda2 expressions using two traversals of an flambda2
196
+ ` to_cmm ` translate flambda2 expressions using two traversals of an flambda2
202
197
body.
203
198
204
199
The first traversal iterates over all sets of closures defined by the body.
205
200
This allows to assign offsets to all members of sets of closures (taking into
206
201
account constraints due to a potential sharing of closures of env vars beetween
207
- sets of closures), using the code in ` un_cps_closure .ml` .
202
+ sets of closures), using the code in ` to_cmm_closure .ml` .
208
203
209
- After that, ` un_cps ` operates the second, and main traversal of the
204
+ After that, ` to_cmm ` operates the second, and main traversal of the
210
205
expression, accumulating information (about continuations, substitutions, etc)
211
- in an environment (defined in ` un_cps_env .ml` ), and then returning two
206
+ in an environment (defined in ` to_cmm_env .ml` ), and then returning two
212
207
values: the resulting cmm expression, and a static result that contains all
213
208
the constants that should be pre-allocated (in comparison, ` cmmgen ` uses a global
214
209
reference to store that information during translation). This static result
215
- (defined in ` un_cps_result .ml` ) will be grown by the translation, by either
210
+ (defined in ` to_cmm_result .ml` ) will be grown by the translation, by either
216
211
` let_symbol ` bindings or sets of closures bindings. Translations of flambda2
217
212
expression that can result in pre-allocation of static constants go through
218
- the ` un_cps_static .ml` file.
213
+ the ` to_cmm_static .ml` file.
219
214
220
215
### Tagging and unboxing
221
216
@@ -225,7 +220,7 @@ of values, e.g. boxed integers are identified with their size, tagged integers
225
220
are differentiated from untagged integers, ... . Together with information
226
221
about what the cmm primitives expect (i.e. which primitive expect or return
227
222
a tagged integer, and which deal with untagged integers), this offers a
228
- rather comprehensive way for ` un_cps ` to know when or where to tag/untag
223
+ rather comprehensive way for ` to_cmm ` to know when or where to tag/untag
229
224
things. See the following for more details:
230
225
- ` middle_end/flambda/terms/flambda_primitive.ml ` for the data about kinds
231
226
consumed/returned by flambda primitives (particularly the
@@ -234,11 +229,11 @@ things. See the following for more details:
234
229
(this is still a TODO)
235
230
236
231
Unboxing is also straightforward: as mentioned earlier, flambda2 already
237
- takes care of identifying and applying all the unboxing we want, so ` un_cps `
232
+ takes care of identifying and applying all the unboxing we want, so ` to_cmm `
238
233
only introduces the boxing and unboxing as needed, using the same information
239
234
as for tagging/untagging.
240
235
241
- For the concrete implementation, ` un_cps ` mostly re-uses code from
236
+ For the concrete implementation, ` to_cmm ` mostly re-uses code from
242
237
` cmm_helpers ` .
243
238
244
239
### "Big" and "small" values
@@ -254,13 +249,13 @@ bits and its higher bits, and then carried on two registers. Handling these
254
249
is relatively straightforward since the low-level operations are already
255
250
written in ` cmm_helpers ` .
256
251
257
- A difference between ` cmmgen ` and ` un_cps ` is that flambda2 has explicit
252
+ A difference between ` cmmgen ` and ` to_cmm ` is that flambda2 has explicit
258
253
box/unbox operations on these, and as such, where ` cmmgen ` is in control of the
259
254
boxing and thus most of the time generate calls to function that handle the
260
- boxed version of Int64s, ` un_cps ` actually has to mostly deal with unboxed
255
+ boxed version of Int64s, ` to_cmm ` actually has to mostly deal with unboxed
261
256
Int64, and generate calls that handle the unboxed variant.
262
257
263
- Currently, there may be some cases in ` un_cps ` that will raise a fatal error
258
+ Currently, there may be some cases in ` to_cmm ` that will raise a fatal error
264
259
because there was not yet an unboxed version of the required function in the
265
260
runtime.
266
261
@@ -298,8 +293,8 @@ a trap mechanism to mirror that of flambda2.
298
293
299
294
### Let-binding substitution
300
295
301
- This is the most complex part of ` un_cps ` and also the part most sensitive
302
- to changes (even innocuous changes in ` un_cps ` might break becasue of this).
296
+ This is the most complex part of ` to_cmm ` and also the part most sensitive
297
+ to changes (even innocuous changes in ` to_cmm ` might break becasue of this).
303
298
The goal is to substitute let-bound variable's bodies during translation, because
304
299
it allows for more optimizations. There are two technical challenges
305
300
with this:
@@ -309,7 +304,7 @@ with this:
309
304
continuations, in which case the expression might be evaluated more than once).
310
305
311
306
Most of the code to deal with this is in the definition of the translation
312
- environment in ` un_cps_env ` : the environment accumulates all let-bindings
307
+ environment in ` to_cmm_env ` : the environment accumulates all let-bindings
313
308
(whether that can be substituted or not), since we have to be able to
314
309
substitute through a non-substitutable binding. A nice consequence of that is
315
310
that translating a let-binding can then be tail-rec, which is very useful.
@@ -322,7 +317,7 @@ Let-bindings are stored in the environment in a few structures:
322
317
or a single effectful binding.
323
318
These two structures are used to store enough information to perform substitution
324
319
if needed. Additionally, another map is used to relate all flambda2 variables to
325
- corresponding cmm variables. This mapping is used when ` un_cps ` decides not to
320
+ corresponding cmm variables. This mapping is used when ` to_cmm ` decides not to
326
321
substitute a variable's body.
327
322
328
323
When a let-bound variable has to be translated, a special env lookup is used,
0 commit comments