pub trait Function {
type Inst: Clone + Debug;
Show 23 methods
// Required methods
fn insns(&self) -> &[Self::Inst];
fn insns_mut(&mut self) -> &mut [Self::Inst];
fn get_insn(&self, insn: InstIx) -> &Self::Inst;
fn get_insn_mut(&mut self, insn: InstIx) -> &mut Self::Inst;
fn blocks(&self) -> Range<BlockIx>;
fn entry_block(&self) -> BlockIx;
fn block_insns(&self, block: BlockIx) -> Range<InstIx>;
fn block_succs(&self, block: BlockIx) -> Cow<'_, [BlockIx]>;
fn is_ret(&self, insn: InstIx) -> bool;
fn get_regs(insn: &Self::Inst, collector: &mut RegUsageCollector<'_>);
fn map_regs<RUM: RegUsageMapper>(insn: &mut Self::Inst, maps: &RUM);
fn is_move(&self, insn: &Self::Inst) -> Option<(Writable<Reg>, Reg)>;
fn get_num_vregs(&self) -> usize;
fn get_spillslot_size(
&self,
regclass: RegClass,
for_vreg: VirtualReg,
) -> u32;
fn gen_spill(
&self,
to_slot: SpillSlot,
from_reg: RealReg,
for_vreg: Option<VirtualReg>,
) -> Self::Inst;
fn gen_reload(
&self,
to_reg: Writable<RealReg>,
from_slot: SpillSlot,
for_vreg: Option<VirtualReg>,
) -> Self::Inst;
fn gen_move(
&self,
to_reg: Writable<RealReg>,
from_reg: RealReg,
for_vreg: VirtualReg,
) -> Self::Inst;
fn gen_zero_len_nop(&self) -> Self::Inst;
fn maybe_direct_reload(
&self,
insn: &Self::Inst,
reg: VirtualReg,
slot: SpillSlot,
) -> Option<Self::Inst>;
fn func_liveins(&self) -> Set<RealReg>;
fn func_liveouts(&self) -> Set<RealReg>;
// Provided methods
fn insn_indices(&self) -> Range<InstIx> { ... }
fn is_included_in_clobbers(&self, _insn: &Self::Inst) -> bool { ... }
}
Expand description
A trait defined by the regalloc client to provide access to its machine-instruction / CFG representation.
Required Associated Types§
Required Methods§
Sourcefn insns_mut(&mut self) -> &mut [Self::Inst]
fn insns_mut(&mut self) -> &mut [Self::Inst]
Allow mutable access to the underlying vector of instructions.
Sourcefn get_insn(&self, insn: InstIx) -> &Self::Inst
fn get_insn(&self, insn: InstIx) -> &Self::Inst
Get an instruction with a type-safe InstIx index.
Sourcefn get_insn_mut(&mut self, insn: InstIx) -> &mut Self::Inst
fn get_insn_mut(&mut self, insn: InstIx) -> &mut Self::Inst
Get a mutable borrow of an instruction with the given type-safe InstIx index.
Sourcefn entry_block(&self) -> BlockIx
fn entry_block(&self) -> BlockIx
Get the index of the entry block.
Sourcefn block_insns(&self, block: BlockIx) -> Range<InstIx>
fn block_insns(&self, block: BlockIx) -> Range<InstIx>
Provide the range of instruction indices contained in each block.
Sourcefn block_succs(&self, block: BlockIx) -> Cow<'_, [BlockIx]>
fn block_succs(&self, block: BlockIx) -> Cow<'_, [BlockIx]>
Get CFG successors for a given block.
Sourcefn is_ret(&self, insn: InstIx) -> bool
fn is_ret(&self, insn: InstIx) -> bool
Determine whether an instruction is a return instruction.
Sourcefn get_regs(insn: &Self::Inst, collector: &mut RegUsageCollector<'_>)
fn get_regs(insn: &Self::Inst, collector: &mut RegUsageCollector<'_>)
Add to collector
the used, defined, and modified registers for an
instruction.
Sourcefn map_regs<RUM: RegUsageMapper>(insn: &mut Self::Inst, maps: &RUM)
fn map_regs<RUM: RegUsageMapper>(insn: &mut Self::Inst, maps: &RUM)
Map each register slot through a virtual-to-real mapping indexed
by virtual register. The two separate maps in maps.pre
and
maps.post
provide the mapping to use for uses (which semantically
occur just prior to the instruction’s effect) and defs (which
semantically occur just after the instruction’s effect). Regs that were
“modified” can use either map; the vreg should be the same in both.
Note that this does not take a self
, because we want to allow the
regalloc to have a mutable borrow of an insn (which borrows the whole
Function in turn) outstanding while calling this.
Sourcefn is_move(&self, insn: &Self::Inst) -> Option<(Writable<Reg>, Reg)>
fn is_move(&self, insn: &Self::Inst) -> Option<(Writable<Reg>, Reg)>
Allow the regalloc to query whether this is a move. Returns (dst, src).
Sourcefn get_num_vregs(&self) -> usize
fn get_num_vregs(&self) -> usize
Get the precise number of VirtualReg
in use in this function, to allow preallocating data
structures. This number must be a correct lower-bound, otherwise invalid index failures
may happen; it is of course better if it is exact.
Sourcefn get_spillslot_size(&self, regclass: RegClass, for_vreg: VirtualReg) -> u32
fn get_spillslot_size(&self, regclass: RegClass, for_vreg: VirtualReg) -> u32
How many logical spill slots does the given regclass require? E.g., on a 64-bit machine, spill slots may nominally be 64-bit words, but a 128-bit vector value will require two slots. The regalloc will always align on this size.
This passes the associated virtual register to the client as well, because the way in which we spill a real register may depend on the value that we are using it for. E.g., if a machine has V128 registers but we also use them for F32 and F64 values, we may use a different store-slot size and smaller-operand store/load instructions for an F64 than for a true V128.
Sourcefn gen_spill(
&self,
to_slot: SpillSlot,
from_reg: RealReg,
for_vreg: Option<VirtualReg>,
) -> Self::Inst
fn gen_spill( &self, to_slot: SpillSlot, from_reg: RealReg, for_vreg: Option<VirtualReg>, ) -> Self::Inst
Generate a spill instruction for insertion into the instruction sequence. The associated virtual register (whose value is being spilled) is passed, if it exists, so that the client may make decisions about the instruction to generate based on the type of value in question. Because the register allocator will insert spill instructions at arbitrary points, the returned instruction here must not modify the machine’s condition codes.
Sourcefn gen_reload(
&self,
to_reg: Writable<RealReg>,
from_slot: SpillSlot,
for_vreg: Option<VirtualReg>,
) -> Self::Inst
fn gen_reload( &self, to_reg: Writable<RealReg>, from_slot: SpillSlot, for_vreg: Option<VirtualReg>, ) -> Self::Inst
Generate a reload instruction for insertion into the instruction sequence. The associated virtual register (whose value is being loaded) is passed as well, if it exists. The returned instruction must not modify the machine’s condition codes.
Sourcefn gen_move(
&self,
to_reg: Writable<RealReg>,
from_reg: RealReg,
for_vreg: VirtualReg,
) -> Self::Inst
fn gen_move( &self, to_reg: Writable<RealReg>, from_reg: RealReg, for_vreg: VirtualReg, ) -> Self::Inst
Generate a register-to-register move for insertion into the instruction sequence. The associated virtual register is passed as well. The returned instruction must not modify the machine’s condition codes.
Sourcefn gen_zero_len_nop(&self) -> Self::Inst
fn gen_zero_len_nop(&self) -> Self::Inst
Generate an instruction which is a no-op and has zero length.
Sourcefn maybe_direct_reload(
&self,
insn: &Self::Inst,
reg: VirtualReg,
slot: SpillSlot,
) -> Option<Self::Inst>
fn maybe_direct_reload( &self, insn: &Self::Inst, reg: VirtualReg, slot: SpillSlot, ) -> Option<Self::Inst>
Try to alter an existing instruction to use a value directly in a spillslot (accessing memory directly) instead of the given register. May be useful on ISAs that have mem/reg ops, like x86.
Note that this is not quite just fusing a load with the op; if the value is def’d or modified, it should be written back to the spill slot as well. In other words, it is just using the spillslot as if it were a real register, for reads and/or writes.
FIXME JRS 2020Feb06: state precisely the constraints on condition code changes.
Sourcefn func_liveins(&self) -> Set<RealReg>
fn func_liveins(&self) -> Set<RealReg>
Return the set of registers that should be considered live at the beginning of the function. This is semantically equivalent to an instruction at the top of the entry block def’ing all registers in this set.
Sourcefn func_liveouts(&self) -> Set<RealReg>
fn func_liveouts(&self) -> Set<RealReg>
Return the set of registers that should be considered live at the end of the function (after every return instruction). This is semantically equivalent to an instruction at each block with no successors that uses each of these registers.
Provided Methods§
Sourcefn insn_indices(&self) -> Range<InstIx>
fn insn_indices(&self) -> Range<InstIx>
Get all instruction indices as an iterable range.
Sourcefn is_included_in_clobbers(&self, _insn: &Self::Inst) -> bool
fn is_included_in_clobbers(&self, _insn: &Self::Inst) -> bool
Determine whether an instruction should be considered while computing
the set of registers that need to be saved/restored in the function’s
prologue/epilogue, that is, the registers returned in
clobbered_registers
in RegAllocResult
. computation. Only
instructions for which this function returns true
will be used to
compute that set.
One reason that a client might not want an instruction to be included would be if it can handle the clobbers some other way: for example, ABI-support code might exclude call instructions’ defs and mods from the clobber set, because (given the callee has same ABI as the caller) the registers possibly written by the callee are all registers that the caller is also allowed to clobber (not save/restore in prologue/epilogue).
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.