Skip to content

Commit ac231a6

Browse files
cristianocclaude
andcommitted
Name each IR dump after the pass that produced it
The -debug-ir labels had drifted from the sequence they describe. "initial" was dumped after collapse_var_aliases rather than before it, "flatten1" and "before-simplify-exits" each dumped a term already dumped under another name, "simplify_alias_before" named the pass that came next rather than the one that had run, and the output of guard_raises was labelled simplify_lets. Every dump is now named after the pass whose output it holds, and the three rounds of deep_flatten, simplify_alias and simplify_exits are numbered so a dump can be placed in the sequence. The initial dump now happens before collapse_var_aliases, so it is the term the pipeline was handed. Removed the commented-out scc pass with its dump label, and the commented-out collect_info and simplify_alias that followed sroa. The area guide linked to lam_convert.ml, which no longer exists, and said six constructors normalize as they build. There are seven: apply, prim, switch, stringswitch, if_, seq and not_. It now also carries the pass sequence as a table, with which statistics each pass consumes: only simplify_alias reads them, and a fresh collect_info runs immediately before each of its three rounds. Signed-off-by: Cristiano Calcagno <ccrisccris@gmail.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W8g8qwBARAcvW9MyuKQq8H
1 parent 85c954c commit ac231a6

3 files changed

Lines changed: 42 additions & 22 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
- Split `lambda.ml` into the IR and its traversals, static exits and path translation, so the module defining `Lambda.t` no longer reaches into `Env`, `Path` or `Parsetree`. https://github.com/rescript-lang/rescript/pull/8618
7777
- Record a record field's `@as` rename on the declaration instead of re-reading the attribute, so every place that needs the runtime name reads one field. https://github.com/rescript-lang/rescript/pull/8619
7878
- Record a variant constructor's `@as` tag on the declaration instead of re-interpreting its attributes, keeping the source spelling for printing. https://github.com/rescript-lang/rescript/pull/8619
79+
- Optimization passes now return the term they were given when they change nothing, rather than rebuilding an identical one. https://github.com/rescript-lang/rescript/pull/8620
7980
- Merge the duplicate Lam intermediate representation into Lambda, removing the conversion layer and obsolete supporting infrastructure. Lambda is now a single private, normalized representation, with generated JavaScript remaining semantically unchanged. https://github.com/rescript-lang/rescript/pull/8608
8081
- Rework the object-type representation end to end: object rows are plain field chains carrying a per-field mutability state (no phantom setter members), object literals are typed directly and property access and assignment are first-class AST and Lambda nodes shared between the Lambda and JS pipelines, and dead class-system remnants (the field-presence lattice, the class-abbreviation memo on object types, method-send typing) are removed. https://github.com/rescript-lang/rescript/pull/8597
8182
- Upgrade the development toolchain and primary CI builds to OCaml 5.5 while retaining OCaml 5.0 as the minimum supported version. https://github.com/rescript-lang/rescript/pull/8589

compiler/core/README.md

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,37 @@ Typedtree translation in `compiler/ml/translcore.ml` and
1010
`compiler/ml/translmod.ml` produces the `Lambda` representation defined in
1111
`compiler/ml/lambda.mli`.
1212

13-
[`lam_convert.ml`](lam_convert.ml)
14-
: Collects the modules a compilation unit depends on, read off the Lambda
15-
term.
16-
1713
`lam_pass_*.ml` and the other `lam_*.ml` modules
1814
: Analyze and transform Lambda. [`lam_compile_main.ml`](lam_compile_main.ml)
1915
coordinates the backend pass sequence; read it before inserting or
2016
reordering a pass.
2117

18+
The sequence is hand-unrolled rather than iterated to a fixed point. Only
19+
`simplify_alias` reads the statistics, and a fresh `collect_info` runs
20+
immediately before each of its three rounds. `simplify_lets` and `sroa`
21+
compute what they need themselves. Each `-debug-ir` dump is named after the
22+
pass whose output it holds.
23+
24+
| # | pass | statistics |
25+
|---|---|---|
26+
| 1 | `collapse_var_aliases` | |
27+
| 2 | `deep_flatten` | |
28+
| 3 | `simplify_exits` | |
29+
| 4 | `simplify_alias` | reads a snapshot taken just before |
30+
| 5 | `deep_flatten` | |
31+
| 6 | `simplify_alias` | reads a snapshot taken just before |
32+
| 7 | `deep_flatten` | |
33+
| 8 | `simplify_exits` | |
34+
| 9 | `simplify_alias` | reads a snapshot taken just before |
35+
| 10 | `simplify_lets` | own occurrence count |
36+
| 11 | `sroa` | own field-use classification |
37+
| 12 | `simplify_exits` | |
38+
| 13 | `guard_raises` | |
39+
40+
A snapshot is fresh when its pass starts, but `simplify_alias` also mutates
41+
the table as it rewrites, so entries can describe an earlier version of the
42+
term by the time the pass finishes.
43+
2244
[`lam_compile.ml`](lam_compile.ml)
2345
: Lowers Lambda to JavaScript IR. Primitive-specific and FFI lowering is split
2446
into `lam_compile_primitive.ml`, `lam_compile_external_call.ml`, and related
@@ -35,7 +57,8 @@ Typedtree translation in `compiler/ml/translcore.ml` and
3557
## Changing a representation
3658

