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>" ]
lazy_static = "0.1.15"
log = "0.3.5"
simple_logger = "0.4.0"
nalgebra = "0.8.2"
\ No newline at end of file
nalgebra = "0.8.2"
linked-hash-map = "0.0.10"
\ No newline at end of file
......@@ -5,10 +5,9 @@ use vm::machine_code::CompiledFunction;
use compiler::backend;
use utils::vec_utils;
use utils::hashset_utils;
use utils::LinkedHashSet;
use std::cell::RefCell;
use std::collections::HashSet;
use std::collections::HashMap;
const COALESCING : bool = true;
......@@ -16,8 +15,8 @@ const COALESCING : bool = true;
pub struct GraphColoring {
pub ig: InterferenceGraph,
precolored: HashSet<Node>,
colors: HashMap<backend::RegGroup, HashSet<MuID>>,
precolored: LinkedHashSet<Node>,
colors: HashMap<backend::RegGroup, LinkedHashSet<MuID>>,
pub colored_nodes: Vec<Node>,
initial: Vec<Node>,
......@@ -25,20 +24,20 @@ pub struct GraphColoring {
worklist_moves: Vec<Move>,
movelist: HashMap<Node, RefCell<Vec<Move>>>,
active_moves: HashSet<Move>,
coalesced_nodes: HashSet<Node>,
coalesced_moves: HashSet<Move>,
constrained_moves: HashSet<Move>,
active_moves: LinkedHashSet<Move>,
coalesced_nodes: LinkedHashSet<Node>,
coalesced_moves: LinkedHashSet<Move>,
constrained_moves: LinkedHashSet<Move>,
alias: HashMap<Node, Node>,
worklist_spill: Vec<Node>,
spillable: HashMap<MuID, bool>,
spilled_nodes: Vec<Node>,
worklist_freeze: HashSet<Node>,
frozen_moves: HashSet<Move>,
worklist_freeze: LinkedHashSet<Node>,
frozen_moves: LinkedHashSet<Move>,
worklist_simplify: HashSet<Node>,
worklist_simplify: LinkedHashSet<Node>,
select_stack: Vec<Node>
}
......@@ -47,11 +46,11 @@ impl GraphColoring {
let mut coloring = GraphColoring {
ig: ig,
precolored: HashSet::new(),
precolored: LinkedHashSet::new(),
colors: {
let mut map = HashMap::new();
map.insert(backend::RegGroup::GPR, HashSet::new());
map.insert(backend::RegGroup::FPR, HashSet::new());
map.insert(backend::RegGroup::GPR, LinkedHashSet::new());
map.insert(backend::RegGroup::FPR, LinkedHashSet::new());
map
},
colored_nodes: Vec::new(),
......@@ -61,20 +60,20 @@ impl GraphColoring {
worklist_moves: Vec::new(),
movelist: HashMap::new(),
active_moves: HashSet::new(),
coalesced_nodes: HashSet::new(),
coalesced_moves: HashSet::new(),
constrained_moves: HashSet::new(),
active_moves: LinkedHashSet::new(),
coalesced_nodes: LinkedHashSet::new(),
coalesced_moves: LinkedHashSet::new(),
constrained_moves: LinkedHashSet::new(),
alias: HashMap::new(),
worklist_spill: Vec::new(),
spillable: HashMap::new(),
spilled_nodes: Vec::new(),
worklist_freeze: HashSet::new(),
frozen_moves: HashSet::new(),
worklist_freeze: LinkedHashSet::new(),
frozen_moves: LinkedHashSet::new(),
worklist_simplify: HashSet::new(),
worklist_simplify: LinkedHashSet::new(),
select_stack: Vec::new()
};
......@@ -178,8 +177,8 @@ impl GraphColoring {
!self.node_moves(node).is_empty()
}
fn node_moves(&mut self, node: Node) -> HashSet<Move> {
let mut moves = HashSet::new();
fn node_moves(&mut self, node: Node) -> LinkedHashSet<Move> {
let mut moves = LinkedHashSet::new();
// addAll(active_moves)
for m in self.active_moves.iter() {
......@@ -191,7 +190,7 @@ impl GraphColoring {
moves.insert(m.clone());
}
let mut retained = HashSet::new();
let mut retained = LinkedHashSet::new();
let movelist = &GraphColoring::movelist_mut(&mut self.movelist, node).borrow();
for m in moves.iter() {
if vec_utils::find_value(movelist, *m).is_some() {
......@@ -223,20 +222,21 @@ impl GraphColoring {
fn simplify(&mut self) {
// 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));
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));
self.decrement_degree(m);
}
}
fn adjacent(&self, n: Node) -> HashSet<Node> {
let mut adj = HashSet::new();
fn adjacent(&self, n: Node) -> LinkedHashSet<Node> {
let mut adj = LinkedHashSet::new();
// add n's successors
for s in self.ig.outedges_of(n) {
......@@ -286,9 +286,11 @@ impl GraphColoring {
}
}
fn enable_moves(&mut self, nodes: HashSet<Node>) {
for n in nodes {
for mov in self.node_moves(n) {
fn enable_moves(&mut self, nodes: LinkedHashSet<Node>) {
for n in nodes.iter() {
let n = *n;
for mov in self.node_moves(n).iter() {
let mov = *mov;
if self.active_moves.contains(&mov) {
self.active_moves.insert(mov);
self.worklist_moves.push(mov);
......@@ -373,7 +375,8 @@ impl GraphColoring {
}
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)
|| self.degree(t) < self.n_regs_for_node(t) as isize
|| self.ig.is_adj(t, u) {
......@@ -389,10 +392,14 @@ impl GraphColoring {
let adj_u = self.adjacent(u);
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;
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 {
k += 1;
}
......@@ -426,11 +433,12 @@ impl GraphColoring {
movelist_u.extend_from_slice(movelist_v.as_slice());
}
let mut nodes = HashSet::new();
let mut nodes = LinkedHashSet::new();
nodes.insert(v);
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.decrement_degree(t);
}
......@@ -459,7 +467,7 @@ impl GraphColoring {
fn freeze(&mut self) {
// 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));
self.worklist_simplify.insert(node);
......@@ -467,7 +475,8 @@ impl GraphColoring {
}
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);
if v == self.get_alias(u) {
v = self.get_alias(m.to);
......@@ -528,7 +537,7 @@ impl GraphColoring {
let n = self.select_stack.pop().unwrap();
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) {
let w = self.get_alias(w);
match self.ig.get_color_of(w) {
......@@ -542,7 +551,7 @@ impl GraphColoring {
trace!("{} is a spilled node", self.node_info(n));
self.spilled_nodes.push(n);
} 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);
self.colored_nodes.push(n);
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)]
mod linked_hashset;
pub use utils::linked_hashset::LinkedHashSet;
pub use utils::linked_hashset::LinkedHashMap;
// This porvides some missing operations on Vec.
// They are not included in the standard libarary.
// (because they are likely inefficient?)
......@@ -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 fn replace(s: &mut String, index: usize, replace: &String, replace_len: usize) {
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