WASM-OPT(1)
๐ธ NAME ๐ธ
okay so bestie, welcome to wasm-opt ๐ it's a User Commands manual page and its whole entire job is: read, write, and optimize files. that's it, that's the vibe. ๐ฆ
โจ DESCRIPTION โจ
================================================================================
wasm-opt INFILE
Read, write, and optimize files. ๐
Example usage:
wasm-opt input.wasm -O3 -o output.wasm
so basically: it reads an input wasm file, optimizes with -O3, and writes out the result. iconic. no notes. ๐
For more on how to optimize effectively, see
https://github.com/WebAssembly/binaryen/wiki/Optimizer-Cookbook
https://github.com/WebAssembly/binaryen/wiki/GC-Optimization-Guidebook
================================================================================
๐ wasm-opt options ๐
like, the main-character flags, fr fr:
--output,-oโ Output file. where the lil guy goes when it's done ๐ซถ--emit-text,-Sโ Emit text instead of binary for the output file. so you can read it with your eyeballs ๐--converge,-cโ Run passes to convergence, continuing while binary size decreases. it just keeps going while the numbers go down, obsessed ๐--fuzz-exec-before,-fehโ Execute functions before optimization, helping fuzzing find bugs. shake it around first and see what falls out ๐--fuzz-exec,-feโ Execute functions before and after optimization, helping fuzzing find bugs. before and after, we love a comparison moment โจ--fuzz-exec-secondโ A second module to link with the first, for--fuzz-exec-before(only before, as optimizations are not applied to it). a little plus-one module ๐ง--extra-fuzz-command,-efcโ An extra command to run on the output before and after optimizing. The output is compared between the two, and an error occurs if they are not equal. if they don't match bestie, it's a whole thing ๐--translate-to-fuzz,-ttfโ Translate the input into a valid wasm module *somehow*, useful for fuzzing. yes "somehow" is the official energy here ๐--initial-fuzz,-ifโ Initial wasm content in--translate-to-fuzz(-ttf) mode.--fuzz-passes,-fpโ When doing--translate-to-fuzz, pick a set of random passes from the input to further shape the wasm. chaos but make it structured ๐ช๏ธ--no-fuzz-memoryโ don't emit memory ops when fuzzing.--no-fuzz-oobโ don't emit out-of-bounds loads/stores/indirect calls when fuzzing.--fuzz-preserve-imports-exportsโ don't add imports and exports in-ttfmode, and keep the start. do not perceive them, do not add them ๐ซ--fuzz-against-jsโ modify the wasm in valid ways that assume it is used only from JS.--fuzz-importโ a module to use as an import in-ttfmode.--emit-spec-wrapper,-eswโ Emit a wasm spec interpreter wrapper file that can run the wasm with some test values, useful for fuzzing.--emit-wasm2c-wrapper,-eswโ Emit a C wrapper file that can run the wasm after it is compiled withwasm2c, useful for fuzzing. (yes bestie it's the same-eswshort flag as the one above, that's literally what the page says, i do not make the rules ๐ )--input-source-map,-ismโ Consume source map from the specified file.--output-source-map,-osmโ Emit source map to the specified file.--output-source-map-url,-osuโ Emit specified string as source map URL.--experimental-new-ehโ Deprecated; same as--emit-exnref. it's giving "we're literally so over this one" ๐ญ--emit-exnrefโ After running all requested transformations / optimizations, translate the instruction to use the new EH instructions at the end. Depending on the optimization level specified, this may do some more post-translation optimizations. a lil afterparty pass ๐
๐ฅ Optimization passes ๐ฅ
the pass list. it's long. it's giving encyclopedia. we're doing all of them, no skips, periodt. ๐
--abstract-type-refiningโ refine and merge abstract (never-created) types--alignment-loweringโ lower unaligned loads and stores to smaller aligned ones--asyncifyโ async/await style transform, allowing pausing and resuming โธ๏ธโถ๏ธ--avoid-reinterpretsโ Tries to avoid reinterpret operations via more loads--cfpโ propagate constant struct field values--cfp-reftestโ propagate constant struct field values, usingref.test--coalesce-localsโ reduce # of locals by coalescing--coalesce-locals-learningโ reduce # of locals by coalescing and learning--code-foldingโ fold code, merging duplicates--code-pushingโ push code forward, potentially making it not always execute--const-hoistingโ hoist repeated constants to a local--constraint-analysisโ finds and uses mathematical constraints on locals--daeโ removes arguments to calls in an lto-like manner--dae-optimizingโ removes arguments to calls in an lto-like manner, and optimizes where we removed--dae2โ Experimental reimplementation of DAE--dceโ removes unreachable code ๐๏ธ--dealignโ forces all loads and stores to have alignment 1--denanโ instrument the wasm to convert NaNs into 0 at runtime--dfoโ optimizes using the DataFlow SSA IR--directizeโ turns indirect calls into direct ones--discard-global-effectsโ discards global effect info--duplicate-function-eliminationโ removes duplicate functions--duplicate-import-eliminationโ removes duplicate imports--dwarfdumpโ dump DWARF debug info sections from the read binary--emit-target-featuresโ emit the target features section in the output--enclose-worldโ modify the wasm (destructively) for closed-world โ ๏ธ yes bestie it says destructively, read it again--extract-functionโ leaves just one function (useful for debugging)--extract-function-indexโ leaves just one function selected by index--flattenโ flattens out code, removing nesting--fpcast-emuโ emulates function pointer casts, allowing incorrect indirect calls to (sometimes) work ๐--func-metricsโ reports function metrics--generate-dyncallsโ generate dynCall functions used by emscripten ABI--generate-global-effectsโ generate global effect info (helps later passes)--generate-i64-dyncallsโ generate dynCall functions used by emscripten ABI, but only for functions withi64in their signature (which cannot be invoked via the wasm table without JavaScript BigInt support).--global-refiningโ refine the types of globals--gsiโ globally optimize struct values--gsi-desc-castโ globally optimize struct values, also emittingref.cast_desc_eq--gtoโ globally optimize GC types--gufaโ Grand Unified Flow Analysis: optimize the entire program using information about what content can actually appear in each location--gufa-cast-allโ GUFA plus add casts for all inferences--gufa-optimizingโ GUFA plus local optimizations in functions we modified--heap-store-optimizationโ optimize heap (GC) stores--heap2localโ replace GC allocations with locals--i64-to-i32-loweringโ lower all uses ofi64s to usei32s instead--inline-mainโ inline__original_mainintomain--inliningโ inline functions (you probably want--inlining-optimizing)--inlining-optimizingโ inline functions and optimizes where we inlined--instrument-branch-hintsโ instrument branch hints so we can see which guessed right ๐ฎ--instrument-localsโ instrument the build with code to intercept all loads and stores--instrument-memoryโ instrument the build with code to intercept all loads and stores--intrinsic-loweringโ lower away binaryen intrinsics--legalize-and-prune-js-interfaceโ legalizes the import/export boundary and prunes when needed--legalize-js-interfaceโ legalizesi64types on the import/export boundary--licmโ loop invariant code motion--limit-segmentsโ attempt to merge segments to fit within web limits--llvm-memory-copy-fill-loweringโ Lowermemory.copyandmemory.fillto wasm mvp and disable the bulk-memory feature.--llvm-nontrapping-fptoint-loweringโ lower nontrapping float-to-int operations to wasm mvp and disable the nontrapping fptoint feature--local-cseโ common subexpression elimination inside basic blocks--local-subtypingโ apply more specific subtypes to locals where possible--log-executionโ instrument the build with logging of where execution goes--mark-js-calledโ mark js called functions (usingconfigureAll) as doing so--memory-packingโ packs memory into separate segments, skipping zeros--memory64-loweringโ lower loads and stores to a 64-bit memory to instead use a 32-bit one--merge-blocksโ merges blocks to their parents--merge-j2cl-itablesโ Merges itable structures into vtables to make types more compact--merge-localsโ merges locals when beneficial--merge-similar-functionsโ merges similar functions when benefical (yes, spelled like that in the original, i'm just the messenger ๐)--metricsโ reports metrics (with an optional title,--metrics[=TITLE])--minify-importsโ minifies import names (only those, and not export names), and emits a mapping to the minified ones--minify-imports-and-exportsโ minifies both import and export names, and emits a mapping to the minified ones--minify-imports-and-exports-and-modulesโ minifies both import and export names, and emits a mapping to the minified ones, and minifies the modules as well--minimize-rec-groupsโ Split types into minimal recursion groups--monomorphizeโ creates specialized versions of functions--monomorphize-alwaysโ creates specialized versions of functions (even if unhelpful) ๐--multi-memory-loweringโ combines multiple memories into a single memory--multi-memory-lowering-with-bounds-checksโ combines multiple memories into a single memory, trapping if the read or write is larger than the length of the memory's data--name-typesโ (re)name all heap types--nmโ name list--no-full-inlineโ mark functions as no-inline (for full inlining only)--no-inlineโ mark functions as no-inline--no-partial-inlineโ mark functions as no-inline (for partial inlining only)--once-reductionโ reduces calls to code that only runs once--optimize-added-constantsโ optimizes added constants into load/store offsets--optimize-added-constants-propagateโ optimizes added constants into load/store offsets, propagating them across locals too--optimize-castsโ eliminate and reuse casts--optimize-for-jsโ early optimize of the instruction combinations for js--optimize-instructionsโ optimizes instruction combinations--optimize-j2clโ optimizes J2CL specific constructs.--outliningโ outline instructions--pick-load-signsโ pick load signs based on their uses--poppifyโ Transform Binaryen IR into Poppy IR--post-emscriptenโ all the lil miscellaneous glow-ups for code that Emscripten made ๐--precomputeโ crunches expressions that can be figured out at compile time, so they're just... already done โจ--precompute-propagateโ same energy as--precompute, except it also pushes those computed values through your locals, no cap ๐ซถ--printโ prints everything in s-expression format ๐ธ--print-boundaryโ prints the boundary in JSON format, iconic ๐--print-call-graphโ prints the call graph, so you can see who's calling whom (drama map fr) ๐--print-featuresโ prints the options for the features you've got enabled, so you know exactly what you're working with โจ--print-fullโ prints in the full s-expression format, extra detailed bestie ๐--print-function-mapโ prints a map of function indexes to names, iykyk ๐บ๏ธ--print-minifiedโ prints in minified s-expression format, compact queen ๐--propagate-debug-locsโ carries debug locations down from parents or previous siblings onto their child nodes ๐ง--propagate-globals-globallyโ propagates global values into other globals (handy for tests) ๐--remove-exportsโ yeets exports using a wildcard ๐ญ--remove-importsโ takes imports out and swaps them for nops, gone but not forgotten ๐--remove-memoryโ removes memory init (this is the legacy name, so it's giving vintage) ๐--remove-memory-initโ removes memory initialization โจ--remove-non-js-opsโ strips out operations that js can't vibe with ๐ซ--remove-relaxed-simdโ swaps relaxed SIMD instructions out forunreachable๐ธ--remove-unused-brsโ removes breaks that are sitting at locations where they're just not needed ๐--remove-unused-module-elementsโ removes module elements nobody's using, decluttering era ๐งน--remove-unused-namesโ removes names from locations that are never branched to โจ--remove-unused-nonfunction-module-elementsโ removes unused module elements that aren't functions (yes, specifically the non-function ones) ๐--remove-unused-typesโ removes unused private GC types ๐ซถ--reorder-functionsโ sorts functions by access frequency, hottest first ๐ฅ--reorder-functions-by-nameโ sorts functions by name (this one's for debugging, so cute) ๐--reorder-globalsโ sorts globals by access frequency ๐ฅ--reorder-localsโ sorts locals by access frequency ๐ฅ--reorder-typesโ sorts private types by access frequency ๐ฅ--rereloopโ re-optimizes control flow using the relooper algorithm, we love a rerun ๐--roundtripโ writes the module out to binary, then reads it right back in. a lil circular moment โจ--rseโ removes redundantlocal.sets๐ง--safe-heapโ instruments loads and stores so they check for invalid behavior ๐--separate-data-segmentsโ writes data segments out to a file and strips them from the module ๐ฆ--set-globalsโ sets the globals you specify to the values you specify ๐ฏ--signature-pruningโ removes params from function signature types wherever it possibly can โ๏ธ--signature-refiningโ applies more specific subtypes to signature types wherever possible ๐--signext-loweringโ lowers sign-ext operations down to wasm mvp and turns the sign extension feature off ๐ธ--simplify-globalsโ all the miscellaneous globals-related optimizations โจ--simplify-globals-optimizingโ same miscellaneous globals-related optimizations, plus it optimizes wherever we swappedglobal.gets out for constants ๐ซถ--simplify-localsโ all the miscellaneous locals-related optimizations ๐--simplify-locals-nonestingโ miscellaneous locals-related optimizations, but with no nesting at all โ it preserves flatness ๐ง--simplify-locals-nostructureโ miscellaneous locals-related optimizations, no structure edition ๐--simplify-locals-noteeโ miscellaneous locals-related optimizations, no tees edition ๐--simplify-locals-notee-nostructureโ miscellaneous locals-related optimizations with absolutely no tees and no structure. minimalist queen ๐--souperifyโ emits Souper IR in text form โ๏ธ--souperify-single-useโ emits Souper IR in text form, but single-use nodes only ๐--spill-pointersโ spills pointers onto the C stack (this is the one for Boehm-style GC) ๐--ssaโ ssa-ifies your variables so every one of them gets a single assignment ๐ฏ--ssa-nomergeโ ssa-ifies your variables so each gets a single assignment, ignoring merges ๐--stack-checkโ enforces limits on llvm's__stack_pointerglobal ๐ง--string-gatheringโ gathers wasm strings up into globals ๐งบ--string-liftingโ lifts string imports up into wasm strings ๐--string-loweringโ lowers wasm strings and operations down into imports โฌ๏ธ--string-lowering-magic-importsโ same asstring-lowering, except it encodes well-formed strings as magic imports โจ--string-lowering-magic-imports-assertโ same asstring-lowering-magic-imports, except it raises a fatal error if there are invalid strings ๐--stripโ deprecated; same asstrip-debugโ ๏ธ--strip-debugโ strips debug info, and that includes the names section ๐งน--strip-dwarfโ strips dwarf debug info ๐งน--strip-ehโ strips EH instructions ๐งน--strip-producersโ strips the wasm producers section ๐งน--strip-target-featuresโ strips the wasm target features section ๐งน--strip-toolchain-annotationsโ strips out every toolchain-specific code annotation ๐งน--stub-unsupported-jsโ stubs out the JS operations that aren't supported ๐--symbolmapโ (alias forprint-function-map) ๐บ๏ธ--table64-loweringโ alias formemory64-lowering๐--trace-callsโ instruments the build with code that intercepts specific function calls ๐--translate-to-exnrefโ translates old Phase 3 EH instructions into the new ones withexnref๐--translate-to-new-ehโ deprecated; same astranslate-to-exnrefโ ๏ธ--trap-mode-clampโ replaces trapping operations with clamping semantics ๐งฒ--trap-mode-jsโ replaces trapping operations with js semantics ๐จ--tuple-optimizationโ optimizes trivial tuples right out of existence ๐ซฅ--type-finalizingโ marks every leaf type as final ๐--type-mergingโ merges types into their supertypes wherever possible ๐ซ--type-refiningโ applies more specific subtypes to type fields wherever possible ๐--type-refining-gufaโ applies more specific subtypes to type fields wherever possible, using GUFA โจ--type-ssaโ creates new types to help out the other optimizations (team player fr) ๐ซถ--type-unfinalizingโ marks every type as non-final (open) ๐--unsubtypingโ removes the subtyping relationships that aren't necessary โ๏ธ--unteeโ removeslocal.teesand replaces them with sets and gets ๐--vacuumโ sucks up code that's obviously unneeded ๐งน
๐ Optimization options ๐
bestie this is the big one. the -O dial. turn it up, turn it down, pick your fighter ๐
-Oโ run the default optimization passes (it's equivalent to-Os) โจ-O0โ run no optimization passes at all. nothing. raw. ๐-O1โ run the-O1optimization passes: quick & useful opts, great for iteration builds ๐-O2โ run the-O2optimization passes: most of the opts, generally gets you most of the perf ๐-O3โ run the-O3optimization passes: it spends potentially a lot of time optimizing, and honestly? it's worth it ๐ฅ-O4โ run the-O4optimization passes: this one also flattens the IR, which can take a lot more time and memory, but it's genuinely useful on more nested / complex / less-optimized input ๐-Osโ run the default optimization passes, but focusing on code size ๐ฆ-Ozโ run the default optimization passes with super-focus on code size. teeny tiny ๐--optimize-level,-olโ how much to focus on optimizing code โก--shrink-level,-sโ how much to focus on shrinking code size ๐--debuginfo,-gโ emit the names section in the wasm binary (or full debuginfo in wast) ๐--always-inline-max-function-size,-aimfsโ the max size of functions that are always inlined (default2, which is safe to use with-Osbuilds) ๐ซถ--flexible-inline-max-function-size,-fimfsโ the max size of functions that get inlined when they're lightweight (no loops or function calls) while optimizing aggressively for speed (-O3). Default:20๐ชถ--one-caller-inline-max-function-size,-ocimfsโ the max size of functions that get inlined when there's only one caller (default-1, which means all such functions are inlined) โ๏ธ--inline-max-combined-binary-size,-imcbsโ the max size of combined functions after inlining. Default:409600๐--inline-functions-with-loops,-ifwlโ allow inlining of functions that have loops ๐--partial-inlining-ifs,-piiโ the number of ifs allowed in partial inlining (zero means partial inlining is disabled) (default:0) ๐ค--ignore-implicit-traps,-iitโ optimize under the helpful assumption that no surprising traps occur (from load, div/mod, etc.) โ ๏ธ--traps-never-happen,-tnhโ optimize under the helpful assumption that no trap is ever reached at runtime (from load, div/mod, etc.) ๐--low-memory-unused,-lmuโ optimize under the helpful assumption that the low 1K of memory isn't used by the application ๐ง--fast-math,-ffmโ optimize floats without handling the corner cases of NaNs and rounding ๐--zero-filled-memory,-uimโ assume that an imported memory will be zero-initialized 0๏ธโฃ--skip-pass,-spโ skip a pass (as in, don't run it) ๐
๐ ๏ธ Tool options ๐ ๏ธ
--mvp-features,-mvpโ disable every non-MVP feature ๐ซ--all-features,-allโ enable every feature. all of them. the whole buffet ๐ฝ๏ธ--detect-featuresโ (deprecated - this flag does nothing) ๐--quiet,-qโ emit less verbose output and hide the trivial warnings. peace and quiet era ๐คซ--experimental-poppyโ parse wast files as Poppy IR, for testing purposes ๐ผ--emit-module-namesโ emit module names, even if you're not emitting the rest of the names section โจ--enable-sign-extโ enable sign extension operations โ--disable-sign-extโ disable sign extension operations โ--enable-threadsโ enable atomic operations ๐งต--disable-threadsโ disable atomic operations ๐ซ--enable-mutable-globalsโ enable mutable globals ๐--disable-mutable-globalsโ disable mutable globals ๐--enable-nontrapping-float-to-intโ enable nontrapping float-to-int operations ๐--disable-nontrapping-float-to-intโ disable nontrapping float-to-int operations ๐ซ--enable-simdโ enable SIMD operations and types ๐๏ธ--disable-simdโ disable SIMD operations and types ๐ซ--enable-bulk-memoryโ enable bulk memory operations ๐งฑ--disable-bulk-memoryโ disable bulk memory operations ๐ซ--enable-bulk-memory-optโ enablememory.copyandmemory.fill๐--disable-bulk-memory-optโ disablememory.copyandmemory.fill๐ซ--enable-call-indirect-overlongโ enable LEB encoding of call-indirect (ignored for compatibility, since it has no effect on Binaryen) ๐คท--disable-call-indirect-overlongโ disable LEB encoding of call-indirect (ignored for compatibility, since it has no effect on Binaryen) ๐คท--enable-exception-handlingโ turns ON exception handling operations ๐--disable-exception-handlingโ turns OFF exception handling operations--enable-tail-callโ turns ON tail call operations โจ--disable-tail-callโ turns OFF tail call operations--enable-reference-typesโ turns ON reference types ๐--disable-reference-typesโ turns OFF reference types--enable-multivalueโ turns ON multivalue functions ๐ฆ--disable-multivalueโ turns OFF multivalue functions--enable-gcโ turns ON garbage collection ๐ธ--disable-gcโ turns OFF garbage collection--enable-memory64โ turns ON memory64 ๐--disable-memory64โ turns OFF memory64--enable-relaxed-simdโ turns ON relaxed SIMD ๐ซถ--disable-relaxed-simdโ turns OFF relaxed SIMD--enable-extended-constโ turns ON extended const expressions ๐ญ--disable-extended-constโ turns OFF extended const expressions--enable-stringsโ turns ON strings ๐ฅ--disable-stringsโ turns OFF strings--enable-multimemoryโ turns ON multimemory ๐--disable-multimemoryโ turns OFF multimemory--enable-stack-switchingโ turns ON stack switching ๐--disable-stack-switchingโ turns OFF stack switching--enable-shared-everythingโ turns ON shared-everything threads โญ--disable-shared-everythingโ turns OFF shared-everything threads--enable-fp16โ turns ON float 16 operations ๐--disable-fp16โ turns OFF float 16 operations--enable-custom-descriptorsโ turns ON custom descriptors (RTTs) and exact references ๐--disable-custom-descriptorsโ turns OFF custom descriptors (RTTs) and exact references--enable-multibyteโ turns ON multibyte array loads and stores ๐--disable-multibyteโ turns OFF multibyte array loads and stores--enable-relaxed-atomicsโ turns ON acquire/release atomic memory operations ๐ง--disable-relaxed-atomicsโ turns OFF acquire/release atomic memory operations--enable-custom-page-sizesโ turns ON custom page sizes ๐--disable-custom-page-sizesโ turns OFF custom page sizes--enable-wide-arithmeticโ turns ON wide arithmetic ๐--disable-wide-arithmeticโ turns OFF wide arithmetic--enable-compact-importsโ turns ON compact import section โจ--disable-compact-importsโ turns OFF compact import section--enable-typed-function-referencesโ deprecated compat flag, bestie, it's just vibing here for the old days ๐--disable-typed-function-referencesโ also a deprecated compatibility flag, same energy ๐--no-validation,-nโ disables validation, and yes it literally just assumes your inputs are correct ๐ญ it does NOT check for you, it trusts you completely, which is either iconic or terrifying depending on the day--pass-arg,-paโ an argument you pass along to whatever optimization passes are being run ๐ซถ. It must be in the formKEY@VALUE. IfKEYis the name of a pass then it applies to the closest instance of that pass before us. IfKEYisn't the name of a pass then it's a global option that applies to all pass instances that read it ๐--closed-world,-cwโ assume code outside of the module does not inspect or interact with GC and function references, even if they are passed out ๐. The outside may hold on to them and pass them back in, but not inspect their contents or call them.--preserve-type-orderโ preserve the order of types from the input (so good for debugging and testing, fr fr) ๐ธ--generate-stack-irโ generate StackIR during writing ๐ฆ--optimize-stack-irโ optimize StackIR during writing ๐--print-stack-irโ print StackIR during writing ๐--no-stack-irโ do not use StackIR (even when it is the default) ๐ซ
๐ General options ๐
the little housekeeping besties, the ones you actually need every single day
--versionโ output version information and exit โญ--help,-hโ show this help message and exit ๐ซถ--debug,-dโ print debug information tostderr๐
and that's the whole thing, bestie, you made it to the end ๐ this was wasm-opt from version 131, dated August 2026, and the page you just read is WASM-OPT(1). go forth and optimize, no cap ๐โจ
๐ฆ where this page comes from
- ubuntu stonking: binaryen 131-2 ยท Apache-2.0
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms