pub struct Func {
pub name: Symbol,
/* private fields */
}Expand description
One function, in machine instructions.
Fields§
§name: SymbolThe name it is called by, which is the name of the IR function it was lowered from.
Implementations§
Source§impl Func
impl Func
Sourcepub fn new_vreg(&mut self, class: RegClass) -> Reg
pub fn new_vreg(&mut self, class: RegClass) -> Reg
A virtual register of that class, which nothing has defined yet.
§Panics
Panics if the function already has two billion of them, which no function does.
Sourcepub fn vregs(&self) -> usize
pub fn vregs(&self) -> usize
How many virtual registers the function has, which is what the allocator sizes itself against.
Sourcepub fn class_of(&self, reg: Reg) -> Option<RegClass>
pub fn class_of(&self, reg: Reg) -> Option<RegClass>
The class of a virtual register, or None for a physical one or a number this function
never handed out.
Sourcepub fn create_block(&mut self) -> Block
pub fn create_block(&mut self) -> Block
Creates a block with no parameters and nothing in it, at the end of the layout.
Sourcepub fn entry(&self) -> Option<Block>
pub fn entry(&self) -> Option<Block>
The entry block, which is the first in layout order, or None before there is one.
Sourcepub fn block_count(&self) -> usize
pub fn block_count(&self) -> usize
How many blocks the function has ever had, which is what a table indexed by block is sized against. A block taken out of the layout still counts, because it keeps its index.
Sourcepub fn inst_count(&self) -> usize
pub fn inst_count(&self) -> usize
How many instructions the function has ever had, which is what a table indexed by instruction is sized against. One taken out of a block still counts, because it keeps its index.
Sourcepub fn blocks(&self) -> impl Iterator<Item = Block> + use<'_>
pub fn blocks(&self) -> impl Iterator<Item = Block> + use<'_>
Its blocks, in layout order, which is the order they are printed and emitted in.
Sourcepub fn set_block_order(&mut self, order: &[Block])
pub fn set_block_order(&mut self, order: &[Block])
Puts the blocks in that order, which is the order they are printed and emitted in.
A block keeps its index, so nothing holding one is invalidated and nothing else in the function has to be touched: the order is a linked list and this relinks it. That is the whole reason the list is a list rather than the order the blocks were created in.
The first block in the order becomes the entry, which is a real decision rather than a consequence: on this machine a function is entered at its first byte, so the block that runs first has to be laid out first.
§Panics
Panics unless order is every block of the function exactly once. A block left out would
be unreachable in a way nothing later could notice, and one named twice would make the
list a loop, so both are worth finding here rather than in the encoder.
Sourcepub fn append_param(&mut self, block: Block, class: RegClass) -> Reg
pub fn append_param(&mut self, block: Block, class: RegClass) -> Reg
Adds a parameter of that class to a block, and gives back the virtual register it arrives as.
Every predecessor’s arm has to grow an argument to match, which is what
Func::succs_mut is for.
Sourcepub fn append_given_param(&mut self, block: Block, param: Param)
pub fn append_given_param(&mut self, block: Block, param: Param)
Adds a parameter that is already a particular register, which is what allocation leaves behind.
Sourcepub fn params_mut(&mut self, block: Block) -> &mut Vec<Param>
pub fn params_mut(&mut self, block: Block) -> &mut Vec<Param>
What arrives in a block, to be read or replaced.
Allocation is what replaces it: once every parameter is a place and every argument is a place, an edge is a set of moves and the parameters are what those moves write, so the block stops asking for anything and the machine IR stops being in SSA form.
Sourcepub fn succs_mut(&mut self, block: Block) -> &mut Vec<BlockCall>
pub fn succs_mut(&mut self, block: Block) -> &mut Vec<BlockCall>
Where a block goes, to be read or replaced.
The arms are in the order the terminator’s own arms run, so the first is the arm a conditional branch takes when its condition holds.
Sourcepub fn insts(&self, block: Block) -> impl Iterator<Item = Inst> + use<'_>
pub fn insts(&self, block: Block) -> impl Iterator<Item = Inst> + use<'_>
The instructions of a block, in order.
Sourcepub fn terminator(&self, block: Block) -> Option<Inst>
pub fn terminator(&self, block: Block) -> Option<Inst>
The last instruction of a block, which is its terminator once it has one.
Sourcepub fn block_of(&self, inst: Inst) -> Option<Block>
pub fn block_of(&self, inst: Inst) -> Option<Block>
Which block an instruction is in, or None for one that has been taken out of its
block.
Sourcepub fn build(&mut self, block: Block, opcode: Opcode) -> InstBuilder<'_>
pub fn build(&mut self, block: Block, opcode: Opcode) -> InstBuilder<'_>
Starts an instruction at the end of that block.
Nothing is added to the function until InstBuilder::finish, so a builder that is
dropped leaves no trace.
Sourcepub fn append_inst(&mut self, block: Block, inst: Inst)
pub fn append_inst(&mut self, block: Block, inst: Inst)
Puts an instruction that is in no block at the end of one.
§Panics
Panics if the instruction is already in a block, because an instruction in two blocks is the kind of thing that is found much later and somewhere else.
Sourcepub fn insert_after(&mut self, after: Inst, inst: Inst)
pub fn insert_after(&mut self, after: Inst, inst: Inst)
Puts an instruction that is in no block immediately after another one.
§Panics
Panics if the instruction is already in a block, or if the one it is to follow is in none.
Sourcepub fn build_loose(&mut self, opcode: Opcode) -> InstBuilder<'_>
pub fn build_loose(&mut self, opcode: Opcode) -> InstBuilder<'_>
Starts an instruction that will be in no block until something puts it in one.
This is what a pass that inserts rather than appends builds with, and it hands the
instruction to Func::prepend_inst, Func::insert_before or Func::insert_after.
Everything else about it is the same, which is the point: the operand order is the
builder’s invariant wherever the instruction ends up.
Sourcepub fn prepend_inst(&mut self, block: Block, inst: Inst)
pub fn prepend_inst(&mut self, block: Block, inst: Inst)
Puts an instruction that is in no block at the start of one, in front of everything in it.
§Panics
Panics if the instruction is already in a block.
Sourcepub fn insert_before(&mut self, before: Inst, inst: Inst)
pub fn insert_before(&mut self, before: Inst, inst: Inst)
Puts an instruction that is in no block immediately before another one.
This is what a reload is: the instruction that wants the value has to see it already read in, so the load goes in front of it rather than behind whatever came before, which is the same place only when something came before.
§Panics
Panics if the instruction is already in a block, or if the one it is to precede is in none.
Sourcepub fn remove_inst(&mut self, inst: Inst)
pub fn remove_inst(&mut self, inst: Inst)
Takes an instruction out of its block, leaving it in the function’s tables.
It keeps its index, the way a removed block keeps its number, because renumbering would invalidate every index anything else was holding.
Sourcepub fn push_operands(&mut self, operands: &[Operand]) -> OperandList
pub fn push_operands(&mut self, operands: &[Operand]) -> OperandList
Puts a run of operands in the operand table and gives back the run.
Sourcepub fn add_amode(&mut self, amode: Amode) -> MemRef
pub fn add_amode(&mut self, amode: Amode) -> MemRef
Puts an addressing mode in the table of them.
Sourcepub fn create_inst(&mut self, data: InstData, span: Span) -> Inst
pub fn create_inst(&mut self, data: InstData, span: Span) -> Inst
Creates an instruction that is in no block yet.