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 5b23d615 authored by Yi Lin's avatar Yi Lin
Browse files

Merge branch 'freeze-fix' into 'master'

using a better freeze heuristics, and fix code for memmap crate (their API changed)

See merge request !54
parents 7f1c3933 be4e027c
......@@ -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);
......@@ -162,7 +165,7 @@ impl InterferenceGraph {
fn spillcost_heuristic(ty: NodeType, loop_depth: usize) -> f32 {
const DEF_WEIGHT: f32 = 1f32;
const USE_WEIGHT: f32 = 1f32;
const COPY_WEIGHT: f32 = 0.5f32;
const COPY_WEIGHT: f32 = 2f32;
let loop_depth = loop_depth as i32;
......@@ -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
......
......@@ -38,21 +38,19 @@ pub struct FreeListSpace {
pub trace_map: Arc<AddressMap<u8>>,
#[allow(dead_code)]
mmap: memmap::Mmap,
mmap: memmap::MmapMut,
treadmill: Mutex<Treadmill>
}
impl FreeListSpace {
pub fn new(space_size: usize) -> FreeListSpace {
let anon_mmap: memmap::Mmap = match memmap::Mmap::anonymous(
space_size + SPACE_ALIGN,
memmap::Protection::ReadWrite
) {
Ok(m) => m,
Err(_) => panic!("failed to call mmap")
};
let start: Address = Address::from_ptr::<u8>(anon_mmap.ptr()).align_up(SPACE_ALIGN);
let mut anon_mmap: memmap::MmapMut =
match memmap::MmapMut::map_anon(space_size + SPACE_ALIGN) {
Ok(m) => m,
Err(_) => panic!("failed to call mmap")
};
let start: Address = Address::from_ptr::<u8>(anon_mmap.as_mut_ptr()).align_up(SPACE_ALIGN);
let end: Address = start + space_size;
let trace_map = AddressMap::new(start, end);
......
......@@ -161,7 +161,7 @@ pub struct ImmixSpace {
total_blocks: usize, // for debug use
#[allow(dead_code)]
mmap: memmap::Mmap,
mmap: memmap::MmapMut,
usable_blocks: Mutex<LinkedList<Box<ImmixBlock>>>,
used_blocks: Mutex<LinkedList<Box<ImmixBlock>>>
}
......@@ -180,14 +180,12 @@ const SPACE_ALIGN: usize = 1 << 19;
impl ImmixSpace {
pub fn new(space_size: usize) -> ImmixSpace {
// acquire memory through mmap
let anon_mmap: memmap::Mmap = match memmap::Mmap::anonymous(
space_size + SPACE_ALIGN,
memmap::Protection::ReadWrite
) {
Ok(m) => m,
Err(_) => panic!("failed to call mmap")
};
let start: Address = Address::from_ptr::<u8>(anon_mmap.ptr()).align_up(SPACE_ALIGN);
let mut anon_mmap: memmap::MmapMut =
match memmap::MmapMut::map_anon(space_size + SPACE_ALIGN) {
Ok(m) => m,
Err(_) => panic!("failed to call mmap")
};
let start: Address = Address::from_ptr::<u8>(anon_mmap.as_mut_ptr()).align_up(SPACE_ALIGN);
let end: Address = start + space_size;
let line_mark_table = LineMarkTable::new(start, end);
......
......@@ -99,7 +99,7 @@ pub struct MuStack {
/// the Mmap that keeps this memory alive
#[allow(dead_code)]
mmap: Option<memmap::Mmap>
mmap: Option<memmap::MmapMut>
}
lazy_static!{
pub static ref MUSTACK_SP_OFFSET : usize =
......@@ -109,16 +109,16 @@ impl MuStack {
/// creates a new MuStack for given entry function and function address
pub fn new(id: MuID, func_addr: Address, stack_arg_size: usize) -> MuStack {
// allocate memory for the stack
let anon_mmap = {
let mut anon_mmap = {
// reserve two guard pages more than we need for the stack
let total_size = PAGE_SIZE * 2 + STACK_SIZE;
match memmap::Mmap::anonymous(total_size, memmap::Protection::ReadWrite) {
match memmap::MmapMut::map_anon(total_size) {
Ok(m) => m,
Err(_) => panic!("failed to mmap for a stack")
}
};
let mmap_start = Address::from_ptr(anon_mmap.ptr());
let mmap_start = Address::from_ptr(anon_mmap.as_mut_ptr());
debug_assert!(mmap_start.is_aligned_to(PAGE_SIZE));
// calculate the addresses
......
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