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 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