To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit 69e8132a authored by qinsoon's avatar qinsoon
Browse files

[wip] simple_spill works

parent a6b8e16b
......@@ -94,6 +94,19 @@ impl <'a> GraphColoring<'a> {
coloring.regalloc()
}
fn display_node(&self, node: Node) -> String {
let id = self.ig.get_temp_of(node);
self.display_id(id)
}
fn display_id(&self, id: MuID) -> String {
self.func.context.get_temp_display(id)
}
fn display_move(&self, m: Move) -> String {
format!("Move: {} -> {}", self.display_node(m.from), self.display_node(m.to))
}
fn regalloc(mut self) -> Result<GraphColoring<'a>, RegAllocFailure> {
trace!("Initializing coloring allocator...");
......@@ -121,10 +134,7 @@ impl <'a> GraphColoring<'a> {
let outdegree = self.ig.outdegree_of(node);
self.degree.insert(node, outdegree);
trace!("{} has a degree of {}", {
let id = self.ig.get_temp_of(node);
self.func.context.get_temp_display(id)
}, outdegree);
trace!("{} has a degree of {}", self.display_node(node), outdegree);
}
}
......@@ -155,7 +165,7 @@ impl <'a> GraphColoring<'a> {
if cfg!(debug_assertions) {
trace!("nodes to be spilled:");
for node in self.spilled_nodes.iter() {
trace!("{:?}: {:?}", node, self.ig.get_temp_of(*node));
trace!("{}", self.display_node(*node));
}
}
......@@ -173,7 +183,7 @@ impl <'a> GraphColoring<'a> {
let ref ig = self.ig;
let ref mut movelist = self.movelist;
for m in ig.moves() {
trace!("add {:?} to movelist", m);
trace!("add to movelist: {:?}", m);
self.worklist_moves.push(m.clone());
GraphColoring::movelist_mut(movelist, m.from).borrow_mut().push(m.clone());
GraphColoring::movelist_mut(movelist, m.to).borrow_mut().push(m.clone());
......@@ -195,13 +205,13 @@ impl <'a> GraphColoring<'a> {
degree >= n_regs
} {
trace!("{} 's degree >= reg number limit (K), push to spill list", self.node_info(node));
trace!("{} 's degree >= reg number limit (K), push to spill list", self.display_node(node));
self.worklist_spill.push(node);
} else if self.is_move_related(node) {
trace!("{} is move related, push to freeze list", self.node_info(node));
trace!("{} is move related, push to freeze list", self.display_node(node));
self.worklist_freeze.insert(node);
} else {
trace!("{} has small degree and not move related, push to simplify list", self.node_info(node));
trace!("{} has small degree and not move related, push to simplify list", self.display_node(node));
self.worklist_simplify.insert(node);
}
}
......@@ -262,7 +272,7 @@ impl <'a> GraphColoring<'a> {
// remove next element from worklist_simplify, we know its not empty
let node = self.worklist_simplify.pop_front().unwrap();
trace!("Simplifying {}", self.node_info(node));
trace!("Simplifying {}", self.display_node(node));
self.select_stack.push(node);
......@@ -304,14 +314,14 @@ impl <'a> GraphColoring<'a> {
return;
}
trace!("decrement degree of {}", self.node_info(n));
trace!("decrement degree of {}", self.display_node(n));
let d = self.degree(n);
debug_assert!(d != 0);
self.degree.insert(n, d - 1);
if d == self.n_regs_for_node(n) {
trace!("{}'s degree is K, no longer need to spill it", self.node_info(n));
trace!("{}'s degree is K, no longer need to spill it", self.display_node(n));
let mut nodes = self.adjacent(n);
nodes.insert(n);
trace!("enable moves of {:?}", nodes);
......@@ -320,10 +330,10 @@ impl <'a> GraphColoring<'a> {
vec_utils::remove_value(&mut self.worklist_spill, n);
if self.is_move_related(n) {
trace!("{} is move related, push to freeze list", self.node_info(n));
trace!("{} is move related, push to freeze list", self.display_node(n));
self.worklist_freeze.insert(n);
} else {
trace!("{} is not move related, push to simplify list", self.node_info(n));
trace!("{} is not move related, push to simplify list", self.display_node(n));
self.worklist_simplify.insert(n);
}
}
......@@ -345,11 +355,11 @@ impl <'a> GraphColoring<'a> {
fn coalesce(&mut self) {
let m = self.worklist_moves.pop().unwrap();
trace!("Coalescing on {}", self.move_info(m));
trace!("Coalescing on {}", self.display_move(m));
let x = self.get_alias(m.from);
let y = self.get_alias(m.to);
trace!("resolve alias: from {} to {}", self.node_info(x), self.node_info(y));
trace!("resolve alias: from {} to {}", self.display_node(x), self.display_node(y));
let (u, v, precolored_u, precolored_v) = {
if self.precolored.contains(&y) {
......@@ -369,8 +379,8 @@ impl <'a> GraphColoring<'a> {
}
};
trace!("u={}, v={}, precolored_u={}, precolroed_v={}",
self.node_info(u),
self.node_info(v),
self.display_node(u),
self.display_node(v),
precolored_u, precolored_v);
if u == v {
......@@ -511,7 +521,7 @@ impl <'a> GraphColoring<'a> {
fn freeze(&mut self) {
// it is not empty (checked before)
let node = self.worklist_freeze.pop_front().unwrap();
trace!("Freezing {}...", self.node_info(node));
trace!("Freezing {}...", self.display_node(node));
self.worklist_simplify.insert(node);
self.freeze_moves(node);
......@@ -567,7 +577,7 @@ impl <'a> GraphColoring<'a> {
// m is not none
let m = m.unwrap();
trace!("Spilling {}...", self.node_info(m));
trace!("Spilling {}...", self.display_node(m));
vec_utils::remove_value(&mut self.worklist_spill, m);
self.worklist_simplify.insert(m);
......@@ -578,7 +588,7 @@ impl <'a> GraphColoring<'a> {
trace!("---coloring done---");
while !self.select_stack.is_empty() {
let n = self.select_stack.pop().unwrap();
trace!("Assigning color to {}", self.node_info(n));
trace!("Assigning color to {}", self.display_node(n));
let mut ok_colors : LinkedHashSet<MuID> = self.colors.get(&self.ig.get_group_of(n)).unwrap().clone();
for w in self.ig.outedges_of(n) {
......@@ -591,11 +601,11 @@ impl <'a> GraphColoring<'a> {
trace!("available colors: {:?}", ok_colors);
if ok_colors.is_empty() {
trace!("{} is a spilled node", self.node_info(n));
trace!("{} is a spilled node", self.display_node(n));
self.spilled_nodes.push(n);
} else {
let first_available_color = ok_colors.pop_front().unwrap();
trace!("Color {} as {}", self.node_info(n), first_available_color);
trace!("Color {} as {}", self.display_node(n), first_available_color);
if !backend::is_callee_saved(first_available_color) {
warn!("Use caller saved register {}", first_available_color);
......@@ -606,13 +616,13 @@ impl <'a> GraphColoring<'a> {
}
}
for n in self.coalesced_nodes.iter() {
for n in self.colored_nodes.iter() {
let n = *n;
let alias = self.get_alias(n);
let alias_color = self.ig.get_color_of(alias).unwrap();
trace!("Assign color to {} based on aliased {}", self.node_info(n), self.node_info(alias));
trace!("Color {} as {}", self.node_info(n), alias_color);
trace!("Assign color to {} based on aliased {}", self.display_node(n), self.display_node(alias));
trace!("Color {} as {}", self.display_node(n), alias_color);
self.ig.color_node(n, alias_color);
}
......@@ -674,13 +684,4 @@ impl <'a> GraphColoring<'a> {
spills
}
fn node_info(&self, node: Node) -> String {
let reg = self.ig.get_temp_of(node);
format!("{:?}/Reg {}", node, reg)
}
fn move_info(&self, m: Move) -> String {
format!("Move: {} -> {}", self.node_info(m.from), self.node_info(m.to))
}
}
......@@ -3,6 +3,7 @@ extern crate log;
extern crate simple_logger;
extern crate libloading;
use aot;
use test_ir::test_ir::factorial;
use self::mu::compiler::*;
use self::mu::utils::vec_utils;
......@@ -362,5 +363,297 @@ fn create_spill1() -> VM {
vm.define_func_version(func_ver);
vm
}
#[test]
fn test_simple_spill() {
simple_logger::init_with_level(log::LogLevel::Trace).ok();
let vm = Arc::new(create_simple_spill());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let func_id = vm.id_of("simple_spill");
{
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&func.cur_ver.unwrap()).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
}
backend::emit_context(&vm);
let dylib = aot::link_dylib(vec![Mu("simple_spill")], "libsimple_spill.dylib");
let lib = libloading::Library::new(dylib.as_os_str()).unwrap();
unsafe {
let simple_spill : libloading::Symbol<unsafe extern fn() -> u64> = match lib.get(b"simple_spill") {
Ok(symbol) => symbol,
Err(e) => panic!("cannot find symbol simple_spill in dylib: {:?}", e)
};
let res = simple_spill();
println!("simple_spill() = {}", res);
assert!(res == 2);
}
}
fn create_simple_spill() -> VM {
let vm = VM::new();
// .typedef @int_64 = int<64>
let type_def_int64 = vm.declare_type(vm.next_id(), MuType_::int(64));
vm.set_name(type_def_int64.as_entity(), Mu("int_64"));
// .const @int_64_1 <@int_64> = 1
let const_def_int64_1 = vm.declare_const(vm.next_id(), type_def_int64.clone(), Constant::Int(1));
vm.set_name(const_def_int64_1.as_entity(), "int64_1".to_string());
// .funcsig @simple_spill_sig = () -> (@int_64)
let simple_spill_sig = vm.declare_func_sig(vm.next_id(), vec![type_def_int64.clone()], vec![]);
vm.set_name(simple_spill_sig.as_entity(), Mu("simple_spill_sig"));
// .funcdecl @simple_spill <@simple_spill_sig>
let func = MuFunction::new(vm.next_id(), simple_spill_sig.clone());
vm.set_name(func.as_entity(), Mu("simple_spill"));
let func_id = func.id();
vm.declare_func(func);
// .funcdef @simple_spill VERSION @simple_spill_v1 <@simple_spill_sig>
let mut func_ver = MuFunctionVersion::new(vm.next_id(), func_id, simple_spill_sig.clone());
vm.set_name(func_ver.as_entity(), Mu("simple_spill_v1"));
// %entry():
let mut blk_entry = Block::new(vm.next_id());
vm.set_name(blk_entry.as_entity(), Mu("entry"));
// BRANCH %start(1, 1, 1, 1, ..., 1) // 14 constant ONE
let const_int64_1 = func_ver.new_constant(const_def_int64_1.clone());
let blk_start_id = vm.next_id();
let blk_entry_branch = func_ver.new_inst(Instruction{
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![const_int64_1.clone(); 14]),
v: Instruction_::Branch1(Destination{
target: blk_start_id,
args: vec![
DestArg::Normal(0),
DestArg::Normal(1),
DestArg::Normal(2),
DestArg::Normal(3),
DestArg::Normal(4),
DestArg::Normal(5),
DestArg::Normal(6),
DestArg::Normal(7),
DestArg::Normal(8),
DestArg::Normal(9),
DestArg::Normal(10),
DestArg::Normal(11),
DestArg::Normal(12),
DestArg::Normal(13),
]
})
});
blk_entry.content = Some(BlockContent {
args: vec![],
exn_arg: None,
body: vec![blk_entry_branch],
keepalives: None
});
// %start(%t1, %t2, ..., %t14):
let mut blk_start = Block::new(blk_start_id);
vm.set_name(blk_start.as_entity(), Mu("start"));
// args
let blk_start_t1 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t1.as_entity(), Mu("blk_start_t1"));
let blk_start_t2 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t2.as_entity(), Mu("blk_start_t2"));
let blk_start_t3 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t3.as_entity(), Mu("blk_start_t3"));
let blk_start_t4 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t4.as_entity(), Mu("blk_start_t4"));
let blk_start_t5 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t5.as_entity(), Mu("blk_start_t5"));
let blk_start_t6 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t6.as_entity(), Mu("blk_start_t6"));
let blk_start_t7 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t7.as_entity(), Mu("blk_start_t7"));
let blk_start_t8 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t8.as_entity(), Mu("blk_start_t8"));
let blk_start_t9 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t9.as_entity(), Mu("blk_start_t9"));
let blk_start_t10= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t10.as_entity(), Mu("blk_start_t10"));
let blk_start_t11= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t11.as_entity(), Mu("blk_start_t11"));
let blk_start_t12= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t12.as_entity(), Mu("blk_start_t12"));
let blk_start_t13= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t13.as_entity(), Mu("blk_start_t13"));
let blk_start_t14= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_t14.as_entity(), Mu("blk_start_t14"));
// %res = ADD %t1 %t2
let blk_start_res = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_start_res.as_entity(), Mu("blk_start_res"));
let blk_start_add = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: Some(vec![blk_start_res.clone_value()]),
ops: RwLock::new(vec![blk_start_t1.clone(), blk_start_t2.clone()]),
v: Instruction_::BinOp(BinOp::Add, 0, 1)
});
// BRANCH %ret (%res, %t1, %t2, ..., %t14)
let blk_ret_id = vm.next_id();
let blk_start_branch = func_ver.new_inst(Instruction{
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![
blk_start_res.clone(),
blk_start_t1.clone(),
blk_start_t2.clone(),
blk_start_t3.clone(),
blk_start_t4.clone(),
blk_start_t5.clone(),
blk_start_t6.clone(),
blk_start_t7.clone(),
blk_start_t8.clone(),
blk_start_t9.clone(),
blk_start_t10.clone(),
blk_start_t11.clone(),
blk_start_t12.clone(),
blk_start_t13.clone(),
blk_start_t14.clone(),
]),
v: Instruction_::Branch1(Destination{
target: blk_ret_id,
args: vec![
DestArg::Normal(0),
DestArg::Normal(1),
DestArg::Normal(2),
DestArg::Normal(3),
DestArg::Normal(4),
DestArg::Normal(5),
DestArg::Normal(6),
DestArg::Normal(7),
DestArg::Normal(8),
DestArg::Normal(9),
DestArg::Normal(10),
DestArg::Normal(11),
DestArg::Normal(12),
DestArg::Normal(13),
DestArg::Normal(14),
]
})
});
blk_start.content = Some(BlockContent {
args: vec![
blk_start_t1.clone_value(),
blk_start_t2.clone_value(),
blk_start_t3.clone_value(),
blk_start_t4.clone_value(),
blk_start_t5.clone_value(),
blk_start_t6.clone_value(),
blk_start_t7.clone_value(),
blk_start_t8.clone_value(),
blk_start_t9.clone_value(),
blk_start_t10.clone_value(),
blk_start_t11.clone_value(),
blk_start_t12.clone_value(),
blk_start_t13.clone_value(),
blk_start_t14.clone_value(),
],
exn_arg: None,
body: vec![blk_start_add, blk_start_branch],
keepalives: None
});
// %ret(%res, %t1, %t2, ... %t14):
let mut blk_ret = Block::new(blk_ret_id);
vm.set_name(blk_ret.as_entity(), Mu("ret"));
// args
let blk_ret_res = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_res.as_entity(), Mu("blk_ret_res"));
let blk_ret_t1 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t1.as_entity(), Mu("blk_ret_t1"));
let blk_ret_t2 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t2.as_entity(), Mu("blk_ret_t2"));
let blk_ret_t3 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t3.as_entity(), Mu("blk_ret_t3"));
let blk_ret_t4 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t4.as_entity(), Mu("blk_ret_t4"));
let blk_ret_t5 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t5.as_entity(), Mu("blk_ret_t5"));
let blk_ret_t6 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t6.as_entity(), Mu("blk_ret_t6"));
let blk_ret_t7 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t7.as_entity(), Mu("blk_ret_t7"));
let blk_ret_t8 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t8.as_entity(), Mu("blk_ret_t8"));
let blk_ret_t9 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t9.as_entity(), Mu("blk_ret_t9"));
let blk_ret_t10= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t10.as_entity(), Mu("blk_ret_t10"));
let blk_ret_t11= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t11.as_entity(), Mu("blk_ret_t11"));
let blk_ret_t12= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t12.as_entity(), Mu("blk_ret_t12"));
let blk_ret_t13= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t13.as_entity(), Mu("blk_ret_t13"));
let blk_ret_t14= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_t14.as_entity(), Mu("blk_ret_t14"));
// RET %res
let blk_ret_ret = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![blk_ret_res.clone()]),
v: Instruction_::Return(vec![0])
});
blk_ret.content = Some(BlockContent {
args: vec![
blk_ret_res.clone_value(),
blk_ret_t1.clone_value(),
blk_ret_t2.clone_value(),
blk_ret_t3.clone_value(),
blk_ret_t4.clone_value(),
blk_ret_t5.clone_value(),
blk_ret_t6.clone_value(),
blk_ret_t7.clone_value(),
blk_ret_t8.clone_value(),
blk_ret_t9.clone_value(),
blk_ret_t10.clone_value(),
blk_ret_t11.clone_value(),
blk_ret_t12.clone_value(),
blk_ret_t13.clone_value(),
blk_ret_t14.clone_value(),
],
exn_arg: None,
body: vec![blk_ret_ret],
keepalives: None
});
func_ver.define(FunctionContent {
entry: blk_entry.id(),
blocks: {
let mut blocks = HashMap::new();
blocks.insert(blk_entry.id(), blk_entry);
blocks.insert(blk_start.id(), blk_start);
blocks.insert(blk_ret.id(), blk_ret);
blocks
}
});
vm.define_func_version(func_ver);
vm
}
\ No newline at end of file
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