watr 4.5.3 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -67,11 +67,6 @@ export function strength(ast: any[]): any[];
67
67
  * @returns {Array}
68
68
  */
69
69
  export function branch(ast: any[]): any[];
70
- /**
71
- * Propagate values through locals and eliminate single-use/dead locals.
72
- * Constants propagate to all uses; pure single-use exprs inline into get site.
73
- * Multi-pass with batch counting for convergence.
74
- */
75
70
  export function propagate(ast: any): any;
76
71
  /**
77
72
  * Inline tiny functions (single expression, no locals, no params or simple params).
@@ -79,6 +74,36 @@ export function propagate(ast: any): any;
79
74
  * @returns {Array}
80
75
  */
81
76
  export function inline(ast: any[]): any[];
77
+ /**
78
+ * Inline functions that are called from exactly one place into their lone caller,
79
+ * then delete them. Unlike {@link inline} (which duplicates tiny stateless bodies),
80
+ * this never duplicates code and never inflates: each inlined function drops a
81
+ * function-section entry, a type-section entry (if now unused), and a `call`
82
+ * instruction, paying back only a `block`/`local.set` wrapper. This is what
83
+ * `wasm-opt -Oz` does — collapsing helper chains down to a couple of functions —
84
+ * and it's the bulk of the gap between hand-tuned WASM and naive codegen.
85
+ *
86
+ * A function `$f` qualifies when it is, all of:
87
+ * • named, with named params and locals (numeric indices can't be safely renamed);
88
+ * • referenced exactly once across the whole module, by a plain `call` (no
89
+ * `return_call`, `ref.func`, `elem`, `export`, or `start` reference, and not
90
+ * recursive);
91
+ * • single-result or void (a multi-value result can't be modeled as `(block (result …))`);
92
+ * • free of numeric (depth-relative) branch labels — those would shift under the
93
+ * extra block nesting — and of `return_call*` in its body.
94
+ *
95
+ * `(call $f a0 a1 …)` becomes
96
+ * (block $__inlN (result T)?
97
+ * (local.set $__inlN_p0 a0) (local.set $__inlN_p1 a1) … ;; args evaluated once, in order
98
+ * …body, params/locals renamed to $__inlN_*, `return X` → `br $__inlN X`…)
99
+ * and the renamed params+locals are appended to the caller's `local` decls; the
100
+ * body's own block/loop/if labels are renamed too so they can't shadow the caller's.
101
+ * Runs to a fixpoint so helper chains fully collapse.
102
+ *
103
+ * @param {Array} ast
104
+ * @returns {Array}
105
+ */
106
+ export function inlineOnce(ast: any[]): any[];
82
107
  /**
83
108
  * Normalize options to { opt: bool } map.
84
109
  * @param {boolean|string|Object} opts
@@ -95,7 +120,10 @@ export namespace OPTS {
95
120
  let branch: boolean;
96
121
  let propagate: boolean;
97
122
  let inline: boolean;
123
+ let inlineOnce: boolean;
98
124
  let vacuum: boolean;
125
+ let mergeBlocks: boolean;
126
+ let coalesce: boolean;
99
127
  let peephole: boolean;
100
128
  let globals: boolean;
101
129
  let offset: boolean;
@@ -123,7 +151,14 @@ export function vacuum(ast: any[]): any[];
123
151
  */
124
152
  export function peephole(ast: any[]): any[];
125
153
  /**
126
- * Replace global.get of immutable globals with their constant init values.
154
+ * Replace `global.get` of an immutable, const-initialised global with the
155
+ * constant — but only when it doesn't grow the module. A `global.get` costs
156
+ * ~2 B; an `i32.const 12345` costs 4 B; an `f64.const` costs 9 B. Naively
157
+ * inlining a big constant read from many sites trades a few cheap reads + one
158
+ * global decl for many fat immediates — pure bloat (and the node-count size
159
+ * guard can't see it: same number of AST nodes). So we only propagate a global
160
+ * when `refs·constSize ≤ refs·2 + declSize`; when every read is replaced and
161
+ * the global isn't exported, its now-dead decl is dropped here too.
127
162
  * @param {Array} ast
128
163
  * @returns {Array}
129
164
  */
@@ -186,5 +221,32 @@ export function packData(ast: any[]): any[];
186
221
  * @returns {Array}
187
222
  */
188
223
  export function minifyImports(ast: any[]): any[];
