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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user