`findPendingModule` decides which translation unit a demanded definition
is emitted into. Under `--icBackendStage:cg` it was `return m` with a
`# TODO fixme` over it: the destination was whichever TU did the asking,
because the stage was built around a single `--icBackendModule` and
there was never a second answer to give.
That hardcoding is what makes the backend inflexible to batching. It is
not that codegen cannot place a definition with its owner — the branch
four lines down already does exactly that, creating the `BModule` on
demand — it is that the cg stage could not express "this process writes
several modules' TUs", so the question never got asked.
So ask it. `BModuleList.icEmitted` is the set of module positions this
process writes a TU for, and routing consults it: an owner in the set
gets its own definition (the ordinary whole-program routing, now
reachable from cg), an owner outside it means the definition has nowhere
else to go and is emitted here as well — today's emit-everywhere, which
`merge` still deduplicates. Duplication therefore falls smoothly as the
set grows rather than switching over at some threshold.
The stage puts one module in the set, so this run is a no-op by
construction: the owner is `m` and the branch returns what `return m`
returned. Verified as one — a 67-module `--ic:on` build produces `.c`
AND `.c.nif` byte-identical to the previous commit's, `testament cat ic`
is 40/40, and `koch boot -d:release` reaches "executables are equal".
A change that provably alters nothing needs a live-probe check, or it is
indistinguishable from dead code. Temporarily adding `system`'s position
to the set — a module these processes do NOT write — moved 12 generic
instantiations (`addQuoted_i*`, `clamp_i*`) out of the TUs that demanded
them and into a TU nobody wrote, failing the link with exactly those 12
undefined symbols and shrinking generated `.c.nif` volume by 4%. The
routing is live; what it still lacks is the plumbing to write a TU per
batch member, which is the next step.