Simplify the dead EBB argument tracking.

It is not necessary to to a second pass over the live values to update
the set of available registers. The color_args() and color_entry_args()
functions can do that in a single pass.
This commit is contained in:
Jakob Stoklund Olesen
2017-05-11 11:48:58 -07:00
parent 9f743cf3a5
commit 4dda3e02f1

View File

@@ -163,24 +163,14 @@ impl<'a> Context<'a> {
tracker.ebb_top(ebb, &func.dfg, self.liveness, &func.layout, self.domtree); tracker.ebb_top(ebb, &func.dfg, self.liveness, &func.layout, self.domtree);
// Arguments to the entry block have ABI constraints. // Arguments to the entry block have ABI constraints.
let mut regs = if func.layout.entry_block() == Some(ebb) { if func.layout.entry_block() == Some(ebb) {
assert_eq!(liveins.len(), 0); assert_eq!(liveins.len(), 0);
self.color_entry_args(&func.signature, args, &mut func.locations) self.color_entry_args(&func.signature, args, &mut func.locations)
} else { } else {
// The live-ins have already been assigned a register. Reconstruct the allocatable set. // The live-ins have already been assigned a register. Reconstruct the allocatable set.
let regs = self.livein_regs(liveins, func); let regs = self.livein_regs(liveins, func);
self.color_args(args, regs, &mut func.locations) self.color_args(args, regs, &mut func.locations)
};
// Now forget about the dead arguments.
for lv in args.iter().filter(|&lv| lv.is_dead) {
if let Affinity::Reg(rci) = lv.affinity {
let rc = self.reginfo.rc(rci);
let reg = func.locations[lv.value].unwrap_reg();
regs.free(rc, reg);
}
} }
regs
} }
/// Initialize a set of allocatable registers from the values that are live-in to a block. /// Initialize a set of allocatable registers from the values that are live-in to a block.
@@ -221,7 +211,7 @@ impl<'a> Context<'a> {
/// These are function arguments that should already have assigned register units in the /// These are function arguments that should already have assigned register units in the
/// function signature. /// function signature.
/// ///
/// Return the set of remaining allocatable registers. /// Return the set of remaining allocatable registers after filtering out the dead arguments.
fn color_entry_args(&self, fn color_entry_args(&self,
sig: &Signature, sig: &Signature,
args: &[LiveValue], args: &[LiveValue],
@@ -236,7 +226,9 @@ impl<'a> Context<'a> {
Affinity::Reg(rci) => { Affinity::Reg(rci) => {
let rc = self.reginfo.rc(rci); let rc = self.reginfo.rc(rci);
if let ArgumentLoc::Reg(reg) = abi.location { if let ArgumentLoc::Reg(reg) = abi.location {
regs.take(rc, reg); if !lv.is_dead {
regs.take(rc, reg);
}
*locations.ensure(lv.value) = ValueLoc::Reg(reg); *locations.ensure(lv.value) = ValueLoc::Reg(reg);
} else { } else {
// This should have been fixed by the reload pass. // This should have been fixed by the reload pass.
@@ -278,6 +270,9 @@ impl<'a> Context<'a> {
mut regs: AllocatableSet, mut regs: AllocatableSet,
locations: &mut EntityMap<Value, ValueLoc>) locations: &mut EntityMap<Value, ValueLoc>)
-> AllocatableSet { -> AllocatableSet {
// Available registers *after* filtering out the dead arguments.
let mut live_regs = regs.clone();
for lv in args { for lv in args {
// Only look at the register arguments. // Only look at the register arguments.
if let Affinity::Reg(rci) = lv.affinity { if let Affinity::Reg(rci) = lv.affinity {
@@ -287,11 +282,16 @@ impl<'a> Context<'a> {
.next() .next()
.expect("Out of registers for arguments"); .expect("Out of registers for arguments");
regs.take(rc, reg); regs.take(rc, reg);
if !lv.is_dead {
live_regs.take(rc, reg);
}
*locations.ensure(lv.value) = ValueLoc::Reg(reg); *locations.ensure(lv.value) = ValueLoc::Reg(reg);
} }
} }
regs // All arguments are accounted for in `regs`. We don't care about the dead arguments now
// that we have made sure they don't interfere.
live_regs
} }
/// Color the values defined by `inst` and insert any necessary shuffle code to satisfy /// Color the values defined by `inst` and insert any necessary shuffle code to satisfy