Expand description
The prologue, the epilogue, and the moves the allocator asked for.
Design: spec/10-backend.md sections 10.4 and 10.7.
crate::frame works out what a function’s stack looks like and writes nothing. This is what
writes it. Three things are still missing from a function the allocator has finished with, and
all three of them are instructions no lowering rule chose:
the prologue takes the frame the layout worked out, and puts away the registers a call
leaves alone that this function writes anyway
the moves every spill, every reload and every copy the allocator handed back as an
edit, in the place it said and in the order it said
the epilogue gives the frame back and puts the registers back, at the end of every block
the function returns fromAfter this the function is one an encoder can read: every register is physical, every offset into the frame is a constant, and the stack pointer is where the convention says it should be at every instruction that could look.
§Why the moves go in first
Every offset the frame reports is from the stack pointer as it stands in the body of the function. A spill written before the prologue exists would be written in front of the instruction it belongs to and behind nothing, which is where the prologue then goes, so the prologue ends up in front of it and the offsets stay true. Writing them the other way round would put the first reload above the instruction that takes the frame, and it would read from an address that is one frame out.
§Where a return is
A block that goes nowhere is a block the function returns from. There is no other kind: a block with no successors and no return would be one that falls off the end of the function, which is a function that was mis-lowered rather than one this has an opinion about. So the epilogue goes at the end of every block with an empty successor list, and there may be several, because nothing here insists a function has one exit.
§What is target-specific here
The names, and only the names. Which instruction pushes a register and which one moves the
stack pointer is rucc_target::FrameInsts, which the target says and this reads, so what
is written below is the shape of a prologue rather than any particular machine’s. That is
spec/10-backend.md section 10.8 as it applies to the one pass that would otherwise be full
of x64. by hand.
Functions§
- finish
- Writes the moves, the prologue and the epilogue into a function the allocator has finished with.