Measure Wado's performance or the size of the Wasm it generates, and refresh the benchmark/ and wasm-size/ README files. Use for any benchmarking or size-measurement request, whichever benchmark it names.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Debug the Wado optimizer with the WADO_TRACE, WADO_DUMP_PASS_BEFORE/AFTER, WADO_LIST_PASSES, and WADO_SKIP_PASS env vars. Use whenever a NIR/WIR pass is in question — wrong code, a WIR pipeline ICE, or just to see what a pass did to the IR. For guest-side slowness see wado-performance.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
실행 점수 미검증
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
The optimize.rs and wir_optimize.rs pipelines are big — many passes,
each rewriting the IR in place. When a pass is wrong, the symptom usually
shows up two passes later as "the WIR validates but produces the wrong
behaviour" or as "the codegen finds an invalid Wasm module" deep in the
final emitter. The debug hooks below let you diff the IR around any
single pass without sprinkling eprintln! through pass internals.
All three are env-var-driven so they work uniformly across wado compile,
wado test, wado run, and Kiln invocations from package-gale.
WADO_LIST_PASSES=1 cargo run --bin wado --quiet -- compile -O1 file.wado -o scratchpad/out.wasm 2>&1 | grep '\[pass\]'
Prints every pass name in execution order. Lets you correlate the order
in source (optimize.rs and wir_optimize.rs) with what actually fires
under your -Ox choice.
WADO_DUMP_PASS_AFTER=wir/sroa_multi_value_returns \
cargo run --bin wado --quiet -- compile -O1 file.wado -o scratchpad/out.wasm 2>scratchpad/after.log
scratchpad/after.log holds the full WIR (or NIR, depending on the pass) right
after the named pass, framed by === WIR after <name> === /
=== end WIR after <name> === (NIR passes use === NIR after <name> ===).
WADO_DUMP_PASS_BEFORE=wir/sroa_multi_value_returns \
cargo run --bin wado --quiet -- compile -O1 file.wado -o scratchpad/out.wasm 2>scratchpad/before.log
Same framing, before the pass runs. diff the two logs to see exactly
what the pass rewrote.
The variables accept a comma-separated list:
WADO_DUMP_PASS_AFTER=nir/inline,wir/sroa_multi_value_returns \
cargo run --bin wado --quiet -- compile -O1 file.wado -o scratchpad/out.wasm 2>scratchpad/dump.log
WADO_SKIP_PASS=nir/cse cargo run --bin wado --quiet -- compile -O3 file.wado -o scratchpad/out.wasm
Same comma-separated list as WADO_DUMP_PASS_*, with one extra
convenience: a @N suffix targets the Nth invocation of a pass within
the fixed-point loop (1-based). WADO_SKIP_PASS=nir/cse@2 skips cse
only on the second iteration — invaluable for iteration-dependent bugs
whose failing test passes on the first iteration and only diverges once
the inliner expands an additional function on a later one.
Only standalone run_pass spans are skippable; confirm a name with
WADO_LIST_PASSES=1 first. Local rules folded into the peephole session
(ref_elim, elide_box_local, match_to_switch, value_copy_elide,
array_literal, …) are not individually addressable — target
nir/peephole to skip the whole session.
When a pass is the only one whose skipping makes the bug go away that
just narrows the participants in the buggy interaction — it does not
prove the pass is itself buggy. Pair the skip-bisection result with
WADO_DUMP_PASS_AFTER on the same pass to compare its output across
the working vs. broken configuration before concluding.
For developer-only messages from inside a pass. The crate denies eprintln!,
so use compiler_trace!, which writes to the sink the host installed:
WADO_TRACE=sroa_return cargo run --bin wado --quiet -- compile -O1 file.wado -o scratchpad/out.wasm 2>&1 | grep '\[sroa_return\]'
Output is framed [target] message. Targets are passed verbatim to
compiler_trace!(target, ...) calls inside the compiler. Use
WADO_TRACE='*' to enable every target at once.
To add a new tracing call inside a pass:
use crate::compiler_trace;
// ...
compiler_trace!("sroa_return", "candidates = {}", candidates.len());
compiler_trace!("sroa_return", "rewriting return at {span:?}");
The cost when the target is disabled is one OnceLock get + a linear
scan of the configured target list — fine for any rate that makes
sense in a compiler pass.
--log-level debug ends the NIR loop with either "converged after N
iteration(s)" or "hit the N-iteration cap without converging", the latter
naming the passes still reporting changes. From there:
WADO_TRACE=opt_loop lists, per iteration, every pass that reported a
change. The tail of that list is the culprit set.WADO_TRACE=const_fold names each function const_fold changed, so a
pass that keeps reporting a change points at the body it keeps rewriting.
WADO_TRACE=inline_sites names, per round, the callees spliced into each
caller: a late round splicing small helpers is a callee that only shrank
under the threshold once its own callees were spliced.WADO_DUMP_PASS_BEFORE/_AFTER=<pass> around a late round, diffed, says
which of three it is: nothing rewritten at all (the pass reports a change it
did not make), a rewrite a later pass deletes (two passes fighting), or real
work that tapers (the pass takes one step per round where its own fixed
point is one sweep away).-O3 emitting several times -O2's wasm is the inliner, not the loop —
check the iteration count first (WADO_TRACE=opt_loop) and stop suspecting
convergence once it is small.
--optimize-inline-threshold. A cliff rather than a curve means one
callee crossed the budget and is now copied at every call site.WADO_TRACE=inline reports, per round, the unit size and how many
candidates the threshold admitted only because the cold discount put
them under it — with what those are worth in growth. A handful of callees
accounting for most of a round's growth is that pattern.
WADO_TRACE=inline_verdict gives each callee's verdict: its hot cost, its
call sites, and which of them it reaches.WADO_TRACE=cold_outline says why such a callee was not split: control
leaving the region, or a local the call cannot hand over.--optimize-inline-growth <pct> caps unit growth, and --log-level debug
then names what the cap turned down, with both of the callee's prices.A wir_expect that disappears when an unrelated knob moves is a precision hole
somewhere else: one pass reshaped the IR into a form the second pass does not
recognise, and the second pass is the one to fix.
--optimize-inline-threshold one step
at a time until the expectation flips. One step is one callee, so the
before/after dump --nir diff is small enough to read.WADO_TRACE=<pass> for the pass that stopped firing. const_object_globalization
names each function it walks and, per let, either the hoist or the check
that declined it.&x as a call argument versus &x bound
by a let — is the hole; the inliner just moved it from the first to the
second.The codegen-time validator catches type mismatches the optimizer introduced. The error always points at codegen, but the bug is upstream. Walk the pass pipeline like this:
Get the failing fixture compiling at -O0 first to confirm it is an
optimization-introduced bug (not a lower/codegen bug).
List the passes that run at the failing -Ox level:
WADO_LIST_PASSES=1 cargo run --bin wado --quiet -- compile -O1 fixture.wado -o scratchpad/out.wasm 2>&1 | grep '\[pass\]'
Bisect: pick a pass roughly mid-pipeline, dump after it, and check whether the IR is already broken. If it is, the bug is at or before that pass; otherwise it is later.
Once you have the suspect pass, dump before AND after it and read the diff. The mismatch will be visible — usually a function whose signature was rewritten but whose return sites weren't (the canonical shape of the SROA / signature-rewrite class of bugs), or a struct layout that changed in one place but not at consumers.
Add compiler_trace!("<pass_name>", ...) calls at the suspect rewrite
site to confirm which subtrees the pass visits. The *_mut walkers
in wir_visitor.rs and WirInstr::for_each_boxed_child_mut cover
most rewrite needs.
| Prefix | Phase |
|---|---|
nir/<name> | NIR-level pass (optimize.rs) |
wir/<name> | WIR-level pass (wir_optimize.rs) |
A #![wasm_module] core module (the allocator, mem) runs the WIR list as a
package of its own, under wir/<module>:<name> — so wir/run_peephole stays
the main module's and wir/mem:run_peephole targets the allocator.
WADO_LIST_PASSES=1 is the source of truth — names there match exactly
the strings the env vars want.
debugger skill (rust-gdb) or read the WIR/Wasm directly.tracing calls in annotate.rs directly.wado dump --tir-resolved / --tir-monomorphized (TIR, before lowering)
or --nir-lowered (NIR, right after lowering) instead; those are exposed
as proper CLI flags.wado-compiler/src/trace.rs — compiler_trace! macro and filter
parsing (with unit tests).wado-compiler/src/optimize.rs — run_pass for NIR passes; defines
the env-var hook implementation in mod pass_dump.wado-compiler/src/wir_optimize.rs — wir_pass for WIR passes.아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Measure Wado's performance or the size of the Wasm it generates, and refresh the benchmark/ and wasm-size/ README files. Use for any benchmarking or size-measurement request, whichever benchmark it names.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Measure how long GitHub Actions jobs and steps took across past runs, and find the pull request that made CI slower. Use for any question about CI duration, a slow job, or when CI got slow.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
How to answer code review feedback — a human reviewer, CodeRabbit, or any review bot. Verify the findings, report the classes they are instances of to the user before fixing, then fix the class rather than the sites named. Put design decisions to the user, then run /distill. Invoke when responding to review comments on a pull request, or to the findings of a /code-review run.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Investigate and improve code coverage for the wado-compiler crate. Use for any question about what the tests do and do not reach, dead code included.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Review the branch with /code-review at high, then answer the findings with /code-review-response.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use rust-gdb to inspect variables and step through code without modifying it. Prefer it over print debugging for any investigation into what the compiler is actually doing (lldb is unavailable on Claude Code Web).
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.