Clobbers: use a more efficient bitmask representation in API. (#58)
* Clobbers: use a more efficient bitmask representation in API. Currently, the `Function` trait requires a `&[PReg]` for the clobber-list for a given instruction. In most cases where clobbers are used, the list may be long: e.g., ABIs specify a fixed set of registers that are clobbered and there may be ~half of all registers in this list. What's more, the list can't be shared for e.g. all calls of a given ABI, because actual return-values (defs) can't be clobbers. So we need to allocate space for long, sometimes-slightly-different lists; this is inefficient for the embedder and for us. It's much more efficient to use a bitmask to represent a set of physical registers. With current data structure bitpacking limitations, we can support at most 128 physical registers; this means we can use a `u128` bitmask. This also allows e.g. an embedder to start with a constant for a given ABI, and mask out bits for actual return-value registers on call instructions. This PR makes that change, for minor but positive performance impact. * Review comments.
This commit is contained in:
@@ -95,7 +95,7 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
let clobbers = self
|
||||
.func
|
||||
.inst_clobbers(inst)
|
||||
.iter()
|
||||
.into_iter()
|
||||
.map(|preg| format!("{}", preg))
|
||||
.collect::<Vec<_>>();
|
||||
let allocs = (0..ops.len())
|
||||
|
||||
@@ -491,9 +491,7 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
// operands and clobbers.
|
||||
for inst in insns.rev().iter() {
|
||||
// Mark clobbers with CodeRanges on PRegs.
|
||||
for i in 0..self.func.inst_clobbers(inst).len() {
|
||||
// don't borrow `self`
|
||||
let clobber = self.func.inst_clobbers(inst)[i];
|
||||
for clobber in self.func.inst_clobbers(inst) {
|
||||
// Clobber range is at After point only: an
|
||||
// instruction can still take an input in a reg
|
||||
// that it later clobbers. (In other words, the
|
||||
|
||||
@@ -950,7 +950,7 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
}
|
||||
}
|
||||
for reg in this.func.inst_clobbers(inst) {
|
||||
redundant_moves.clear_alloc(Allocation::reg(*reg));
|
||||
redundant_moves.clear_alloc(Allocation::reg(reg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user