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.

Commit eeaecb3f authored by qinsoon's avatar qinsoon
Browse files

Replacing HashSet with LinkedHashSet so that results from regalloc are fixed

parent 30a6d074
...@@ -8,4 +8,5 @@ authors = [ "Your name <you@example.com>" ] ...@@ -8,4 +8,5 @@ authors = [ "Your name <you@example.com>" ]
lazy_static = "0.1.15" lazy_static = "0.1.15"
log = "0.3.5" log = "0.3.5"
simple_logger = "0.4.0" simple_logger = "0.4.0"
nalgebra = "0.8.2" nalgebra = "0.8.2"
\ No newline at end of file linked-hash-map = "0.0.10"
\ No newline at end of file
...@@ -5,10 +5,9 @@ use vm::machine_code::CompiledFunction; ...@@ -5,10 +5,9 @@ use vm::machine_code::CompiledFunction;
use compiler::backend; use compiler::backend;
use utils::vec_utils; use utils::vec_utils;
use utils::hashset_utils; use utils::LinkedHashSet;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashSet;
use std::collections::HashMap; use std::collections::HashMap;
const COALESCING : bool = true; const COALESCING : bool = true;
...@@ -16,8 +15,8 @@ const COALESCING : bool = true; ...@@ -16,8 +15,8 @@ const COALESCING : bool = true;
pub struct GraphColoring { pub struct GraphColoring {
pub ig: InterferenceGraph, pub ig: InterferenceGraph,
precolored: HashSet<Node>, precolored: LinkedHashSet<Node>,
colors: HashMap<backend::RegGroup, HashSet<MuID>>, colors: HashMap<backend::RegGroup, LinkedHashSet<MuID>>,
pub colored_nodes: Vec<Node>, pub colored_nodes: Vec<Node>,
initial: Vec<Node>, initial: Vec<Node>,
...@@ -25,20 +24,20 @@ pub struct GraphColoring { ...@@ -25,20 +24,20 @@ pub struct GraphColoring {
worklist_moves: Vec<Move>, worklist_moves: Vec<Move>,
movelist: HashMap<Node, RefCell<Vec<Move>>>, movelist: HashMap<Node, RefCell<Vec<Move>>>,
active_moves: HashSet<Move>, active_moves: LinkedHashSet<Move>,
coalesced_nodes: HashSet<Node>, coalesced_nodes: LinkedHashSet<Node>,
coalesced_moves: HashSet<Move>, coalesced_moves: LinkedHashSet<Move>,
constrained_moves: HashSet<Move>, constrained_moves: LinkedHashSet<Move>,
alias: HashMap<Node, Node>, alias: HashMap<Node, Node>,
worklist_spill: Vec<Node>, worklist_spill: Vec<Node>,
spillable: HashMap<MuID, bool>, spillable: HashMap<MuID, bool>,
spilled_nodes: Vec<Node>, spilled_nodes: Vec<Node>,
worklist_freeze: HashSet<Node>, worklist_freeze: LinkedHashSet<Node>,
frozen_moves: HashSet<Move>, frozen_moves: LinkedHashSet<Move>,
worklist_simplify: HashSet<Node>, worklist_simplify: LinkedHashSet<Node>,
select_stack: Vec<Node> select_stack: Vec<Node>
} }
...@@ -47,11 +46,11 @@ impl GraphColoring { ...@@ -47,11 +46,11 @@ impl GraphColoring {
let mut coloring = GraphColoring { let mut coloring = GraphColoring {
ig: ig, ig: ig,
precolored: HashSet::new(), precolored: LinkedHashSet::new(),
colors: { colors: {
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert(backend::RegGroup::GPR, HashSet::new()); map.insert(backend::RegGroup::GPR, LinkedHashSet::new());
map.insert(backend::RegGroup::FPR, HashSet::new()); map.insert(backend::RegGroup::FPR, LinkedHashSet::new());
map map
}, },
colored_nodes: Vec::new(), colored_nodes: Vec::new(),
...@@ -61,20 +60,20 @@ impl GraphColoring { ...@@ -61,20 +60,20 @@ impl GraphColoring {
worklist_moves: Vec::new(), worklist_moves: Vec::new(),
movelist: HashMap::new(), movelist: HashMap::new(),
active_moves: HashSet::new(), active_moves: LinkedHashSet::new(),
coalesced_nodes: HashSet::new(), coalesced_nodes: LinkedHashSet::new(),
coalesced_moves: HashSet::new(), coalesced_moves: LinkedHashSet::new(),
constrained_moves: HashSet::new(), constrained_moves: LinkedHashSet::new(),
alias: HashMap::new(), alias: HashMap::new(),
worklist_spill: Vec::new(), worklist_spill: Vec::new(),
spillable: HashMap::new(), spillable: HashMap::new(),
spilled_nodes: Vec::new(), spilled_nodes: Vec::new(),
worklist_freeze: HashSet::new(), worklist_freeze: LinkedHashSet::new(),
frozen_moves: HashSet::new(), frozen_moves: LinkedHashSet::new(),
worklist_simplify: HashSet::new(), worklist_simplify: LinkedHashSet::new(),
select_stack: Vec::new() select_stack: Vec::new()
}; };
...@@ -178,8 +177,8 @@ impl GraphColoring { ...@@ -178,8 +177,8 @@ impl GraphColoring {
!self.node_moves(node).is_empty() !self.node_moves(node).is_empty()
} }
fn node_moves(&mut self, node: Node) -> HashSet<Move> { fn node_moves(&mut self, node: Node) -> LinkedHashSet<Move> {
let mut moves = HashSet::new(); let mut moves = LinkedHashSet::new();
// addAll(active_moves) // addAll(active_moves)
for m in self.active_moves.iter() { for m in self.active_moves.iter() {
...@@ -191,7 +190,7 @@ impl GraphColoring { ...@@ -191,7 +190,7 @@ impl GraphColoring {
moves.insert(m.clone()); moves.insert(m.clone());
} }
let mut retained = HashSet::new(); let mut retained = LinkedHashSet::new();
let movelist = &GraphColoring::movelist_mut(&mut self.movelist, node).borrow(); let movelist = &GraphColoring::movelist_mut(&mut self.movelist, node).borrow();
for m in moves.iter() { for m in moves.iter() {
if vec_utils::find_value(movelist, *m).is_some() { if vec_utils::find_value(movelist, *m).is_some() {
...@@ -223,20 +222,21 @@ impl GraphColoring { ...@@ -223,20 +222,21 @@ impl GraphColoring {
fn simplify(&mut self) { fn simplify(&mut self) {
// remove next element from worklist_simplify, we know its not empty // remove next element from worklist_simplify, we know its not empty
let node = hashset_utils::pop_first(&mut self.worklist_simplify).unwrap(); let node = self.worklist_simplify.pop_front().unwrap();
trace!("Simplifying {}", self.node_info(node)); trace!("Simplifying {}", self.node_info(node));
self.select_stack.push(node); self.select_stack.push(node);
for m in self.adjacent(node) { for m in self.adjacent(node).iter() {
let m = *m;
trace!("decrement degree of its adjacent node {}", self.node_info(m)); trace!("decrement degree of its adjacent node {}", self.node_info(m));
self.decrement_degree(m); self.decrement_degree(m);
} }
} }
fn adjacent(&self, n: Node) -> HashSet<Node> { fn adjacent(&self, n: Node) -> LinkedHashSet<Node> {
let mut adj = HashSet::new(); let mut adj = LinkedHashSet::new();
// add n's successors // add n's successors
for s in self.ig.outedges_of(n) { for s in self.ig.outedges_of(n) {
...@@ -286,9 +286,11 @@ impl GraphColoring { ...@@ -286,9 +286,11 @@ impl GraphColoring {
} }
} }
fn enable_moves(&mut self, nodes: HashSet<Node>) { fn enable_moves(&mut self, nodes: LinkedHashSet<Node>) {
for n in nodes { for n in nodes.iter() {
for mov in self.node_moves(n) { let n = *n;
for mov in self.node_moves(n).iter() {
let mov = *mov;
if self.active_moves.contains(&mov) { if self.active_moves.contains(&mov) {
self.active_moves.insert(mov); self.active_moves.insert(mov);
self.worklist_moves.push(mov); self.worklist_moves.push(mov);
...@@ -373,7 +375,8 @@ impl GraphColoring { ...@@ -373,7 +375,8 @@ impl GraphColoring {
} }
fn ok(&self, u: Node, v: Node) -> bool { fn ok(&self, u: Node, v: Node) -> bool {
for t in self.adjacent(v) { for t in self.adjacent(v).iter() {
let t = *t;
if !self.precolored.contains(&t) if !self.precolored.contains(&t)
|| self.degree(t) < self.n_regs_for_node(t) as isize || self.degree(t) < self.n_regs_for_node(t) as isize
|| self.ig.is_adj(t, u) { || self.ig.is_adj(t, u) {
...@@ -389,10 +392,14 @@ impl GraphColoring { ...@@ -389,10 +392,14 @@ impl GraphColoring {
let adj_u = self.adjacent(u); let adj_u = self.adjacent(u);
let adj_v = self.adjacent(v); let adj_v = self.adjacent(v);
let nodes = adj_u.union(&adj_v).collect::<HashSet<_>>(); let nodes = {
let mut ret = adj_u;
ret.add_all(adj_v);
ret
};
let mut k = 0; let mut k = 0;
for n in nodes { for n in nodes.iter() {
if self.precolored.contains(n) || self.degree(*n) >= self.n_regs_for_node(*n) as isize { if self.precolored.contains(n) || self.degree(*n) >= self.n_regs_for_node(*n) as isize {
k += 1; k += 1;
} }
...@@ -426,11 +433,12 @@ impl GraphColoring { ...@@ -426,11 +433,12 @@ impl GraphColoring {
movelist_u.extend_from_slice(movelist_v.as_slice()); movelist_u.extend_from_slice(movelist_v.as_slice());
} }
let mut nodes = HashSet::new(); let mut nodes = LinkedHashSet::new();
nodes.insert(v); nodes.insert(v);
self.enable_moves(nodes); self.enable_moves(nodes);
for t in self.adjacent(v) { for t in self.adjacent(v).iter() {
let t = *t;
self.add_edge(t, u); self.add_edge(t, u);
self.decrement_degree(t); self.decrement_degree(t);
} }
...@@ -459,7 +467,7 @@ impl GraphColoring { ...@@ -459,7 +467,7 @@ impl GraphColoring {
fn freeze(&mut self) { fn freeze(&mut self) {
// it is not empty (checked before) // it is not empty (checked before)
let node = hashset_utils::pop_first(&mut self.worklist_freeze).unwrap(); let node = self.worklist_freeze.pop_front().unwrap();
trace!("Freezing {}...", self.node_info(node)); trace!("Freezing {}...", self.node_info(node));
self.worklist_simplify.insert(node); self.worklist_simplify.insert(node);
...@@ -467,7 +475,8 @@ impl GraphColoring { ...@@ -467,7 +475,8 @@ impl GraphColoring {
} }
fn freeze_moves(&mut self, u: Node) { fn freeze_moves(&mut self, u: Node) {
for m in self.node_moves(u) { for m in self.node_moves(u).iter() {
let m = *m;
let mut v = self.get_alias(m.from); let mut v = self.get_alias(m.from);
if v == self.get_alias(u) { if v == self.get_alias(u) {
v = self.get_alias(m.to); v = self.get_alias(m.to);
...@@ -528,7 +537,7 @@ impl GraphColoring { ...@@ -528,7 +537,7 @@ impl GraphColoring {
let n = self.select_stack.pop().unwrap(); let n = self.select_stack.pop().unwrap();
trace!("Assigning color to {}", self.node_info(n)); trace!("Assigning color to {}", self.node_info(n));
let mut ok_colors = self.colors.get(&self.ig.get_group_of(n)).unwrap().clone(); let mut ok_colors : LinkedHashSet<MuID> = self.colors.get(&self.ig.get_group_of(n)).unwrap().clone();
for w in self.ig.outedges_of(n) { for w in self.ig.outedges_of(n) {
let w = self.get_alias(w); let w = self.get_alias(w);
match self.ig.get_color_of(w) { match self.ig.get_color_of(w) {
...@@ -542,7 +551,7 @@ impl GraphColoring { ...@@ -542,7 +551,7 @@ impl GraphColoring {
trace!("{} is a spilled node", self.node_info(n)); trace!("{} is a spilled node", self.node_info(n));
self.spilled_nodes.push(n); self.spilled_nodes.push(n);
} else { } else {
let first_available_color = hashset_utils::pop_first(&mut ok_colors).unwrap(); let first_available_color = ok_colors.pop_front().unwrap();
trace!("Color {} as {}", self.node_info(n), first_available_color); trace!("Color {} as {}", self.node_info(n), first_available_color);
self.colored_nodes.push(n); self.colored_nodes.push(n);
self.ig.color_node(n, first_available_color); self.ig.color_node(n, first_available_color);
......
extern crate linked_hash_map;
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hash};
use std::borrow::Borrow;
use self::linked_hash_map::Keys;
pub use self::linked_hash_map::LinkedHashMap;
pub struct LinkedHashSet<K, S = RandomState>(LinkedHashMap<K, (), S>);
impl<K: Hash + Eq> LinkedHashSet<K> {
pub fn new() -> Self {
LinkedHashSet(LinkedHashMap::new())
}
}
impl<K: Hash + Eq, S: BuildHasher> LinkedHashSet<K, S> {
pub fn insert(&mut self, k: K) -> Option<()> {
self.0.insert(k, ())
}
pub fn contains<Q: ?Sized>(&self, k: &Q) -> bool
where K: Borrow<Q>,
Q: Eq + Hash
{
self.0.contains_key(k)
}
pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<()>
where K: Borrow<Q>,
Q: Eq + Hash
{
self.0.remove(k)
}
pub fn iter(&self) -> Keys<K, ()> {
self.0.keys()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn pop_front(&mut self) -> Option<K> {
match self.0.pop_front() {
Some((k, _)) => Some(k),
None => None
}
}
pub fn add_all(&mut self, mut other: Self) {
while !other.is_empty() {
let entry = other.pop_front().unwrap();
self.insert(entry);
}
}
}
impl<K: Hash + Eq + Clone> Clone for LinkedHashSet<K> {
fn clone(&self) -> Self {
LinkedHashSet(self.0.clone())
}
}
use std::fmt;
use std::fmt::DebugSet;
impl<A: fmt::Debug + Hash + Eq, S: BuildHasher> fmt::Debug for LinkedHashSet<A, S> {
/// Returns a string that lists the key-value pairs in insertion order.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
\ No newline at end of file
#![allow(dead_code)] #![allow(dead_code)]
mod linked_hashset;
pub use utils::linked_hashset::LinkedHashSet;
pub use utils::linked_hashset::LinkedHashMap;
// This porvides some missing operations on Vec. // This porvides some missing operations on Vec.
// They are not included in the standard libarary. // They are not included in the standard libarary.
// (because they are likely inefficient?) // (because they are likely inefficient?)
...@@ -35,20 +39,6 @@ pub mod vec_utils { ...@@ -35,20 +39,6 @@ pub mod vec_utils {
} }
} }
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)
}
}
}
pub mod string_utils { pub mod string_utils {
pub fn replace(s: &mut String, index: usize, replace: &String, replace_len: usize) { pub fn replace(s: &mut String, index: usize, replace: &String, replace_len: usize) {
let vec = unsafe {s.as_mut_vec()}; let vec = unsafe {s.as_mut_vec()};
......
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