WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit c6054d60 authored by qinsoon's avatar qinsoon
Browse files

[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