Commit 2f47b866 authored by qinsoon's avatar qinsoon

[wip] debugging

parent dcfeb8fc
use ast::ir::MuID;
use ast::ir::*;
use compiler::backend;
use compiler::backend::reg_alloc::graph_coloring;
use compiler::backend::reg_alloc::graph_coloring::liveness::InterferenceGraph;
use compiler::backend::reg_alloc::graph_coloring::liveness::{Node, Move};
use compiler::backend;
use compiler::backend::reg_alloc::RegAllocFailure;
use compiler::machine_code::CompiledFunction;
use vm::VM;
use utils::vec_utils;
use utils::LinkedHashSet;
......@@ -14,7 +17,7 @@ const COALESCING : bool = true;
pub struct GraphColoring {
pub ig: InterferenceGraph,
precolored: LinkedHashSet<Node>,
colors: HashMap<backend::RegGroup, LinkedHashSet<MuID>>,
pub colored_nodes: Vec<Node>,
......@@ -42,10 +45,10 @@ pub struct GraphColoring {
}
impl GraphColoring {
pub fn start (ig: InterferenceGraph) -> Result<GraphColoring, RegAllocFailure> {
pub fn start (func: &mut MuFunctionVersion, cf: &mut CompiledFunction, vm: &VM) -> Result<GraphColoring, RegAllocFailure> {
let mut coloring = GraphColoring {
ig: ig,
ig: graph_coloring::build_inteference_graph(cf, func),
precolored: LinkedHashSet::new(),
colors: {
let mut map = HashMap::new();
......@@ -77,13 +80,13 @@ impl GraphColoring {
select_stack: Vec::new()
};
match coloring.init() {
match coloring.regalloc(func, cf, vm) {
Ok(_) => Ok(coloring),
Err(fail) => Err(fail)
}
}
fn init (&mut self) -> Result<(), RegAllocFailure> {
fn regalloc(&mut self, func: &mut MuFunctionVersion, cf: &mut CompiledFunction, vm: &VM) -> Result<(), RegAllocFailure> {
trace!("Initializing coloring allocator...");
// precolor for all machine registers
......@@ -129,7 +132,16 @@ impl GraphColoring {
&& self.worklist_spill.is_empty())
} {}
self.assign_colors()
self.assign_colors();
if !self.spilled_nodes.is_empty() {
trace!("spill required");
self.rewrite_program(func, cf, vm);
GraphColoring::start(func, cf, vm);
}
Ok(())
}
fn build(&mut self) {
......@@ -539,7 +551,7 @@ impl GraphColoring {
self.freeze_moves(m);
}
fn assign_colors(&mut self) -> Result<(), RegAllocFailure> {
fn assign_colors(&mut self) -> Result<(), ()> {
trace!("---coloring done---");
while !self.select_stack.is_empty() {
let n = self.select_stack.pop().unwrap();
......@@ -583,6 +595,49 @@ impl GraphColoring {
Ok(())
}
fn rewrite_program(&mut self, func: &mut MuFunctionVersion, cf: &mut CompiledFunction, vm: &VM) {
let spills = self.spills();
let mut spilled_mem = HashMap::new();
// allocating frame slots for every spilled temp
for reg_id in spills.iter() {
let ssa_entry = match func.context.get_value(*reg_id) {
Some(entry) => entry,
None => panic!("The spilled register {} is not in func context", reg_id)
};
let mem = cf.frame.alloc_slot_for_spilling(ssa_entry.value().clone(), vm);
spilled_mem.insert(*reg_id, mem);
}
let new_temps = backend::spill_rewrite(&spilled_mem, func, cf, vm);
//
// self.spilled_nodes.clear();
//
// self.initial = {
// let mut ret = vec![];
//
// for node in self.colored_nodes.iter() {
// vec_utils::add_unique(&mut ret, node.clone());
// }
// for node in self.coalesced_nodes.iter() {
// vec_utils::add_unique(&mut ret, node.clone());
// }
//
// // create nodes for every new temp
// for tmp in new_temps {
// let node = self.ig.new_node(tmp.id(), &func.context);
// vec_utils::add_unique(&mut ret, node.clone());
// }
//
// ret
// };
//
// self.colored_nodes.clear();
// self.coalesced_nodes.clear();
}
pub fn spills(&self) -> Vec<MuID> {
let mut spills = vec![];
......
......@@ -28,7 +28,6 @@ impl RegisterAllocation {
}
#[allow(unused_variables)]
// returns true if we spill registers (which requires another instruction selection)
fn coloring(&mut self, vm: &VM, func: &mut MuFunctionVersion) -> Result<(), RegAllocFailure> {
let compiled_funcs = vm.compiled_funcs().read().unwrap();
let mut cf = compiled_funcs.get(&func.id()).unwrap().write().unwrap();
......@@ -38,58 +37,32 @@ impl RegisterAllocation {
// initialize machine registers for the function context
init_machine_regs_for_func(&mut func.context);
let liveness = graph_coloring::build_inteference_graph(&mut cf, func);
liveness.print();
let coloring = match graph_coloring::GraphColoring::start(liveness) {
let coloring = match graph_coloring::GraphColoring::start(func, &mut cf, vm) {
Ok(coloring) => coloring,
Err(err) => {
return Err(err);
}
Err(_) => panic!("error during coloring - unexpected")
};
let spills = coloring.spills();
if !spills.is_empty() {
let mut spilled_mem = HashMap::new();
// allocating frame slots for every spilled temp
for reg_id in spills.iter() {
let ssa_entry = match func.context.get_value(*reg_id) {
Some(entry) => entry,
None => panic!("The spilled register {} is not in func context", reg_id)
};
let mem = cf.frame.alloc_slot_for_spilling(ssa_entry.value().clone(), vm);
spilled_mem.insert(*reg_id, mem);
}
backend::spill_rewrite(&spilled_mem, func, &mut cf, vm);
return Err(RegAllocFailure::FailedForSpilling);
}
// replace regs
trace!("Replacing Registers...");
for node in coloring.ig.nodes() {
let temp = coloring.ig.get_temp_of(node);
// skip machine registers
if temp < MACHINE_ID_END {
continue;
} else {
let alias = coloring.get_alias(node);
let machine_reg = coloring.ig.get_color_of(alias).unwrap();
trace!("replacing {} with {}", temp, machine_reg);
cf.mc_mut().replace_reg(temp, machine_reg);
cf.temps.insert(temp, machine_reg);
}
}
cf.mc().trace_mc();
Ok(())
}
}
......
......@@ -23,6 +23,10 @@ impl<K: Hash + Eq> LinkedHashSet<K> {
ret
}
pub fn clear(&mut self) {
self.0.clear();
}
}
impl<K: Hash + Eq, S: BuildHasher> LinkedHashSet<K, S> {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment