Commit dd776b84 authored by qinsoon's avatar qinsoon

[wip] simplify (untested). added utils mod for some vec operations

parent 19c5b2c0
......@@ -4,9 +4,8 @@ use compiler::backend::reg_alloc::liveness::{Node, Move};
use vm::machine_code::CompiledFunction;
use compiler::backend;
use compiler::backend::reg_alloc::liveness::find_value;
use utils::vec_utils;
use std::collections::LinkedList;
use std::collections::HashSet;
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
......@@ -20,16 +19,19 @@ pub struct GraphColoring <'a> {
precolored: HashSet<Node>,
colors: HashSet<MuID>,
initial: LinkedList<Node>,
initial: Vec<Node>,
degree: HashMap<Node, usize>,
worklist_moves: LinkedList<Move>,
worklist_moves: Vec<Move>,
movelist: HashMap<Node, Vec<Move>>,
active_moves: HashSet<Move>,
coalesced_nodes: HashSet<Node>,
worklist_spill: LinkedList<Node>,
worklist_spill: Vec<Node>,
worklist_freeze: HashSet<Node>,
worklist_simplify: HashSet<Node>
worklist_simplify: HashSet<Node>,
select_stack: Vec<Node>
}
impl <'a> GraphColoring <'a> {
......@@ -41,16 +43,19 @@ impl <'a> GraphColoring <'a> {
precolored: HashSet::new(),
colors: HashSet::new(),
initial: LinkedList::new(),
initial: Vec::new(),
degree: HashMap::new(),
worklist_moves: LinkedList::new(),
worklist_moves: Vec::new(),
movelist: HashMap::new(),
active_moves: HashSet::new(),
coalesced_nodes: HashSet::new(),
worklist_spill: LinkedList::new(),
worklist_spill: Vec::new(),
worklist_freeze: HashSet::new(),
worklist_simplify: HashSet::new()
worklist_simplify: HashSet::new(),
select_stack: Vec::new()
};
coloring.init();
......@@ -69,7 +74,7 @@ impl <'a> GraphColoring <'a> {
for node in self.ig.nodes() {
if !self.ig.is_colored(node) {
self.initial.push_back(node);
self.initial.push(node);
self.degree.insert(node, self.ig.outdegree_of(node));
}
}
......@@ -97,32 +102,12 @@ impl <'a> GraphColoring <'a> {
self.assign_colors();
}
fn simplify(&mut self) {
unimplemented!()
}
fn coalesce(&mut self) {
unimplemented!()
}
fn freeze(&mut self) {
unimplemented!()
}
fn select_spill(&mut self) {
unimplemented!()
}
fn assign_colors(&mut self) {
unimplemented!()
}
fn build(&mut self) {
if COALESCING.load(Ordering::Relaxed) {
let ref ig = self.ig;
let ref mut movelist = self.movelist;
for m in ig.moves() {
self.worklist_moves.push_back(m.clone());
self.worklist_moves.push(m.clone());
GraphColoring::movelist_mut(movelist, m.from).push(m.clone());
GraphColoring::movelist_mut(movelist, m.to).push(m.clone());
}
......@@ -131,16 +116,16 @@ impl <'a> GraphColoring <'a> {
fn make_work_list(&mut self) {
while !self.initial.is_empty() {
let node = self.initial.pop_front().unwrap();
let node = self.initial.pop().unwrap();
if {
// condition: degree >= K
let degree = self.ig.degree_of(node);
let n_regs = backend::number_of_regs_in_group(self.ig.get_group_of(node));
let n_regs = self.n_regs_for_node(node);
degree >= n_regs
} {
self.worklist_spill.push_back(node);
self.worklist_spill.push(node);
} else if self.is_move_related(node) {
self.worklist_freeze.insert(node);
} else {
......@@ -149,6 +134,10 @@ impl <'a> GraphColoring <'a> {
}
}
fn n_regs_for_node(&self, node: Node) -> usize {
backend::number_of_regs_in_group(self.ig.get_group_of(node))
}
fn is_move_related(&mut self, node: Node) -> bool {
!self.node_moves(node).is_empty()
}
......@@ -169,7 +158,7 @@ impl <'a> GraphColoring <'a> {
let mut retained = HashSet::new();
let movelist = GraphColoring::movelist_mut(&mut self.movelist, node);
for m in moves.iter() {
if find_value(movelist, *m).is_some() {
if vec_utils::find_value(movelist, *m).is_some() {
retained.insert(*m);
}
}
......@@ -184,4 +173,92 @@ impl <'a> GraphColoring <'a> {
list.get_mut(&node).unwrap()
}
fn simplify(&mut self) {
// remove next element from worklist_simplify
let node = {
let next = self.worklist_simplify.iter().next().unwrap().clone();
self.worklist_simplify.take(&next).unwrap()
};
self.select_stack.push(node);
for m in self.adjacent(node) {
self.decrement_degree(m);
}
}
fn adjacent(&mut self, n: Node) -> HashSet<Node> {
let mut adj = HashSet::new();
// add n's successors
for s in self.ig.outedges_of(n) {
adj.insert(s);
}
// removeAll(select_stack)
for s in self.select_stack.iter() {
adj.remove(s);
}
// removeAll(coalesced_nodes)
for s in self.coalesced_nodes.iter() {
adj.remove(s);
}
adj
}
fn degree(&self, n: Node) -> usize {
match self.degree.get(&n) {
Some(d) => *d,
None => 0
}
}
fn decrement_degree(&mut self, n: Node) {
let d = self.degree(n);
self.degree.insert(n, d - 1);
if d == self.n_regs_for_node(n) {
let mut nodes = self.adjacent(n);
nodes.insert(n);
self.enable_moves(nodes);
vec_utils::remove_value(&mut self.worklist_spill, n);
if self.is_move_related(n) {
self.worklist_freeze.insert(n);
} else {
self.worklist_simplify.insert(n);
}
}
}
fn enable_moves(&mut self, nodes: HashSet<Node>) {
for n in nodes {
for mov in self.node_moves(n) {
if self.active_moves.contains(&mov) {
self.active_moves.insert(mov);
self.worklist_moves.push(mov);
}
}
}
}
fn coalesce(&mut self) {
unimplemented!()
}
fn freeze(&mut self) {
unimplemented!()
}
fn select_spill(&mut self) {
unimplemented!()
}
fn assign_colors(&mut self) {
unimplemented!()
}
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ use vm::machine_code::MachineCode;
use ast::ir::*;
use ast::types;
use compiler::backend;
use utils::vec_utils;
use std::collections::LinkedList;
use std::collections::{HashMap, HashSet};
......@@ -138,6 +139,19 @@ impl InterferenceGraph {
matrix[(from.0, to.0)] || matrix[(to.0, from.0)]
}
pub fn outedges_of(&self, node: Node) -> Vec<Node> {
let mut ret = vec![];
let matrix = self.matrix.as_ref().unwrap();
for i in 0..self.nodes.len() {
if matrix[(node.0, i)] {
ret.push(Node(i));
}
}
ret
}
pub fn outdegree_of(&self, node: Node) -> usize {
let mut count = 0;
for i in 0..self.nodes.len() {
......@@ -267,13 +281,13 @@ pub fn build (cf: &CompiledFunction, func: &MuFunction) -> InterferenceGraph {
// out = union(in[succ]) for all succs
for succ in cf.mc.get_succs(n) {
// trace!("add successor's livein {:?} to #{}", &live_in[*succ], n);
add_all(out_set, &live_in[*succ]);
vec_utils::add_all(out_set, &live_in[*succ]);
}
// in = use(i.e. live_in) + (out - def)
let mut diff = out_set.clone();
for def in cf.mc.get_inst_reg_defines(n) {
remove_value(&mut diff, *def);
vec_utils::remove_value(&mut diff, *def);
// trace!("removing def: {}", *def);
// trace!("diff = {:?}", diff);
}
......@@ -282,7 +296,7 @@ pub fn build (cf: &CompiledFunction, func: &MuFunction) -> InterferenceGraph {
if !diff.is_empty() {
let ref mut in_set = live_in[n];
if add_all(in_set, &diff) {
if vec_utils::add_all(in_set, &diff) {
for p in cf.mc.get_preds(n) {
work_list.push_front(*p);
}
......@@ -346,7 +360,7 @@ pub fn build (cf: &CompiledFunction, func: &MuFunction) -> InterferenceGraph {
}
for d in cf.mc.get_inst_reg_defines(n) {
remove_value(live, *d);
vec_utils::remove_value(live, *d);
}
for u in cf.mc.get_inst_reg_uses(n) {
......@@ -355,34 +369,4 @@ pub fn build (cf: &CompiledFunction, func: &MuFunction) -> InterferenceGraph {
}
ig
}
fn add_all<T: Copy + PartialEq> (vec: &mut Vec<T>, vec2: &Vec<T>) -> bool {
let mut is_changed = false;
for i in vec2.iter() {
if !vec.contains(i) {
vec.push(*i);
is_changed = true;
}
}
is_changed
}
pub fn find_value<T: PartialEq> (vec: &Vec<T>, val: T) -> Option<usize> {
for i in 0..vec.len() {
if vec[i] == val {
return Some(i);
}
}
None
}
fn remove_value<T: PartialEq> (vec: &mut Vec<T>, val: T) {
match find_value(vec, val) {
Some(index) => {vec.remove(index);},
None => {} // do nothing
}
}
\ No newline at end of file
......@@ -9,6 +9,7 @@ mod common;
pub mod ast;
pub mod vm;
pub mod compiler;
mod utils;
#[allow(dead_code)]
fn main() {
......
// This porvides some missing operations on Vec.
// They are not included in the standard libarary.
// (because they are likely inefficient?)
pub mod vec_utils {
pub fn add_all<T: Copy + PartialEq> (vec: &mut Vec<T>, vec2: &Vec<T>) -> bool {
let mut is_changed = false;
for i in vec2.iter() {
if !vec.contains(i) {
vec.push(*i);
is_changed = true;
}
}
is_changed
}
pub fn find_value<T: PartialEq> (vec: &Vec<T>, val: T) -> Option<usize> {
for i in 0..vec.len() {
if vec[i] == val {
return Some(i);
}
}
None
}
pub fn remove_value<T: PartialEq> (vec: &mut Vec<T>, val: T) {
match find_value(vec, val) {
Some(index) => {vec.remove(index);},
None => {} // do nothing
}
}
}
\ 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