Misc usability and functionality enhancements:
- Support preferred and non-preferred subsets of a register class. This allows allocating, e.g., caller-saved registers before callee-saved registers. - Allow branch blockparam args to start an a certain offset in branch operands; this allows branches to have other operands too (e.g., conditional-branch inputs). - Allow `OperandOrAllocation` to be constructed from an `Allocation` and `OperandKind` as well (i.e., an allocation with an use/def bit).
This commit is contained in:
28
src/lib.rs
28
src/lib.rs
@@ -579,6 +579,15 @@ impl OperandOrAllocation {
|
||||
debug_assert!(alloc.bits() >> 29 >= 5);
|
||||
Self { bits: alloc.bits() }
|
||||
}
|
||||
pub fn from_alloc_and_kind(alloc: Allocation, kind: OperandKind) -> Self {
|
||||
debug_assert!(alloc.bits() >> 29 >= 5);
|
||||
let bits = alloc.bits()
|
||||
| match kind {
|
||||
OperandKind::Def => 0,
|
||||
OperandKind::Use => 1 << 28,
|
||||
};
|
||||
Self { bits }
|
||||
}
|
||||
pub fn is_operand(&self) -> bool {
|
||||
(self.bits >> 29) <= 4
|
||||
}
|
||||
@@ -659,10 +668,22 @@ pub trait Function {
|
||||
fn is_ret(&self, insn: Inst) -> bool;
|
||||
|
||||
/// Determine whether an instruction is the end-of-block
|
||||
/// branch. If so, its operands *must* be the block parameters for
|
||||
/// each of its block's `block_succs` successor blocks, in order.
|
||||
/// branch. If so, its operands at the indices given by
|
||||
/// `branch_blockparam_arg_offset()` below *must* be the block
|
||||
/// parameters for each of its block's `block_succs` successor
|
||||
/// blocks, in order.
|
||||
fn is_branch(&self, insn: Inst) -> bool;
|
||||
|
||||
/// If `insn` is a branch at the end of `block`, returns the
|
||||
/// operand index at which outgoing blockparam arguments are
|
||||
/// found. Starting at this index, blockparam arguments for each
|
||||
/// successor block's blockparams, in order, must be found.
|
||||
///
|
||||
/// It is an error if `self.inst_operands(insn).len() -
|
||||
/// self.branch_blockparam_arg_offset(insn)` is not exactly equal
|
||||
/// to the sum of blockparam counts for all successor blocks.
|
||||
fn branch_blockparam_arg_offset(&self, block: Block, insn: Inst) -> usize;
|
||||
|
||||
/// Determine whether an instruction is a safepoint and requires a stackmap.
|
||||
fn is_safepoint(&self, _: Inst) -> bool {
|
||||
false
|
||||
@@ -842,7 +863,8 @@ pub enum Edit {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MachineEnv {
|
||||
regs: Vec<PReg>,
|
||||
regs_by_class: Vec<Vec<PReg>>,
|
||||
preferred_regs_by_class: Vec<Vec<PReg>>,
|
||||
non_preferred_regs_by_class: Vec<Vec<PReg>>,
|
||||
scratch_by_class: Vec<PReg>,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user