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 cfac6aa6 authored by qinsoon's avatar qinsoon
Browse files

improve freeze heuristics: prioritize freezing nodes that are less

involved in moves (taking loop depth into consideration)
parent 4e03378e
......@@ -454,6 +454,43 @@ impl<'a> GraphColoring<'a> {
} else {
trace!("Coalescing disabled...");
}
trace!("Build freeze cost for each node...");
// we try to avoid freeze a node that is involved in many moves
for n in self.ig.nodes() {
// freeze_cost(n) = SUM ((spill_cost(src) + spill_cost(dst)) for m (mov src->dst)
// in movelist[n])
let closure = {
let mut ret = LinkedHashSet::new();
let mut worklist = LinkedHashSet::new();
worklist.insert(n);
while !worklist.is_empty() {
let n = worklist.pop_front().unwrap();
for m in self.get_movelist(n).iter() {
if !ret.contains(&m.from) {
ret.insert(m.from);
worklist.insert(m.from);
}
if !ret.contains(&m.to) {
ret.insert(m.to);
worklist.insert(m.to);
}
}
}
ret
};
let mut freeze_cost = 0f32;
for related_node in closure.iter() {
freeze_cost += self.ig.get_spill_cost(*related_node);
}
self.ig.set_freeze_cost(n, freeze_cost);
trace!(" {} closure: {:?}", n, closure);
trace!(" freeze cost = {}", freeze_cost);
}
}
fn make_work_list(&mut self) {
......@@ -836,13 +873,7 @@ impl<'a> GraphColoring<'a> {
let mut candidate = None;
let mut candidate_cost = f32::MAX;
for &n in self.worklist_freeze.iter() {
// freeze_cost(n) = SUM ((spill_cost(src) + spill_cost(dst)) for m (mov src->dst)
// in movelist[n])
let mut freeze_cost = 0f32;
for m in self.get_movelist(n).iter() {
freeze_cost += self.ig.get_spill_cost(m.from);
freeze_cost += self.ig.get_spill_cost(m.to);
}
let freeze_cost = self.ig.get_freeze_cost(n);
if freeze_cost < candidate_cost {
candidate = Some(n);
......
......@@ -39,7 +39,9 @@ pub struct Node {
/// temp register group (which machine register class we should assign)
group: backend::RegGroup,
/// cost to spill this temp
spill_cost: f32
spill_cost: f32,
/// cost to freeze this temp
freeze_cost: f32
}
impl fmt::Debug for Node {
......@@ -143,7 +145,8 @@ impl InterferenceGraph {
temp: reg_id,
color: None,
group: backend::RegGroup::get_from_ty(entry.ty()),
spill_cost: 0.0f32
spill_cost: 0.0f32,
freeze_cost: 0f32
};
self.nodes.insert(reg_id, node);
......@@ -284,6 +287,16 @@ impl InterferenceGraph {
self.nodes.get(&reg).unwrap().spill_cost
}
/// sets the freeze cost of a node
pub fn set_freeze_cost(&mut self, reg: MuID, cost: f32) {
self.nodes.get_mut(&reg).unwrap().freeze_cost = cost;
}
/// gets the freeze cost of a node
pub fn get_freeze_cost(&self, reg: MuID) -> f32 {
self.nodes.get(&reg).unwrap().freeze_cost
}
/// are two nodes the same node?
fn is_same_node(&self, reg1: MuID, reg2: MuID) -> bool {
reg1 == reg2
......
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