Basic spilling implementation.

Add a spilling pass which lowers register pressure by assigning SSA
values to the stack. Important missing features:

- Resolve conflicts where an instruction uses the same value more than
  once in incompatible ways.
- Deal with EBB arguments.

Fix bugs in the reload pass exposed by the first test case:

- Create live ranges for temporary registers.
- Set encodings on created spill and fill instructions.
This commit is contained in:
Jakob Stoklund Olesen
2017-06-08 10:33:22 -07:00
parent 9cea092bc3
commit 63a372fd80
8 changed files with 380 additions and 6 deletions

View File

@@ -12,7 +12,6 @@ use partition_slice::partition_slice;
use regalloc::affinity::Affinity;
use regalloc::liveness::Liveness;
use regalloc::liverange::LiveRange;
use std::collections::HashMap;
type ValueList = EntityList<Value>;
@@ -299,6 +298,20 @@ impl LiveValueTracker {
self.live.remove_dead_values();
}
/// Process new spills.
///
/// Any values where `f` returns true are spilled and will be treated as if their affinity was
/// `Stack`.
pub fn process_spills<F>(&mut self, mut f: F)
where F: FnMut(Value) -> bool
{
for lv in &mut self.live.values {
if f(lv.value) {
lv.affinity = Affinity::Stack;
}
}
}
/// Save the current set of live values so it is associated with `idom`.
fn save_idom_live_set(&mut self, idom: Inst) {
let values = self.live.values.iter().map(|lv| lv.value);