wasm_opt/passes.rs
1use crate::base::pass_registry;
2use strum_macros::EnumIter;
3
4/// A Binaryen optimization pass.
5///
6/// These have the same names as given on the command line to
7/// `wasm-opt`, but with Rust capitalization conventions.
8// Keep these in the same order as PassRegistry::registerPasses
9#[non_exhaustive]
10#[derive(Clone, Debug, EnumIter)]
11pub enum Pass {
12 /// Lower unaligned loads and stores to smaller aligned ones.
13 AlignmentLowering,
14 /// Async/await style transform, allowing pausing and resuming.
15 Asyncify,
16 /// Tries to avoid reinterpret operations via more loads.
17 AvoidReinterprets,
18 /// Removes arguments to calls in an lto-like manner.
19 Dae,
20 /// Removes arguments to calls in an lto-like manner, and optimizes where removed.
21 DaeOptimizing,
22 /// Refine and merge abstract (never-created) types.
23 AbstractTypeRefining,
24 /// Reduce # of locals by coalescing.
25 CoalesceLocals,
26 /// Reduce # of locals by coalescing and learning.
27 CoalesceLocalsLearning,
28 /// Push code forward, potentially making it not always execute.
29 CodePushing,
30 /// Fold code, merging duplicates.
31 CodeFolding,
32 /// Hoist repeated constants to a local.
33 ConstHoisting,
34 /// Propagate constant struct field values.
35 Cfp,
36 /// Removes unreachable code.
37 Dce,
38 /// Forces all loads and stores to have alignment 1.
39 Dealign,
40 /// Instrument the wasm to convert NaNs into 0 at runtime.
41 DeNan,
42 /// Turns indirect calls into direct ones.
43 Directize,
44 /// Discards global effect info.
45 DiscardGlobalEffects,
46 /// Optimizes using the DataFlow SSA IR.
47 Dfo,
48 /// Dump DWARF debug info sections from the read binary.
49 DwarfDump,
50 /// Removes duplicate imports.
51 DuplicateImportElimination,
52 /// Removes duplicate functions.
53 DuplicateFunctionElimination,
54 /// Emit the target features section in the output.
55 EmitTargetFeatures,
56 /// Leaves just one function (useful for debugging).
57 ExtractFunction,
58 /// Leaves just one function selected by index.
59 ExtractFunctionIndex,
60 /// Flattens out code, removing nesting.
61 Flatten,
62 /// Emulates function pointer casts, allowing incorrect indirect calls to (sometimes) work.
63 FpCastEmu,
64 /// Reports function metrics.
65 FuncMetrics,
66 /// Generate dynCall fuctions used by emscripten ABI.
67 GenerateDyncalls,
68 /// Generate dynCall functions used by emscripten ABI, but only for functions with i64 in their signature (which cannot be invoked via the wasm table without JavaScript BigInt support).
69 GenerateI64Dyncalls,
70 /// Generate global effect info (helps later passes).
71 GenerateGlobalEffects,
72 /// Generate Stack IR.
73 GenerateStackIr,
74 /// Refine the types of globals.
75 GlobalRefining,
76 /// Globally optimize GC types.
77 Gto,
78 /// Globally optimize struct values.
79 Gsi,
80 /// Grand unified flow analyses.
81 ///
82 /// Optimize the entire program using information about what content can actually appear in each location.
83 Gufa,
84 /// GUFA plus add casts for all inferences.
85 GufaCastAll,
86 /// Gufa plus local optimizations in functions we modified.
87 GufaOptimizing,
88 /// Apply more specific subtypes to type fields where possible.
89 TypeRefining,
90 /// Replace GC allocations with locals.
91 Heap2Local,
92 /// Inline __original_main into main.
93 InlineMain,
94 /// Inline functions (you probably want inlining-optimizing).
95 Inlining,
96 /// Inline functions and optimizes where we inlined.
97 InliningOptimizing,
98 /// Lower away binaryen intrinsics.
99 IntrinsicLowering,
100 /// Wrap imports and exports for JavaScript promise integration.
101 Jspi,
102 /// Legalizes i64 types on the import/export boundary.
103 LegalizeJsInterface,
104 /// Legalizes i64 types on the import/export boundary in a minimal manner, only on things only JS will call.
105 LegalizeJsInterfaceMinimally,
106 /// Common subexpression elimination inside basic blocks.
107 LocalCse,
108 /// Apply more specific subtypes to locals where possible.
109 LocalSubtyping,
110 /// Instrument the build with logging of where execution goes.
111 LogExecution,
112 /// Lower all uses of i64s to use i32s instead.
113 I64ToI32Lowering,
114 /// Instrument the build with code to intercept all loads and stores.
115 InstrumentLocals,
116 /// Instrument the build with code to intercept all loads and stores.
117 InstrumentMemory,
118 /// Loop invariant code motion.
119 Licm,
120 /// Attempt to merge segments to fit within web limits.
121 LimitSegments,
122 /// Lower loads and stores to a 64-bit memory to instead use a 32-bit one.
123 Memory64Lowering,
124 /// Packs memory into separate segments, skipping zeros.
125 MemoryPacking,
126 /// Merges blocks to their parents.
127 MergeBlocks,
128 /// Merges similar functions when benefical.
129 MergeSimilarFunctions,
130 /// Merges locals when beneficial.
131 MergeLocals,
132 /// Reports metrics.
133 Metrics,
134 /// Minifies import names (only those, and not export names), and emits a mapping to the minified ones.
135 MinifyImports,
136 /// Minifies both import and export names, and emits a mapping to the minified ones.
137 MinifyImportsAndExports,
138 /// Minifies both import and export names, and emits a mapping to the minified ones, and minifies the modules as well.
139 MinifyImportsAndExportsAndModules,
140 /// Apply the assumption that asyncify imports always unwind, and we never rewind.
141 ModAsyncifyAlwaysAndOnlyUnwind,
142 /// Apply the assumption that asyncify never unwinds.
143 ModAsyncifyNeverUnwind,
144 /// Creates specialized versions of functions.
145 Monomorphize,
146 /// Creates specialized versions of functions (even if unhelpful).
147 MonomorphizeAlways,
148 /// Combines multiple memories into a single memory.
149 MultiMemoryLowering,
150 /// Combines multiple memories into a single memory, trapping if the read or write is larger than the length of the memory's data.
151 MultiMemoryLoweringWithBoundsChecks,
152 /// Name list.
153 Nm,
154 /// (Re)name all heap types.
155 NameTypes,
156 /// Reduces calls to code that only runs once.
157 OnceReduction,
158 /// Optimizes added constants into load/store offsets.
159 OptimizeAddedConstants,
160 /// Optimizes added constants into load/store offsets, propagating them across locals too.
161 OptimizeAddedConstantsPropagate,
162 /// Eliminate and reuse casts.
163 OptimizeCasts,
164 /// Optimizes instruction combinations.
165 OptimizeInstructions,
166 /// Optimize Stack IR.
167 OptimizeStackIr,
168 /// Pick load signs based on their uses.
169 PickLoadSigns,
170 /// Tranform Binaryen IR into Poppy IR.
171 Poppify,
172 /// Miscellaneous optimizations for Emscripten-generated code.
173 PostEmscripten,
174 /// Early optimize of the instruction combinations for js.
175 OptimizeForJs,
176 /// Computes compile-time evaluatable expressions.
177 Precompute,
178 /// Computes compile-time evaluatable expressions and propagates.
179 PrecomputePropagate,
180 /// Print in s-expression format.
181 Print,
182 /// Print in minified s-expression format.
183 PrintMinified,
184 /// Print options for enabled features.
185 PrintFeatures,
186 /// Print in full s-expression format.
187 PrintFull,
188 /// Print call graph.
189 PrintCallGraph,
190 /// Print a map of function indexes to names.
191 PrintFunctionMap,
192 /// (Alias for print-function-map).
193 Symbolmap,
194 /// Print out Stack IR (useful for internal debugging).
195 PrintStackIr,
196 /// Removes operations incompatible with js.
197 RemoveNonJsOps,
198 /// Removes imports and replaces them with nops.
199 RemoveImports,
200 /// Removes memory segments.
201 RemoveMemory,
202 /// Removes breaks from locations that are not needed.
203 RemoveUnusedBrs,
204 /// Removes unused module elements.
205 RemoveUnusedModuleElements,
206 /// Removes unused module elements that are not functions.
207 RemoveUnusedNonfunctionModuleElements,
208 /// Removes names from locations that are never branched to.
209 RemoveUnusedNames,
210 /// Remove unused private GC types.
211 RemoveUnusedTypes,
212 /// Sorts functions by name (useful for debugging).
213 ReorderFunctionsByName,
214 /// Sorts functions by access frequency.
215 ReorderFunctions,
216 /// Sorts globals by access frequency.
217 ReorderGlobals,
218 /// Sorts locals by access frequency.
219 RecorderLocals,
220 /// Re-optimize control flow using the relooper algorithm.
221 Rereloop,
222 /// Remove redundant local.sets.
223 Rse,
224 /// Write the module to binary, then read it.
225 Roundtrip,
226 /// Instrument loads and stores to check for invalid behavior.
227 SafeHeap,
228 /// Sets specified globals to specified values.
229 SetGlobals,
230 /// Remove params from function signature types where possible.
231 SignaturePruning,
232 /// Apply more specific subtypes to signature types where possible.
233 SignatureRefining,
234 /// Lower sign-ext operations to wasm mvp.
235 SignextLowering,
236 /// Miscellaneous globals-related optimizations.
237 SimplifyGlobals,
238 /// Miscellaneous globals-related optimizations, and optimizes where we replaced global.gets with constants.
239 SimplifyGlobalsOptimizing,
240 /// Miscellaneous locals-related optimizations.
241 SimplifyLocals,
242 /// Miscellaneous locals-related optimizations (no nesting at all; preserves flatness).
243 SimplifyLocalsNonesting,
244 /// Miscellaneous locals-related optimizations (no tees).
245 SimplifyLocalsNotee,
246 /// Miscellaneous locals-related optimizations (no structure).
247 SimplifyLocalsNostructure,
248 /// Miscellaneous locals-related optimizations (no tees or structure).
249 SimplifyLocalsNoteeNostructure,
250 /// Emit Souper IR in text form.
251 Souperify,
252 /// Emit Souper IR in text form (single-use nodes only).
253 SouperifySingleUse,
254 /// Spill pointers to the C stack (useful for Boehm-style GC).
255 SpillPointers,
256 /// Stub out unsupported JS operations.
257 StubUnsupportedJs,
258 /// Ssa-ify variables so that they have a single assignment.
259 Ssa,
260 /// Ssa-ify variables so that they have a single assignment, ignoring merges.
261 SsaNomerge,
262 /// Deprecated; same as strip-debug.
263 Strip,
264 /// Enforce limits on llvm's __stack_pointer global.
265 StackCheck,
266 /// Strip debug info (including the names section).
267 StripDebug,
268 /// Strip dwarf debug info.
269 StripDwarf,
270 /// Strip the wasm producers section.
271 StripProducers,
272 /// Strip EH instructions.
273 StripEh,
274 /// Strip the wasm target features section.
275 StripTargetFeatuers,
276 /// Replace trapping operations with clamping semantics.
277 TrapModeClamp,
278 /// Replace trapping operations with js semantics.
279 TrapModeJs,
280 /// Merge types to their supertypes where possible.
281 TypeMerging,
282 /// Create new nominal types to help other optimizations.
283 TypeSsa,
284 /// Removes local.tees, replacing them with sets and gets.
285 Untee,
286 /// Removes obviously unneeded code.
287 Vacuum,
288}
289
290impl Pass {
291 /// Returns the name of the pass.
292 ///
293 /// This is the same name used by Binaryen to identify the pass on the command line.
294 pub fn name(&self) -> &'static str {
295 use Pass::*;
296 match self {
297 AlignmentLowering => "alignment-lowering",
298 Asyncify => "asyncify",
299 AvoidReinterprets => "avoid-reinterprets",
300 Dae => "dae",
301 DaeOptimizing => "dae-optimizing",
302 AbstractTypeRefining => "abstract-type-refining",
303 CoalesceLocals => "coalesce-locals",
304 CoalesceLocalsLearning => "coalesce-locals-learning",
305 CodePushing => "code-pushing",
306 CodeFolding => "code-folding",
307 ConstHoisting => "const-hoisting",
308 Cfp => "cfp",
309 Dce => "dce",
310 Dealign => "dealign",
311 DeNan => "denan",
312 DiscardGlobalEffects => "discard-global-effects",
313 Directize => "directize",
314 Dfo => "dfo",
315 DwarfDump => "dwarfdump",
316 DuplicateImportElimination => "duplicate-import-elimination",
317 DuplicateFunctionElimination => "duplicate-function-elimination",
318 EmitTargetFeatures => "emit-target-features",
319 ExtractFunction => "extract-function",
320 ExtractFunctionIndex => "extract-function-index",
321 Flatten => "flatten",
322 FpCastEmu => "fpcast-emu",
323 FuncMetrics => "func-metrics",
324 GenerateDyncalls => "generate-dyncalls",
325 GenerateI64Dyncalls => "generate-i64-dyncalls",
326 GenerateGlobalEffects => "generate-global-effects",
327 GenerateStackIr => "generate-stack-ir",
328 GlobalRefining => "global-refining",
329 Gto => "gto",
330 Gsi => "gsi",
331 Gufa => "gufa",
332 GufaCastAll => "gufa-cast-all",
333 GufaOptimizing => "gufa-optimizing",
334 TypeRefining => "type-refining",
335 Heap2Local => "heap2local",
336 InlineMain => "inline-main",
337 Inlining => "inlining",
338 InliningOptimizing => "inlining-optimizing",
339 IntrinsicLowering => "intrinsic-lowering",
340 Jspi => "jspi",
341 LegalizeJsInterface => "legalize-js-interface",
342 LegalizeJsInterfaceMinimally => "legalize-js-interface-minimally",
343 LocalCse => "local-cse",
344 LocalSubtyping => "local-subtyping",
345 LogExecution => "log-execution",
346 I64ToI32Lowering => "i64-to-i32-lowering",
347 InstrumentLocals => "instrument-locals",
348 InstrumentMemory => "instrument-memory",
349 Licm => "licm",
350 LimitSegments => "limit-segments",
351 Memory64Lowering => "memory64-lowering",
352 MemoryPacking => "memory-packing",
353 MergeBlocks => "merge-blocks",
354 MergeSimilarFunctions => "merge-similar-functions",
355 MergeLocals => "merge-locals",
356 Metrics => "metrics",
357 MinifyImports => "minify-imports",
358 MinifyImportsAndExports => "minify-imports-and-exports",
359 MinifyImportsAndExportsAndModules => "minify-imports-and-exports-and-modules",
360 ModAsyncifyAlwaysAndOnlyUnwind => "mod-asyncify-always-and-only-unwind",
361 ModAsyncifyNeverUnwind => "mod-asyncify-never-unwind",
362 Monomorphize => "monomorphize",
363 MonomorphizeAlways => "monomorphize-always",
364 MultiMemoryLowering => "multi-memory-lowering",
365 MultiMemoryLoweringWithBoundsChecks => "multi-memory-lowering-with-bounds-checks",
366 Nm => "nm",
367 NameTypes => "name-types",
368 OnceReduction => "once-reduction",
369 OptimizeAddedConstants => "optimize-added-constants",
370 OptimizeAddedConstantsPropagate => "optimize-added-constants-propagate",
371 OptimizeCasts => "optimize-casts",
372 OptimizeInstructions => "optimize-instructions",
373 OptimizeStackIr => "optimize-stack-ir",
374 PickLoadSigns => "pick-load-signs",
375 Poppify => "poppify",
376 PostEmscripten => "post-emscripten",
377 OptimizeForJs => "optimize-for-js",
378 Precompute => "precompute",
379 PrecomputePropagate => "precompute-propagate",
380 Print => "print",
381 PrintMinified => "print-minified",
382 PrintFeatures => "print-features",
383 PrintFull => "print-full",
384 PrintCallGraph => "print-call-graph",
385 PrintFunctionMap => "print-function-map",
386 Symbolmap => "symbolmap",
387 PrintStackIr => "print-stack-ir",
388 RemoveNonJsOps => "remove-non-js-ops",
389 RemoveImports => "remove-imports",
390 RemoveMemory => "remove-memory",
391 RemoveUnusedBrs => "remove-unused-brs",
392 RemoveUnusedModuleElements => "remove-unused-module-elements",
393 RemoveUnusedNonfunctionModuleElements => "remove-unused-nonfunction-module-elements",
394 RemoveUnusedNames => "remove-unused-names",
395 RemoveUnusedTypes => "remove-unused-types",
396 ReorderFunctionsByName => "reorder-functions-by-name",
397 ReorderFunctions => "reorder-functions",
398 ReorderGlobals => "reorder-globals",
399 RecorderLocals => "reorder-locals",
400 Rereloop => "rereloop",
401 Rse => "rse",
402 Roundtrip => "roundtrip",
403 SafeHeap => "safe-heap",
404 SetGlobals => "set-globals",
405 SignaturePruning => "signature-pruning",
406 SignatureRefining => "signature-refining",
407 SignextLowering => "signext-lowering",
408 SimplifyGlobals => "simplify-globals",
409 SimplifyGlobalsOptimizing => "simplify-globals-optimizing",
410 SimplifyLocals => "simplify-locals",
411 SimplifyLocalsNonesting => "simplify-locals-nonesting",
412 SimplifyLocalsNotee => "simplify-locals-notee",
413 SimplifyLocalsNostructure => "simplify-locals-nostructure",
414 SimplifyLocalsNoteeNostructure => "simplify-locals-notee-nostructure",
415 Souperify => "souperify",
416 SouperifySingleUse => "souperify-single-use",
417 SpillPointers => "spill-pointers",
418 StubUnsupportedJs => "stub-unsupported-js",
419 Ssa => "ssa",
420 SsaNomerge => "ssa-nomerge",
421 Strip => "strip",
422 StackCheck => "stack-check",
423 StripDebug => "strip-debug",
424 StripDwarf => "strip-dwarf",
425 StripProducers => "strip-producers",
426 StripEh => "strip-eh",
427 StripTargetFeatuers => "strip-target-features",
428 TrapModeClamp => "trap-mode-clamp",
429 TrapModeJs => "trap-mode-js",
430 TypeMerging => "type-merging",
431 TypeSsa => "type-ssa",
432 Untee => "untee",
433 Vacuum => "vacuum",
434 }
435 }
436
437 /// Get Binaryen's description of the pass.
438 pub fn description(&self) -> String {
439 // NB: This will abort if the name is invalid
440 pass_registry::get_pass_description(self.name())
441 }
442}