Assign spill slots to spilled values.

As soon as a value is spilled, also assign it to a spill slot.

For now, create a new spill slot for each spilled value. In the future,
values will be sharing spill slots of they are phi-related.
This commit is contained in:
Jakob Stoklund Olesen
2017-06-16 13:32:21 -07:00
parent bae37e523f
commit 342121aba0
2 changed files with 25 additions and 11 deletions

View File

@@ -10,6 +10,7 @@ test regalloc
; - %x10-%x15 are function arguments.
;
; regex: V=v\d+
; regex: WS=\s+
isa riscv enable_e
@@ -19,14 +20,18 @@ isa riscv enable_e
; 2. The link register.
; 3. The first computed value, v2
function %pyramid(i32) -> i32 {
; check: ss0 = spill_slot 4
; check: ss1 = spill_slot 4
; check: ss2 = spill_slot 4
; not: spill_slot
ebb0(v1: i32):
; check: $ebb0($(rv1=$V): i32, $(rlink=$V): i32)
; check: $v1 = spill $rv1
; nextln: $(link=$V) = spill $rlink
; check: ,ss0]$WS $v1 = spill $rv1
; nextln: ,ss1]$WS $(link=$V) = spill $rlink
; not: spill
v2 = iadd_imm v1, 12
; check: $(r1v2=$V) = iadd_imm
; nextln: $v2 = spill $r1v2
; nextln: ,ss2]$WS $v2 = spill $r1v2
; not: spill
v3 = iadd_imm v2, 12
v4 = iadd_imm v3, 12

View File

@@ -16,11 +16,11 @@
//! operands.
use dominator_tree::DominatorTree;
use entity_map::EntityMap;
use ir::{DataFlowGraph, Layout, Cursor, InstBuilder};
use ir::{Function, Ebb, Inst, Value, SigRef};
use ir::{Function, Ebb, Inst, Value, ValueLoc, SigRef};
use ir::{InstEncodings, StackSlots, ValueLocations};
use isa::registers::{RegClass, RegClassMask};
use isa::{TargetIsa, RegInfo, EncInfo, Encoding, RecipeConstraints, ConstraintKind};
use isa::{TargetIsa, RegInfo, EncInfo, RecipeConstraints, ConstraintKind};
use regalloc::affinity::Affinity;
use regalloc::live_value_tracker::{LiveValue, LiveValueTracker};
use regalloc::liveness::Liveness;
@@ -41,7 +41,9 @@ struct Context<'a> {
encinfo: EncInfo,
// References to parts of the current function.
encodings: &'a mut EntityMap<Inst, Encoding>,
encodings: &'a mut InstEncodings,
stack_slots: &'a mut StackSlots,
locations: &'a mut ValueLocations,
// References to contextual data structures we need.
domtree: &'a DominatorTree,
@@ -85,6 +87,8 @@ impl Spilling {
reginfo: isa.register_info(),
encinfo: isa.encoding_info(),
encodings: &mut func.encodings,
stack_slots: &mut func.stack_slots,
locations: &mut func.locations,
domtree,
liveness,
topo,
@@ -209,7 +213,7 @@ impl<'a> Context<'a> {
if call_sig.is_some() {
for lv in throughs {
if lv.affinity.is_reg() && !self.spills.contains(&lv.value) {
self.spill_reg(lv.value);
self.spill_reg(lv.value, dfg);
}
}
}
@@ -351,7 +355,7 @@ impl<'a> Context<'a> {
if let Some(value) = best {
// Found a spill candidate.
self.spill_reg(value);
self.spill_reg(value, dfg);
} else {
panic!("Ran out of registers for mask={}", mask);
}
@@ -365,12 +369,17 @@ impl<'a> Context<'a> {
///
/// Note that this does not update the cached affinity in the live value tracker. Call
/// `process_spills` to do that.
fn spill_reg(&mut self, value: Value) {
fn spill_reg(&mut self, value: Value, dfg: &DataFlowGraph) {
if let Affinity::Reg(rci) = self.liveness.spill(value) {
let rc = self.reginfo.rc(rci);
self.pressure.free(rc);
self.spills.push(value);
dbg!("Spilled {}:{} -> {}", value, rc, self.pressure);
// Assign a spill slot.
// TODO: phi-related values should use the same spill slot.
let ss = self.stack_slots.make_spill_slot(dfg.value_type(value));
*self.locations.ensure(value) = ValueLoc::Stack(ss);
dbg!("Spilled {}:{} to {} -> {}", value, rc, ss, self.pressure);
} else {
panic!("Cannot spill {} that was already on the stack", value);
}