From 342121aba089adba96948c9993d1275ae20c6ba8 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 16 Jun 2017 13:32:21 -0700 Subject: [PATCH] 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. --- filetests/regalloc/spill.cton | 11 ++++++++--- lib/cretonne/src/regalloc/spilling.rs | 25 +++++++++++++++++-------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/filetests/regalloc/spill.cton b/filetests/regalloc/spill.cton index f163c478b3..23ddf7129b 100644 --- a/filetests/regalloc/spill.cton +++ b/filetests/regalloc/spill.cton @@ -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 diff --git a/lib/cretonne/src/regalloc/spilling.rs b/lib/cretonne/src/regalloc/spilling.rs index 23d4799dad..f21e6e6c1a 100644 --- a/lib/cretonne/src/regalloc/spilling.rs +++ b/lib/cretonne/src/regalloc/spilling.rs @@ -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, + 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); }