224
+ /**
225
+ * Unwrap redundant `(block $L body)` whose label is never targeted, splicing
226
+ * the body into the surrounding scope. Skips blocks with `param`/`result`/`type`
227
+ * annotations (their stack effect would change). Each unwrap drops the
228
+ * `block`+`end` framing bytes; iterates by walk so chained blocks collapse.
229
+ * @param {Array} ast
230
+ * @returns {Array}
231
+ */
232
+ export function mergeBlocks(ast: any[]): any[];
233
+ /**
234
+ * Share local slots between same-type locals with non-overlapping live ranges.
235
+ * Live range = [first pos, last pos] of any local.get/set/tee, extended over
236
+ * any loop containing a reference (so a value read across loop iterations stays
237
+ * intact). Greedy slot assignment by start position. Params and unnamed/numeric
238
+ * references are left alone; `localReuse` later removes the renamed-away decls.
239
+ *
240
+ * Soundness: WASM zero-initializes locals at function entry, so a local whose
241
+ * first reference (in walk order) is a `local.get` *relies* on that implicit
242
+ * zero — coalescing it into a slot whose previous user left a non-zero residue
243
+ * would silently change behavior (e.g. a `for (let i=0; …)` loop counter
244
+ * inheriting `N*4` from a sibling temp). Such "read-first" locals can still
245
+ * serve as a slot's *primary* (the slot then keeps the function's zero start),
246
+ * but can never be a donor merged into an existing slot.
247
+ * @param {Array} ast
248
+ * @returns {Array}
249
+ */
250
+ export function coalesceLocals(ast: any[]): any[];
189
251
  export { count as size };
190
252
  //# sourceMappingURL=optimize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"optimize.d.ts","sourceRoot":"","sources":["../../src/optimize.js"],"names":[],"mappings":"AAuhEA;;;;;;;;;;;GAWG;AACH,sCATW,QAAM,MAAM,SACZ,OAAO,GAAC,MAAM,MAAO,SAkE/B;AArjED;;;;GAIG;AACH,4BAHW,GAAG,GACD,MAAM,CAOlB;AAED;;;;GAIG;AACH,wCAFa,MAAM,CAIlB;AAwGD;;;;;GAKG;AACH,6CAgJC;AA6ID;;;;GAIG;AACH,wCAwBC;AAoMD;;;;GAIG;AACH,4CAqBC;AA+CD;;;;;GAKG;AACH,8CAmDC;AA7QD;;;;GAIG;AACH,4CASC;AAID;;;;GAIG;AACH,4CA6DC;AAID;;;;GAIG;AACH,0CAuCC;AA6VD;;;;GAIG;AACH,yCAsBC;AAID;;;;GAIG;AACH,0CAiGC;AAvjCD;;;;GAIG;AACH,gCAHW,OAAO,GAAC,MAAM,MAAO,OAa/B;;;;;;;;;;;;;;;;;;;;;;;;;AA4iCD;;;;;GAKG;AACH,0CAgDC;AAyED;;;;GAIG;AACH,4CAQC;AAID;;;;GAIG;AACH,2CAyCC;AAID,2EAA2E;AAC3E,sCAgEC;AAID;;;;GAIG;AACH,4CAuCC;AAID;;;;;GAKG;AACH,4CAqBC;AAID;;;;;;GAMG;AACH,wCAmBC;AAID;;;;;GAKG;AACH,4CAiDC;AAoCD;;;;;GAKG;AACH,0CA8DC;AAiWD,uCAyBC;AAtXD;;;;;GAKG;AACH,8CAyEC;AAoID;;;;GAIG;AACH,4CAyDC;AAqBD;;;;;GAKG;AACH,iDAgBC"}
1
+ {"version":3,"file":"optimize.d.ts","sourceRoot":"","sources":["../../src/optimize.js"],"names":[],"mappings":"AAs+EA;;;;;;;;;;;GAWG;AACH,sCATW,QAAM,MAAM,SACZ,OAAO,GAAC,MAAM,MAAO,SAiF/B;AAhhFD;;;;GAIG;AACH,4BAHW,GAAG,GACD,MAAM,CAOlB;AAED;;;;GAIG;AACH,wCAFa,MAAM,CAIlB;AAwGD;;;;;GAKG;AACH,6CAgJC;AA6ID;;;;GAIG;AACH,wCAwBC;AAoMD;;;;GAIG;AACH,4CAqBC;AA+CD;;;;;GAKG;AACH,8CAmDC;AA7QD;;;;GAIG;AACH,4CASC;AAID;;;;GAIG;AACH,4CA6DC;AAID;;;;GAIG;AACH,0CAuCC;AAgYD,yCAoCC;AAID;;;;GAIG;AACH,0CAiGC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,8CAgKC;AAtyCD;;;;GAIG;AACH,gCAHW,OAAO,GAAC,MAAM,MAAO,OAa/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAu8CD;;;;;GAKG;AACH,0CAgDC;AAyED;;;;GAIG;AACH,4CAQC;AA4BD;;;;;;;;;;;GAWG;AACH,2CAyDC;AAID,2EAA2E;AAC3E,sCAgEC;AAID;;;;GAIG;AACH,4CAyCC;AAID;;;;;GAKG;AACH,4CAqBC;AAID;;;;;;GAMG;AACH,wCAmBC;AAID;;;;;GAKG;AACH,4CAiDC;AAoCD;;;;;GAKG;AACH,0CA8DC;AAiWD,uCAyBC;AAtXD;;;;;GAKG;AACH,8CAyEC;AAoID;;;;GAIG;AACH,4CAyDC;AAqBD;;;;;GAKG;AACH,iDAgBC;AAphCD;;;;;;;GAOG;AACH,+CAsBC;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,kDAyFC"}