Skip to content

Commit fafad72

Browse files
authored
feat(compiler): Upgrade to Binaryen v124 (#2333)
1 parent 888a979 commit fafad72

File tree

6 files changed

+127
-60
lines changed

6 files changed

+127
-60
lines changed

compiler/esy.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@
2525
"copy:exe": "cp -f #{$GRAINC_BIN_PATH} #{$GRAINDOC_BIN_PATH} #{$GRAINFORMAT_BIN_PATH} #{$GRAINLSP_BIN_PATH} #{$CLI_BIN_DIR}",
2626
"copy:js": "cp -f #{$GRAINC_JS_PATH} #{$GRAINDOC_JS_PATH} #{$GRAINFORMAT_JS_PATH} #{$GRAINLSP_JS_PATH} #{$CLI_BIN_DIR}",
2727
"clean": "rm -rf #{self.root}/_esy",
28-
"build:js": "esy b dune build @js --no-buffer #{os == 'windows' ? '-j 2' : ''}",
28+
"build:js": "esy b dune build @js --no-buffer -j 2",
2929
"test": "#{$TEST_EXEC_PATH}",
3030
"test:js": "node #{$TEST_JS_PATH}",
3131
"format": "dune build @fmt --auto-promote",
3232
"check-format": "dune build @fmt"
3333
},
3434
"dependencies": {
35-
"@grain/binaryen.ml": ">= 0.27.0 < 0.28.0",
35+
"@grain/binaryen.ml": ">= 0.34.0 < 0.35.0",
3636
"@opam/cmdliner": ">= 1.1.1 < 2.0.0",
3737
"@opam/dune": ">= 3.17.1 < 4.0.0",
3838
"@opam/dune-build-info": ">= 3.17.1 < 4.0.0",

compiler/esy.lock/index.json

Lines changed: 20 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/esy.lock/opam/topkg.1.1.0/opam renamed to compiler/esy.lock/opam/topkg.1.1.1/opam

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/src/codegen/compcore.re

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3465,7 +3465,11 @@ let compile_wasm_module =
34653465
];
34663466
let features =
34673467
if (Config.bulk_memory^) {
3468-
[Module.Feature.bulk_memory, ...default_features];
3468+
[
3469+
Module.Feature.bulk_memory,
3470+
Module.Feature.bulk_memory_opt,
3471+
...default_features,
3472+
];
34693473
} else {
34703474
default_features;
34713475
};
@@ -3478,6 +3482,10 @@ let compile_wasm_module =
34783482
Option.is_none(Grain_utils.Config.memory_base^),
34793483
);
34803484

3485+
// Our compiler generates code that should never trap, so enabling this allows
3486+
// Binaryen to perform more aggressive optimizations
3487+
let _ = Settings.set_traps_never_happen(true);
3488+
34813489
compile_type_metadata(wasm_mod, env, prog);
34823490

34833491
ignore @@

compiler/src/codegen/optimize_mod.re

Lines changed: 93 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,79 @@
11
open Binaryen;
22
open Grain_utils;
33

4-
// Defaults from https://github.com/WebAssembly/binaryen/blob/version_107/src/pass.h#L170-L171
4+
// Defaults from https://github.com/WebAssembly/binaryen/blob/version_124/src/pass.h#L247-L248
55
let default_optimize_level = 2;
66
let default_shrink_level = 1;
77

88
let has_gc = wasm_mod =>
99
List.mem(Module.Feature.gc, Module.get_features(wasm_mod));
10+
let has_multivalue = wasm_mod =>
11+
List.mem(Module.Feature.multivalue, Module.get_features(wasm_mod));
12+
let has_strings = wasm_mod =>
13+
List.mem(Module.Feature.strings, Module.get_features(wasm_mod));
1014

