pub struct Pending<'a> {
pub addresses: &'a mut Vec<(Inst, usize)>,
pub arguments: &'a mut Vec<(Inst, u32)>,
pub dynamic: &'a mut Vec<Inst>,
}Expand description
The addresses crate::finish has still to write a displacement into.
Three lists, because the frame holds three kinds of place this pass runs before the layout of:
a local’s address is an offset into this function’s own objects, a stack argument’s is an offset
into the caller’s area, and a variable length array’s is an offset above wherever the stack
pointer ended up. What they have in common is the shape, a lea off the stack pointer with the
displacement left at zero, and what this type is for is that folding one of those away has to
move the entry rather than lose it.
This used to be a set of instructions the pass refused to touch, and refusing was expensive.
Every access to a local through its address was a lea and then a memory instruction reading
through the register it wrote, which is one instruction more than it needs, on the shape any
function whose locals have their address taken is full of. tamnd/rucc#784.
Fields§
§addresses: &'a mut Vec<(Inst, usize)>Which instruction carries the address of which of this function’s stack objects.
arguments: &'a mut Vec<(Inst, u32)>Which instruction reads which of the arguments the caller passed on the stack.
dynamic: &'a mut Vec<Inst>Which instructions carry the address of a local whose size the program worked out.
There is no number beside one of these, because where a variable length array starts is not a place the frame layout hands back: the bytes are already off the stack pointer by the time the address is taken, so what gets written in is how much of the bottom of the frame the arguments of a call keep, which is the same for all of them.