GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

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