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 87048244 authored by qinsoon's avatar qinsoon

more work on register allocation (currently some debug output from it, I

should remove it later)
parent 970bbb22
Pipeline #1154 failed with stages
in 25 minutes and 35 seconds
......@@ -21,15 +21,10 @@ use compiler::backend::reg_alloc::graph_coloring;
use compiler::backend::reg_alloc::graph_coloring::liveness::InterferenceGraph;
use compiler::machine_code::CompiledFunction;
use vm::VM;
use utils::vec_utils;
use utils::LinkedHashSet;
use utils::LinkedHashMap;
use std::cell::RefCell;
use compiler::backend::reg_alloc::graph_coloring::liveness::Move;
use compiler::backend::reg_alloc::graph_coloring::petgraph::graph::NodeIndex;
const COALESCING: bool = true;
const MAX_REWRITE_ITERATIONS_ALLOWED: usize = 10;
......@@ -523,9 +518,11 @@ impl<'a> GraphColoring<'a> {
if !precolored_v {
self.add_worklist(v);
}
} else if (precolored_u && self.ok(u, v)) || (!precolored_u && self.conservative(u, v)) {
trace!("ok(u, v) = {}", self.ok(u, v));
trace!("conservative(u, v) = {}", self.conservative(u, v));
} else if (precolored_u && self.check_ok(u, v)) ||
(!precolored_u && self.check_conservative(u, v))
{
trace!("ok(u, v) = {}", self.check_ok(u, v));
trace!("conservative(u, v) = {}", self.check_conservative(u, v));
trace!(
"precolored_u&&ok(u,v) || !precolored_u&&conserv(u,v), \
......@@ -557,12 +554,11 @@ impl<'a> GraphColoring<'a> {
}
}
fn ok(&self, u: MuID, v: MuID) -> bool {
fn check_ok(&self, u: MuID, v: MuID) -> bool {
debug!("LIN: check_ok(): {} {}", u, v);
for t in self.adjacent(v).iter() {
let t = *t;
if !(self.ig.get_degree_of(t) < self.n_regs_for_node(t) ||
self.precolored.contains(&t) || self.ig.is_in_adj_set(t, u))
{
if !self.ok(t, u) {
return false;
}
}
......@@ -570,7 +566,21 @@ impl<'a> GraphColoring<'a> {
true
}
fn conservative(&self, u: MuID, v: MuID) -> bool {
fn ok(&self, t: MuID, r: MuID) -> bool {
debug!("LIN: ok(t:{}, r:{})", t, r);
let degree_t = self.ig.get_degree_of(t);
let k = self.n_regs_for_node(t);
debug!("LIN: degree[t] = {}, K = {}", degree_t, k);
debug!("LIN: precolored(t) = {}", self.precolored.contains(&t));
debug!("LIN: adj(t, r) = {}", self.ig.is_in_adj_set(t, r));
degree_t < k || self.precolored.contains(&t) || self.ig.is_in_adj_set(t, r)
}
fn check_conservative(&self, u: MuID, v: MuID) -> bool {
debug!("LIN: check_conservative(): {}, {}", u, v);
let adj_u = self.adjacent(u);
let adj_v = self.adjacent(v);
let nodes = {
......@@ -579,16 +589,28 @@ impl<'a> GraphColoring<'a> {
ret
};
let n_reg_for_group = self.n_regs_for_node(u);
let n_regs_for_group = self.n_regs_for_node(u);
self.conservative(nodes, n_regs_for_group)
}
fn conservative(&self, nodes: LinkedHashSet<MuID>, n_regs_for_group: usize) -> bool {
debug!("LIN: conservative({:?}, K={})", nodes, n_regs_for_group);
let mut k = 0;
for n in nodes.iter() {
if self.precolored.contains(n) || self.ig.get_degree_of(*n) >= n_reg_for_group {
// TODO: do we check if n is precolored?
debug!(
"LIN: degree(n) = {}, K = {}",
self.ig.get_degree_of(*n),
n_regs_for_group
);
debug!("LIN: is_precolored(n) = {}", self.precolored.contains(n));
if self.precolored.contains(n) || self.ig.get_degree_of(*n) >= n_regs_for_group {
debug!("LIN: k++");
k += 1;
}
}
k < n_reg_for_group
debug!("LIN: k={}, K={}", k, n_regs_for_group);
k < n_regs_for_group
}
fn combine(&mut self, u: MuID, v: MuID) {
......
......@@ -50,6 +50,15 @@ fn is_precolored(reg: MuID) -> bool {
}
}
#[inline(always)]
fn is_usable(reg: MuID) -> bool {
if backend::all_usable_regs().iter().any(|x| x.id() == reg) {
true
} else {
false
}
}
/// InterferenceGraph represents the interference graph, including
/// * the graph
/// * all the nodes and its NodeIndex (a node is referred to by NodeIndex)
......@@ -136,14 +145,31 @@ impl InterferenceGraph {
/// adds an interference edge between two nodes
pub fn add_edge(&mut self, u: MuID, v: MuID) {
// // adds edge to the internal graph
// self.graph.update_edge(from, to, ());
// if one of the node is machine register, we also add
// interference edge to its alias
// e.g. if we have %a - %edi interfered,
// we also add %a - %rdi interference
let u = if is_precolored(u) {
if is_usable(u) {
backend::get_color_for_precolored(u)
} else {
// if it is not usable, we do not need to add an interference edge
return;
}
} else {
u
};
let v = if is_precolored(v) {
if is_usable(v) {
backend::get_color_for_precolored(v)
} else {
return;
}
} else {
v
};
if !self.adj_set.contains(&(u, v)) && u != v {
self.adj_set.insert((u, v));
self.adj_set.insert((v, u));
......@@ -227,7 +253,19 @@ impl InterferenceGraph {
trace!("");
trace!("Interference Graph");
trace!("not available");
trace!("nodes: ");
for n in self.nodes.values() {
trace!("{:?}", n);
}
trace!("edges: ");
for id in self.nodes.keys() {
trace!("edges for {} ({}): ", id, self.degree.get(id).unwrap());
for neighbour in self.get_adj_list(*id).iter() {
trace!("{}", neighbour)
}
}
}
}
......
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