Commit 6cc6b97f authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano

Merge branch 'master' of gitlab.anu.edu.au:mu/mu-impl-fast

parents f8aa25e3 5b23d615
Pipeline #1281 passed with stages
in 50 minutes and 18 seconds
......@@ -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