Expand description
Making an assignment true in the function it was worked out for.
Design: spec/10-backend.md section 10.4.
crate::assign says where every value goes and touches nothing. This is the other half: every
operand is rewritten to the place its value was given, and the moves that the places do not
already say are collected. After it the function names no virtual register and no block asks
for anything, which is the point at which machine IR stops being in SSA form and starts being
something an encoder could read.
§Why the moves are handed back rather than written
A move is an instruction, and an instruction has an opcode, and an opcode belongs to a target.
spec/10-backend.md section 10.8 says no pipeline crate holds target specific code, so this
crate is not the one that can write x64.mov. What it hands back is an Edit: a move
between two places, the class it is in, and where in the function it goes. rucc-codegen turns
each one into whatever its target moves a register with, which for a value on the stack is a
load or a store rather than a move at all.
The edits at any one place are in the order they have to be made in. That matters in two places: a spilled operand is read into a scratch register before the instruction that wants it, and a two address instruction’s copy has to come after that read, because what it is copying may be the thing that was just read in.
§What a fixed register turns into
A move each way. The assignment deliberately gave the value some other register, so a division
whose dividend has to be in rax gets a move into rax in front of it and a move out of rax
behind it. That is the cost of the rule the assignment follows, and it is the rule that keeps
the -O0 allocator one pass.
§What an edge turns into
The moves that write the block’s parameters, in an order they can be made in one at a time,
which is what crate::moves is for. Where they go depends on the shape of the edge. A block
with one successor puts them at its own end, in front of the branch it finishes with, and a
block with several puts them at the start of the block the edge goes to, which is safe exactly
because that block has no other predecessor. An edge that is critical has neither place to put
them and has to have been split before allocation ran, which this checks rather than assumes.
Structs§
- Edit
- One move the places did not already make true.
Enums§
- At
- Where an edit goes.
Functions§
- rewrite
- Rewrites a function to the places it was given, and says what moves are still wanted.