Expand description
The IR rewrites the machine needs before a rule can be asked anything.
Design: spec/10-backend.md section 10.2, which is where the ordering comes from.
Everything else in this crate turns an instruction into instructions. This turns a block into blocks, which is the one thing a rule cannot do: a rule replaces a term with a term, and the replacement has nowhere to put a block, so a construct whose lowering is a new shape of control flow has to be rewritten before selection rather than during it.
There is one such construct today and it is switch. Every other terminator leaves a block
with one successor or two, which is what the block layout writes jumps for, and a switch
leaves it with as many as the program had cases.
§Why this is the backend’s and not the front end’s
What a switch should become is a target decision and not a language one. A chain of compares
is right for three cases and wrong for two hundred, where the answer is a jump table, and wrong
again for twenty spread over a million, where it is a binary search on the value. A front end
that picked one would be picking for every target at once, and the IR would no longer hold what
the program said. So the switch survives as far as here, and here is where it is given up.
What is written today is the chain, which spec/10-backend.md calls the version every compiler
starts with. It is correct for any number of cases and it is slow for a large one. A jump table
wants a read only section to put the table in and a relocation to reach it, and neither exists
yet, so the chain is also the only one that could be written today.
Functions§
- blocks_
for - The blocks a chain of
ncases needs beyond the ones the program already had. - switches
- Rewrites every
switchin the function into branches, and leaves everything else alone.