3759
`Lambda.t` is private: every term is built through the constructors in
38-
[`../ml/lambda.mli`](../ml/lambda.mli), six of which normalize as they build.
60+
[`../ml/lambda.mli`](../ml/lambda.mli), seven of which normalize as they
61+
build: `apply`, `prim`, `switch`, `stringswitch`, `if_`, `seq` and `not_`.
3962
A constructor may replace a node with an equivalent one, but may not move code
4063
between branches - that is what a pass is for. When adding or changing a
4164
constructor, search every producer, traversal, optimizer, printer, serializer,

compiler/core/lam_compile_main.ml

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -290,48 +290,44 @@ let compile (output_prefix : string) export_idents hoisted (lam : Lambda.t) =
290290
Lam_compile_env.reset ()
291291
in
292292
let may_required_modules = required_modules lam in
293+
let lam = d "initial" lam in
293294
let lam =
294295
Lam_pass_collapse_var_aliases.collapse ~exports:export_ident_sets lam
295296
in
296-
297-
let lam = d "initial" lam in
297+
let lam = d "collapse_var_aliases" lam in
298298
let lam = Lam_pass_deep_flatten.deep_flatten lam in
299-
let lam = d "flatten0" lam in
299+
let lam = d "deep_flatten 1" lam in
300300
let meta : Lam_stats.t = Lam_stats.make ~export_idents ~export_ident_sets in
301301
let lam =
302302
let lam =
303-
lam |> d "flatten1" |> Lam_pass_exits.simplify_exits |> d "simplify_exits"
303+
lam |> Lam_pass_exits.simplify_exits |> d "simplify_exits 1"
304304
|> (fun lam ->
305305
Lam_pass_collect.collect_info meta lam;
306306
if debug_ir then
307307
Ext_log.dwarn ~__POS__ "Before simplify_alias: %a@." Lam_stats.print
308308
meta;
309309
lam)
310310
|> Lam_pass_remove_alias.simplify_alias meta
311-
|> d "simplify_alias" |> Lam_pass_deep_flatten.deep_flatten
312-
|> d "flatten2"
311+
|> d "simplify_alias 1" |> Lam_pass_deep_flatten.deep_flatten
312+
|> d "deep_flatten 2"
313313
in
314-
(* Inling happens*)
315-
314+
(* Inlining happens *)
316315
let () = Lam_pass_collect.collect_info meta lam in
317316
let lam = Lam_pass_remove_alias.simplify_alias meta lam in
317+
let lam = d "simplify_alias 2" lam in
318318
let lam = Lam_pass_deep_flatten.deep_flatten lam in
319+
let lam = d "deep_flatten 3" lam in
319320
let lam = lam |> Lam_pass_exits.simplify_exits in
320321
let () = Lam_pass_collect.collect_info meta lam in
321322

322-
lam |> d "simplify_alias_before"
323+
lam |> d "simplify_exits 2"
323324
|> Lam_pass_remove_alias.simplify_alias meta
324-
|> d "before-simplify_lets"
325+
|> d "simplify_alias 3"
325326
(* we should investigate a better way to put different passes : )*)
326327
|> Lam_pass_lets_dce.simplify_lets
327328
|> d "simplify_lets" |> Lam_pass_sroa.simplify |> d "sroa"
328-
|> d "before-simplify-exits"
329-
(* |> (fun lam -> Lam_pass_collect.collect_info meta lam
330-
; Lam_pass_remove_alias.simplify_alias meta lam) *)
331-
(* |> Lam_group_pass.scc_pass
332-
|> d "scc" *)
333-
|> Lam_pass_exits.simplify_exits
334-
|> Lam_pass_guard_raises.guard_raises |> d "simplify_lets"
329+
|> Lam_pass_exits.simplify_exits |> d "simplify_exits 3"
330+
|> Lam_pass_guard_raises.guard_raises |> d "guard_raises"
335331
|> fun lam ->
336332
if debug_ir then
337333
Ext_log.dwarn ~__POS__ "Before coercion: %a@." Lam_stats.print meta;

0 commit comments

Comments
 (0)