Spill values live across calls.

Calls clobber many registers, so spill everything that is live across a
call for now.

In the future, we may add support for callee-saved registers.
This commit is contained in:
Jakob Stoklund Olesen
2017-06-14 08:55:01 -07:00
parent 5a23f975fc
commit f2f162f37e
3 changed files with 33 additions and 1 deletions

View File

@@ -64,6 +64,14 @@ impl Affinity {
}
}
/// Is this the `Reg` affinity?
pub fn is_reg(self) -> bool {
match self {
Affinity::Reg(_) => true,
_ => false,
}
}
/// Is this the `Stack` affinity?
pub fn is_stack(self) -> bool {
match self {

View File

@@ -152,14 +152,25 @@ impl<'a> Context<'a> {
//
// Spills should be removed from tracker. Otherwise they could be double-counted by
// free_regs below.
let call_sig = dfg.call_signature(inst);
// Update the live value tracker with this instruction.
let (throughs, kills, defs) = tracker.process_inst(inst, dfg, self.liveness);
// Remove kills from the pressure tracker.
self.free_regs(kills);
// If inst is a call, spill all register values that are live across the call.
// This means that we don't currently take advantage of callee-saved registers.
// TODO: Be more sophisticated.
if call_sig.is_some() {
for lv in throughs {
if lv.affinity.is_reg() && !self.spills.contains(&lv.value) {
self.spill_reg(lv.value);
}
}
}
// Make sure we have enough registers for the register defs.
// Dead defs are included here. They need a register too.
// No need to process call return values, they are in fixed registers.