11-
// Translation of https://github.com/WebAssembly/binaryen/blob/version_107/src/passes/pass.cpp#L546-L566
15+
// Translation of https://github.com/WebAssembly/binaryen/blob/version_124/src/passes/pass.cpp#L738-L777
1216
let default_global_optimization_pre_passes =
1317
(~optimize_level, ~shrink_level, wasm_mod) => {
1418
List.concat([
15-
[Passes.duplicate_function_elimination, Passes.memory_packing],
19+
// Removing duplicate functions is fast and saves work later.
20+
[Passes.duplicate_function_elimination],
21+
// Do a global cleanup before anything heavy, as it is fairly fast and can
22+
// save a lot of work if there is a significant amount of dead code.
23+
if (optimize_level >= 2) {
24+
[Passes.remove_unused_module_elements];
25+
} else {
26+
[];
27+
},
28+
[Passes.memory_packing],
1629
if (optimize_level >= 2) {
1730
[Passes.once_reduction];
1831
} else {
1932
[];
2033
},
21-
if (has_gc(wasm_mod)
22-
&& /* TODO: getTypeSystem() == TypeSystem::Nominal && */ optimize_level
23-
>= 2) {
24-
[
25-
Passes.type_refining,
26-
Passes.signature_refining,
27-
Passes.global_refining,
28-
// Global type optimization can remove fields that are not needed, which can
29-
// remove ref.funcs that were once assigned to vtables but are no longer
30-
// needed, which can allow more code to be removed globally. After those,
31-
// constant field propagation can be more effective.
32-
Passes.gto,
33-
Passes.remove_unused_module_elements,
34-
Passes.cfp,
35-
];
34+
if (has_gc(wasm_mod) && optimize_level >= 2) {
35+
List.concat([
36+
if (Settings.get_closed_world()) {
37+
[
38+
Passes.type_refining,
39+
Passes.signature_pruning,
40+
Passes.signature_refining,
41+
];
42+
} else {
43+
[];
44+
},
45+
[Passes.global_refining],
46+
if (Settings.get_closed_world()) {
47+
[
48+
// Global type optimization can remove fields that are not needed, which can
49+
// remove ref.funcs that were once assigned to vtables but are no longer
50+
// needed, which can allow more code to be removed globally. After those,
51+
// constant field propagation can be more effective.
52+
Passes.gto,
53+
];
54+
} else {
55+
[];
56+
},
57+
[Passes.remove_unused_module_elements],
58+
if (Settings.get_closed_world()) {
59+
[
60+
Passes.remove_unused_types,
61+
Passes.cfp,
62+
Passes.gsi,
63+
Passes.abstract_type_refining,
64+
Passes.unsubtyping,
65+
];
66+
} else {
67+
[];
68+
},
69+
]);
3670
} else {
3771
[];
3872
},
3973
]);
4074
};
4175

42-
// Translation of https://github.com/WebAssembly/binaryen/blob/version_107/src/passes/pass.cpp#L447-L544
76+
// Translation of https://github.com/WebAssembly/binaryen/blob/version_124/src/passes/pass.cpp#L626-L736
4377
let default_function_optimization_passes =
4478
(~optimize_level, ~shrink_level, wasm_mod) => {
4579
List.concat([
@@ -64,7 +98,7 @@ let default_function_optimization_passes =
6498
// run some amount of simplify-locals first).
6599
Passes.simplify_locals_notee_nostructure,
66100
Passes.local_cse,
67-
// TODO: add rereloop etc. here
101+
// TODO(BINARYEN): add rereloop etc. here
68102
];
69103
} else {
70104
[];
@@ -76,6 +110,11 @@ let default_function_optimization_passes =
76110
Passes.remove_unused_names,
77111
Passes.optimize_instructions,
78112
],
113+
if (has_gc(wasm_mod)) {
114+
[Passes.heap_store_optimization];
115+
} else {
116+
[];
117+
},
79118
if (optimize_level >= 2 || shrink_level >= 2) {
80119
[Passes.pick_load_signs];
81120
} else {
@@ -101,9 +140,19 @@ let default_function_optimization_passes =
101140
} else {
102141
[];
103142
},
143+
if (has_multivalue(wasm_mod)) {
144+
[
145+
// Optimize tuples before local opts (as splitting tuples can help local
146+
// opts), but also not too early, as we want to be after
147+
// optimize-instructions at least (which can remove tuple-related things).
148+
Passes.tuple_optimization,
149+
];
150+
} else {
151+
[];
152+
},
153+
// don't create if/block return values yet, as coalesce can remove copies that
154+
// that could inhibit
104155
[
105-
// don't create if/block return values yet, as coalesce can remove copies that
106-
// that could inhibit
107156
Passes.simplify_locals_nostructure,
108157
Passes.vacuum, // previous pass creates garbage
109158
Passes.reorder_locals,
@@ -125,9 +174,10 @@ let default_function_optimization_passes =
125174
},
126175
if (optimize_level > 1 && has_gc(wasm_mod)) {
127176
[
177+
Passes.optimize_casts,
128178
// Coalescing may prevent subtyping (as a coalesced local must have the
129179
// supertype of all those combined into it), so subtype first.
130-
// TODO: when optimizing for size, maybe the order should reverse?
180+
// TODO(BINARYEN): when optimizing for size, maybe the order should reverse?
131181
Passes.local_subtyping,
132182
];
133183
} else {
@@ -165,6 +215,11 @@ let default_function_optimization_passes =
165215
[Passes.precompute];
166216
},
167217
[Passes.optimize_instructions],
218+
if (has_gc(wasm_mod)) {
219+
[Passes.heap_store_optimization];
220+
} else {
221+
[];
222+
},
168223
if (optimize_level >= 2 || shrink_level >= 1) {
169224
[
170225
Passes.rse // after all coalesce-locals, and before a final vacuum
@@ -176,7 +231,7 @@ let default_function_optimization_passes =
176231
]);
177232
};
178233

179-
// Translation of https://github.com/WebAssembly/binaryen/blob/version_107/src/passes/pass.cpp#L568-L599
234+
// Translation of https://github.com/WebAssembly/binaryen/blob/version_124/src/passes/pass.cpp#L788-L821
180235
let default_global_optimization_post_passes =
181236
(~optimize_level, ~shrink_level, wasm_mod) => {
182237
List.concat([
@@ -206,18 +261,23 @@ let default_global_optimization_post_passes =
206261
} else {
207262
[Passes.simplify_globals];
208263
},
209-
[
210-
Passes.remove_unused_module_elements,
211-
// may allow more inlining/dae/etc., need --converge for that
212-
Passes.directize,
213-
],
214-
// perform Stack IR optimizations here, at the very end of the
215-
// optimization pipeline
264+
[Passes.remove_unused_module_elements],
265+
if (optimize_level >= 2 && has_strings(wasm_mod)) {
266+
[
267+
// Gather strings to globals right before reorder-globals, which will then
268+
// sort them properly.
269+
Passes.string_gathering,
270+
];
271+
} else {
272+
[];
273+
},
216274
if (optimize_level >= 2 || shrink_level >= 1) {
217-
[Passes.generate_stack_ir, Passes.optimize_stack_ir];
275+
[Passes.reorder_globals];
218276
} else {
219277
[];
220278
},
279+
// may allow more inlining/dae/etc., need --converge for that
280+
[Passes.directize],
221281
]);
222282
};
223283

@@ -227,7 +287,7 @@ let optimize =
227287
~shrink_level=default_shrink_level,
228288
wasm_mod,
229289
) => {
230-
// Translation of https://github.com/WebAssembly/binaryen/blob/version_107/src/passes/pass.cpp#L441-L445
290+
// Translation of https://github.com/WebAssembly/binaryen/blob/version_124/src/passes/pass.cpp#L620-L624
231291
let default_optimizations_passes =
232292
List.concat([
233293
default_global_optimization_pre_passes(

compiler/test/suites/basic_functionality.re

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,6 @@ describe("basic functionality", ({test, testSkip}) => {
391391
~config_fn=smallestFileConfig,
392392
"smallest_grain_program",
393393
"",
394-
6059,
394+
3091,
395395
);
396396
});

0 commit comments

Comments
 (0)