Commit 1461b6f1 authored by qinsoon's avatar qinsoon

[wip] considering branches - need to prune alive entries based on

liveins
parent bdd7e194
Pipeline #310 failed with stage
in 33 minutes and 4 seconds
......@@ -31,6 +31,7 @@ struct ASMCode {
name: MuName,
code: Vec<ASMInst>,
entry: MuName,
blocks: LinkedHashMap<MuName, ASMBlock>,
frame_size_patchpoints: Vec<ASMLocation>
......@@ -116,6 +117,7 @@ impl ASMCode {
trace!("insert spilling code");
let mut ret = ASMCode {
name: self.name.clone(),
entry: self.entry.clone(),
code: vec![],
blocks: linked_hashmap!{},
frame_size_patchpoints: vec![]
......@@ -483,7 +485,7 @@ impl MachineCode for ASMCode {
Some(inst) if inst.code.starts_with("jmp") => {
let split : Vec<&str> = inst.code.split(' ').collect();
Some(String::from(split[1]))
Some(ASMCodeGen::unmangle_block_label(self.name.clone(), String::from(split[1])))
}
_ => None
}
......@@ -495,7 +497,7 @@ impl MachineCode for ASMCode {
Some(inst) if inst.code.ends_with(':') => {
let split : Vec<&str> = inst.code.split(':').collect();
Some(String::from(split[0]))
Some(ASMCodeGen::unmangle_block_label(self.name.clone(), String::from(split[0])))
}
_ => None
}
......@@ -732,6 +734,10 @@ impl MachineCode for ASMCode {
fn get_all_blocks(&self) -> Vec<MuName> {
self.blocks.keys().map(|x| x.clone()).collect()
}
fn get_entry_block(&self) -> MuName {
self.entry.clone()
}
fn get_block_range(&self, block: &str) -> Option<ops::Range<usize>> {
match self.blocks.get(block) {
......@@ -1221,6 +1227,13 @@ impl ASMCodeGen {
format!("{}_{}", self.cur().name, label)
}
fn unmangle_block_label(fn_name: MuName, label: String) -> MuName {
// input: _fn_name_BLOCK_NAME
// return BLOCK_NAME
let split : Vec<&str> = label.splitn(2, &(fn_name + "_")).collect();
String::from(split[1])
}
fn finish_code_sequence_asm(&mut self) -> Box<ASMCode> {
self.cur.take().unwrap()
}
......@@ -1770,9 +1783,10 @@ fn op_postfix(op_len: usize) -> &'static str {
}
impl CodeGenerator for ASMCodeGen {
fn start_code(&mut self, func_name: MuName) -> ValueLocation {
fn start_code(&mut self, func_name: MuName, entry: MuName) -> ValueLocation {
self.cur = Some(Box::new(ASMCode {
name: func_name.clone(),
entry: entry,
code: vec![],
blocks: linked_hashmap! {},
frame_size_patchpoints: vec![]
......@@ -1806,6 +1820,7 @@ impl CodeGenerator for ASMCodeGen {
fn start_code_sequence(&mut self) {
self.cur = Some(Box::new(ASMCode {
name: "snippet".to_string(),
entry: "none".to_string(),
code: vec![],
blocks: linked_hashmap! {},
frame_size_patchpoints: vec![]
......
......@@ -6,7 +6,7 @@ use compiler::machine_code::MachineCode;
use compiler::backend::{Reg, Mem};
pub trait CodeGenerator {
fn start_code(&mut self, func_name: MuName) -> ValueLocation;
fn start_code(&mut self, func_name: MuName, entry: MuName) -> ValueLocation;
fn finish_code(&mut self, func_name: MuName) -> (Box<MachineCode + Sync + Send>, ValueLocation);
// generate unnamed sequence of linear code (no branch)
......
......@@ -3564,12 +3564,14 @@ impl CompilerPass for InstructionSelection {
fn start_function(&mut self, vm: &VM, func_ver: &mut MuFunctionVersion) {
debug!("{}", self.name());
let entry_block = func_ver.content.as_ref().unwrap().get_entry_block();
self.current_fv_id = func_ver.id();
self.current_frame = Some(Frame::new(func_ver.id()));
self.current_func_start = Some({
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_ver.func_id).unwrap().read().unwrap();
self.backend.start_code(func.name().unwrap())
self.backend.start_code(func.name().unwrap(), entry_block.name().unwrap())
});
self.current_callsite_id = 0;
self.current_exn_callsites.clear();
......@@ -3578,8 +3580,7 @@ impl CompilerPass for InstructionSelection {
self.current_constants.clear();
self.current_constants_locs.clear();
// prologue (get arguments from entry block first)
let entry_block = func_ver.content.as_ref().unwrap().get_entry_block();
// prologue (get arguments from entry block first)
let ref args = entry_block.content.as_ref().unwrap().args;
self.emit_common_prologue(args, vm);
}
......
......@@ -8,6 +8,7 @@ use std::fmt;
type EntryID = usize;
#[derive(Clone)]
pub struct AliveEntries {
index: EntryID,
......@@ -232,8 +233,40 @@ impl AliveEntries {
panic!("Temp{} has more than one entry in AliveEntries");
}
}
pub fn intersect(&mut self, another: &Self) -> bool {
let mut entries_to_delete : Vec<EntryID> = vec![];
let mut changed = false;
for (index, entry) in self.inner.iter_mut() {
if entry.has_temp() {
let temp = entry.get_temp().unwrap();
// find entry with the same temp in the other set, and do intersect
for another_entry in another.find_entries_for_temp(temp) {
if entry.intersect(another_entry) {
changed = true;
}
}
} else {
// find entry without a temp in the other set and do intersect
for another_entry in another.inner.values() {
if !another_entry.has_temp() {
if entry.intersect(another_entry) {
changed = true;
}
}
}
}
}
changed
}
}
#[derive(Clone)]
pub struct RegisterEntry {
temp : Option<MuID>,
real : Vec<MuID>,
......@@ -301,6 +334,28 @@ impl RegisterEntry {
self.stack.push(mem)
}
}
// two entries can intersect only when they have the same temp, or they do not have temps
pub fn intersect(&mut self, another: &Self) -> bool {
assert!(
(!self.has_temp() && !another.has_temp()
|| (self.has_temp() && another.has_temp() && self.get_temp().unwrap() == another.get_temp().unwrap()))
);
let mut changed = false;
// intersect real registers
if vec_utils::intersect(&mut self.real, &another.real) {
changed = true;
}
// intersect memory
if vec_utils::intersect(&mut self.stack, &another.stack) {
changed = true;
}
changed
}
}
impl fmt::Display for RegisterEntry {
......
......@@ -178,6 +178,7 @@ pub trait MachineCode {
fn set_ir_block_liveout(&mut self, block: &str, set: Vec<MuID>);
fn get_all_blocks(&self) -> Vec<MuName>;
fn get_entry_block(&self) -> MuName;
// returns [start_inst, end_inst) // end_inst not included
fn get_block_range(&self, block: &str) -> Option<ops::Range<usize>>;
......
......@@ -84,6 +84,22 @@ pub fn find_value<T: PartialEq> (vec: &Vec<T>, val: T) -> Option<usize> {
None
}
pub fn intersect<T: PartialEq + Clone> (vec: &mut Vec<T>, vec2: &Vec<T>) -> bool {
let mut indices_to_delete = vec![];
for i in 0..vec.len() {
if find_value(vec2, vec[0].clone()).is_none() {
indices_to_delete.push(i);
}
}
for i in indices_to_delete.iter() {
vec.remove(*i);
}
indices_to_delete.len() != 0
}
pub fn remove_value<T: PartialEq> (vec: &mut Vec<T>, val: T) {
match find_value(vec, val) {
Some(index) => {vec.remove(index);},
......
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