Commit c6054d60 authored by qinsoon's avatar qinsoon

[wip] all code for reg alloc is done. Start debugging

parent 70efc1ec
......@@ -228,6 +228,14 @@ pub fn all_regs() -> &'static Vec<P<Value>> {
&ALL_MACHINE_REGs
}
pub fn pick_group_for_reg(reg_id: MuID) -> RegGroup {
match reg_id {
0...15 => RegGroup::GPR,
16...31 => RegGroup::FPR,
_ => panic!("expected a machine reg ID, got {}", reg_id)
}
}
pub fn is_valid_x86_imm(op: &P<Value>) -> bool {
use std::u32;
match op.v {
......
......@@ -17,6 +17,8 @@ pub use compiler::backend::x86_64::number_of_regs_in_group;
pub use compiler::backend::x86_64::number_of_all_regs;
#[cfg(target_arch = "x86_64")]
pub use compiler::backend::x86_64::all_regs;
#[cfg(target_arch = "x86_64")]
pub use compiler::backend::x86_64::pick_group_for_reg;
#[cfg(target_arch = "arm")]
#[path = "arch/arm/mod.rs"]
......
......@@ -5,6 +5,7 @@ use vm::machine_code::CompiledFunction;
use compiler::backend;
use utils::vec_utils;
use utils::hashset_utils;
use std::cell::RefCell;
use std::collections::HashSet;
......@@ -18,7 +19,8 @@ pub struct GraphColoring <'a> {
cur_cf: &'a CompiledFunction,
precolored: HashSet<Node>,
colors: HashSet<MuID>,
colors: HashMap<backend::RegGroup, HashSet<MuID>>,
colored_nodes: Vec<Node>,
initial: Vec<Node>,
degree: HashMap<Node, usize>,
......@@ -31,6 +33,9 @@ pub struct GraphColoring <'a> {
alias: HashMap<Node, Node>,
worklist_spill: Vec<Node>,
spillable: HashMap<MuID, bool>,
spilled_nodes: Vec<Node>,
worklist_freeze: HashSet<Node>,
frozen_moves: HashSet<Move>,
......@@ -39,13 +44,19 @@ pub struct GraphColoring <'a> {
}
impl <'a> GraphColoring <'a> {
pub fn start (cf: &CompiledFunction, ig: InterferenceGraph) {
pub fn start (cf: &CompiledFunction, ig: InterferenceGraph) -> GraphColoring {
let mut coloring = GraphColoring {
ig: ig,
cur_cf: cf,
precolored: HashSet::new(),
colors: HashSet::new(),
colors: {
let mut map = HashMap::new();
map.insert(backend::RegGroup::GPR, HashSet::new());
map.insert(backend::RegGroup::FPR, HashSet::new());
map
},
colored_nodes: Vec::new(),
initial: Vec::new(),
degree: HashMap::new(),
......@@ -58,6 +69,9 @@ impl <'a> GraphColoring <'a> {
alias: HashMap::new(),
worklist_spill: Vec::new(),
spillable: HashMap::new(),
spilled_nodes: Vec::new(),
worklist_freeze: HashSet::new(),
frozen_moves: HashSet::new(),
......@@ -66,6 +80,8 @@ impl <'a> GraphColoring <'a> {
};
coloring.init();
coloring
}
fn init (&mut self) {
......@@ -76,7 +92,10 @@ impl <'a> GraphColoring <'a> {
let node = self.ig.get_node(reg_id);
self.precolored.insert(node);
self.colors.insert(reg_id);
{
let group = backend::pick_group_for_reg(reg_id);
self.colors.get_mut(&group).unwrap().insert(reg_id);
}
}
for node in self.ig.nodes() {
......@@ -443,10 +462,78 @@ impl <'a> GraphColoring <'a> {
}
fn select_spill(&mut self) {
unimplemented!()
let mut m : Option<Node> = None;
for n in self.worklist_spill.iter() {
let n = *n;
if m.is_none() {
m = Some(n);
} else if {
// m is not none
let temp = self.ig.get_temp_of(m.unwrap());
let spillable = {match self.spillable.get(&temp) {
None => {
//by default, its spillable
true
},
Some(b) => *b
}};
!spillable
} {
m = Some(n);
} else if (self.ig.get_spill_cost(n) / (self.degree(n) as f32))
< (self.ig.get_spill_cost(m.unwrap()) / (self.degree(m.unwrap()) as f32)) {
m = Some(n);
}
}
// m is not none
let m = m.unwrap();
vec_utils::remove_value(&mut self.worklist_spill, m);
self.worklist_simplify.insert(m);
self.freeze_moves(m);
}
fn assign_colors(&mut self) {
unimplemented!()
while !self.select_stack.is_empty() {
let n = self.select_stack.pop().unwrap();
let mut ok_colors = self.colors.get(&self.ig.get_group_of(n)).unwrap().clone();
for w in self.ig.outedges_of(n) {
let w = self.get_alias(w);
match self.ig.get_color_of(w) {
None => {}, // do nothing
Some(color) => {ok_colors.remove(&color);}
}
}
if ok_colors.is_empty() {
self.spilled_nodes.push(n);
} else {
self.colored_nodes.push(n);
self.ig.color_node(n, hashset_utils::pop_first(&mut ok_colors).unwrap());
}
}
for n in self.coalesced_nodes.iter() {
let n = *n;
let alias = self.get_alias(n);
let alias_color = self.ig.get_color_of(alias).unwrap();
self.ig.color_node(n, alias_color);
}
}
pub fn spills(&self) -> Vec<MuID> {
let mut spills = vec![];
let spill_count = self.spilled_nodes.len();
if spill_count > 0 {
for n in self.spilled_nodes.iter() {
spills.push(self.ig.get_temp_of(*n));
}
}
spills
}
}
\ No newline at end of file
......@@ -14,10 +14,12 @@ use self::nalgebra::DMatrix;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Node(usize);
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq)]
pub struct NodeProperty {
color: Option<MuID>,
group: backend::RegGroup
group: backend::RegGroup,
temp: MuID,
spill_cost: f32
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Move{pub from: Node, pub to: Node}
......@@ -66,14 +68,21 @@ impl InterferenceGraph {
};
let property = NodeProperty {
color: None,
group: group
group: group,
temp: reg_id,
spill_cost: 0.0f32
};
self.nodes_property.insert(node, property);
node
} else {
* self.nodes.get(&reg_id).unwrap()
}
}
let node = * self.nodes.get(&reg_id).unwrap();
// increase node spill cost
let property = self.nodes_property.get_mut(&node).unwrap();
property.spill_cost += 1.0f32;
node
}
pub fn get_node(&self, reg: MuID) -> Node {
......@@ -117,7 +126,7 @@ impl InterferenceGraph {
}
}
fn color_node(&mut self, node: Node, color: MuID) {
pub fn color_node(&mut self, node: Node, color: MuID) {
self.nodes_property.get_mut(&node).unwrap().color = Some(color);
}
......@@ -125,10 +134,22 @@ impl InterferenceGraph {
self.nodes_property.get(&node).unwrap().color.is_some()
}
pub fn get_color_of(&self, node: Node) -> Option<MuID> {
self.nodes_property.get(&node).unwrap().color
}
pub fn get_group_of(&self, node: Node) -> backend::RegGroup {
self.nodes_property.get(&node).unwrap().group
}
pub fn get_temp_of(&self, node: Node) -> MuID {
self.nodes_property.get(&node).unwrap().temp
}
pub fn get_spill_cost(&self, node: Node) -> f32 {
self.nodes_property.get(&node).unwrap().spill_cost
}
fn is_same_node(&self, node1: Node, node2: Node) -> bool {
node1 == node2
}
......
......@@ -39,6 +39,7 @@ impl CompilerPass for RegisterAllocation {
let liveness = liveness::build(&mut cf, func);
liveness.print();
coloring::GraphColoring::start(&mut cf, liveness);
let coloring = coloring::GraphColoring::start(&mut cf, liveness);
let spills = coloring.spills();
}
}
\ No newline at end of file
......@@ -31,4 +31,18 @@ pub mod vec_utils {
None => {} // do nothing
}
}
}
pub mod hashset_utils {
use std::collections::HashSet;
use std::hash::Hash;
pub fn pop_first<T: Eq + Hash + Copy> (set: &mut HashSet<T>) -> Option<T> {
if set.is_empty() {
None
} else {
let next : T = set.iter().next().unwrap().clone();
set.take(&next)
}
}
}
\ No newline at end of file
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