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}