Commit 050c4316 authored by John Zhang's avatar John Zhang

Merge branch 'master' into jit-test

parents ad112529 470eac11
......@@ -10,21 +10,25 @@ use std::sync::RwLock;
#[derive(Debug)]
pub struct Instruction {
pub hdr: MuEntityHeader,
pub value : Option<Vec<P<Value>>>,
pub ops : RwLock<Vec<P<TreeNode>>>,
pub v: Instruction_
}
impl_mu_entity!(Instruction);
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
impl Encodable for Instruction {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("Instruction", 3, |s| {
try!(s.emit_struct_field("value", 0, |s| self.value.encode(s)));
s.emit_struct("Instruction", 4, |s| {
try!(s.emit_struct_field("hdr", 0, |s| self.hdr.encode(s)));
try!(s.emit_struct_field("value", 1, |s| self.value.encode(s)));
let ops = &self.ops.read().unwrap();
try!(s.emit_struct_field("ops", 1, |s| ops.encode(s)));
try!(s.emit_struct_field("ops", 2, |s| ops.encode(s)));
try!(s.emit_struct_field("v", 2, |s| self.v.encode(s)));
try!(s.emit_struct_field("v", 3, |s| self.v.encode(s)));
Ok(())
})
......@@ -33,14 +37,16 @@ impl Encodable for Instruction {
impl Decodable for Instruction {
fn decode<D: Decoder>(d: &mut D) -> Result<Instruction, D::Error> {
d.read_struct("Instruction", 3, |d| {
let value = try!(d.read_struct_field("value", 0, |d| Decodable::decode(d)));
d.read_struct("Instruction", 4, |d| {
let hdr = try!(d.read_struct_field("hdr", 0, |d| Decodable::decode(d)));
let value = try!(d.read_struct_field("value", 1, |d| Decodable::decode(d)));
let ops = try!(d.read_struct_field("ops", 1, |d| Decodable::decode(d)));
let ops = try!(d.read_struct_field("ops", 2, |d| Decodable::decode(d)));
let v = try!(d.read_struct_field("v", 2, |d| Decodable::decode(d)));
let v = try!(d.read_struct_field("v", 3, |d| Decodable::decode(d)));
Ok(Instruction{
hdr: hdr,
value: value,
ops: RwLock::new(ops),
v: v
......@@ -52,6 +58,7 @@ impl Decodable for Instruction {
impl Clone for Instruction {
fn clone(&self) -> Self {
Instruction {
hdr: self.hdr.clone(),
value: self.value.clone(),
ops: RwLock::new(self.ops.read().unwrap().clone()),
v: self.v.clone()
......
......@@ -102,7 +102,6 @@ pub struct MuFunctionVersion {
pub func_id: MuID,
pub sig: P<MuFuncSig>,
pub original_ir: Option<FunctionContent>,
pub content: Option<FunctionContent>,
pub context: FunctionContext,
......@@ -139,7 +138,6 @@ impl MuFunctionVersion {
hdr: MuEntityHeader::unnamed(id),
func_id: func,
sig: sig,
original_ir: None,
content: None,
context: FunctionContext::new(),
block_trace: None
......@@ -147,7 +145,6 @@ impl MuFunctionVersion {
}
pub fn define(&mut self, content: FunctionContent) {
self.original_ir = Some(content.clone());
self.content = Some(content);
}
......@@ -161,31 +158,27 @@ impl MuFunctionVersion {
self.context.values.insert(id, SSAVarEntry::new(val.clone()));
P(TreeNode {
hdr: MuEntityHeader::unnamed(id),
op: pick_op_code_for_ssa(&val.ty),
v: TreeNode_::Value(val)
})
}
pub fn new_constant(&mut self, id: MuID, v: P<Value>) -> P<TreeNode> {
pub fn new_constant(&mut self, v: P<Value>) -> P<TreeNode> {
P(TreeNode{
hdr: MuEntityHeader::unnamed(id),
op: pick_op_code_for_value(&v.ty),
v: TreeNode_::Value(v)
})
}
pub fn new_global(&mut self, id: MuID, v: P<Value>) -> P<TreeNode> {
pub fn new_global(&mut self, v: P<Value>) -> P<TreeNode> {
P(TreeNode{
hdr: MuEntityHeader::unnamed(id),
op: pick_op_code_for_value(&v.ty),
v: TreeNode_::Value(v)
})
}
pub fn new_inst(&mut self, id: MuID, v: Instruction) -> Box<TreeNode> {
pub fn new_inst(&mut self, v: Instruction) -> Box<TreeNode> {
Box::new(TreeNode{
hdr: MuEntityHeader::unnamed(id),
op: pick_op_code_for_inst(&v),
v: TreeNode_::Instruction(v),
})
......@@ -260,7 +253,6 @@ impl FunctionContext {
self.values.insert(id, SSAVarEntry::new(val.clone()));
P(TreeNode {
hdr: MuEntityHeader::unnamed(id),
op: pick_op_code_for_ssa(&val.ty),
v: TreeNode_::Value(val)
})
......@@ -374,9 +366,13 @@ pub struct BlockContent {
impl fmt::Debug for BlockContent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "args: {:?}", self.args).unwrap();
writeln!(f, "exception arg: {:?}", self.args).unwrap();
writeln!(f, "keepalives: {:?}", self.keepalives).unwrap();
writeln!(f, "args: {}", vec_utils::as_str(&self.args)).unwrap();
if self.exn_arg.is_some() {
writeln!(f, "exception arg: {}", self.exn_arg.as_ref().unwrap()).unwrap();
}
if self.keepalives.is_some() {
writeln!(f, "keepalives: {}", vec_utils::as_str(self.keepalives.as_ref().unwrap())).unwrap();
}
for node in self.body.iter() {
writeln!(f, "{}", node).unwrap();
}
......@@ -458,16 +454,14 @@ impl BlockContent {
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
/// always use with P<TreeNode>
pub struct TreeNode {
pub hdr: MuEntityHeader,
pub op: OpCode,
pub v: TreeNode_,
}
impl TreeNode {
// this is a hack to allow creating TreeNode without using a &mut MuFunctionVersion
pub fn new_inst(id: MuID, v: Instruction) -> P<TreeNode> {
pub fn new_inst(v: Instruction) -> P<TreeNode> {
P(TreeNode{
hdr: MuEntityHeader::unnamed(id),
op: pick_op_code_for_inst(&v),
v: TreeNode_::Instruction(v),
})
......@@ -877,7 +871,7 @@ impl PartialEq for MuEntityHeader {
impl fmt::Display for MuEntityHeader {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.name().is_none() {
write!(f, "#{}", self.id)
write!(f, "UNNAMED #{}", self.id)
} else {
write!(f, "{} #{}", self.name().unwrap(), self.id)
}
......@@ -894,11 +888,40 @@ pub trait MuEntity {
impl_mu_entity!(MuFunction);
impl_mu_entity!(MuFunctionVersion);
impl_mu_entity!(Block);
impl_mu_entity!(TreeNode);
impl_mu_entity!(MuType);
impl_mu_entity!(Value);
impl_mu_entity!(MuFuncSig);
impl MuEntity for TreeNode {
fn id(&self) -> MuID {
match self.v {
TreeNode_::Instruction(ref inst) => inst.id(),
TreeNode_::Value(ref pv) => pv.id()
}
}
fn name(&self) -> Option<MuName> {
match self.v {
TreeNode_::Instruction(ref inst) => inst.name(),
TreeNode_::Value(ref pv) => pv.name()
}
}
fn set_name(&self, name: MuName) {
match self.v {
TreeNode_::Instruction(ref inst) => inst.set_name(name),
TreeNode_::Value(ref pv) => pv.set_name(name)
}
}
fn as_entity(&self) -> &MuEntity {
match self.v {
TreeNode_::Instruction(ref inst) => inst.as_entity(),
TreeNode_::Value(ref pv) => pv.as_entity()
}
}
}
pub fn op_vector_str(vec: &Vec<OpIndex>, ops: &Vec<P<TreeNode>>) -> String {
let mut ret = String::new();
for i in 0..vec.len() {
......
......@@ -52,7 +52,7 @@ pub type P<T> = Arc<T>;
#[allow(non_snake_case)]
/// Construct a `P<T>` from a `T` value.
pub fn P<T: MuEntity>(value: T) -> P<T> {
pub fn P<T>(value: T) -> P<T> {
// P {ptr: Arc::new(value)}
Arc::new(value)
}
......
use ast::ir::MuID;
use ast::ir::*;
use compiler::backend;
use compiler::backend::reg_alloc::graph_coloring;
use compiler::backend::reg_alloc::graph_coloring::liveness::InterferenceGraph;
use compiler::backend::reg_alloc::graph_coloring::liveness::{Node, Move};
use compiler::backend;
use compiler::backend::reg_alloc::RegAllocFailure;
use compiler::machine_code::CompiledFunction;
use vm::VM;
use utils::vec_utils;
use utils::LinkedHashSet;
......@@ -14,7 +17,7 @@ const COALESCING : bool = true;
pub struct GraphColoring {
pub ig: InterferenceGraph,
precolored: LinkedHashSet<Node>,
colors: HashMap<backend::RegGroup, LinkedHashSet<MuID>>,
pub colored_nodes: Vec<Node>,
......@@ -42,10 +45,12 @@ pub struct GraphColoring {
}
impl GraphColoring {
pub fn start (ig: InterferenceGraph) -> Result<GraphColoring, RegAllocFailure> {
pub fn start (func: &mut MuFunctionVersion, cf: &mut CompiledFunction, vm: &VM) -> Result<GraphColoring, RegAllocFailure> {
cf.mc().trace_mc();
let mut coloring = GraphColoring {
ig: ig,
ig: graph_coloring::build_inteference_graph(cf, func),
precolored: LinkedHashSet::new(),
colors: {
let mut map = HashMap::new();
......@@ -77,14 +82,21 @@ impl GraphColoring {
select_stack: Vec::new()
};
match coloring.init() {
match coloring.regalloc(func, cf, vm) {
Ok(_) => Ok(coloring),
Err(fail) => Err(fail)
}
}
fn init (&mut self) -> Result<(), RegAllocFailure> {
fn regalloc(&mut self, func: &mut MuFunctionVersion, cf: &mut CompiledFunction, vm: &VM) -> Result<(), RegAllocFailure> {
trace!("Initializing coloring allocator...");
trace!("---InterenceGraph---");
self.ig.print();
trace!("---All temps---");
for entry in func.context.values.values() {
trace!("{}", entry);
}
// precolor for all machine registers
for reg in backend::all_regs().values() {
......@@ -129,7 +141,23 @@ impl GraphColoring {
&& self.worklist_spill.is_empty())
} {}
self.assign_colors()
self.assign_colors();
if !self.spilled_nodes.is_empty() {
trace!("spill required");
if cfg!(debug_assertions) {
trace!("nodes to be spilled:");
for node in self.spilled_nodes.iter() {
trace!("{:?}: {:?}", node, self.ig.get_temp_of(*node));
}
}
self.rewrite_program(func, cf, vm);
GraphColoring::start(func, cf, vm);
}
Ok(())
}
fn build(&mut self) {
......@@ -539,7 +567,7 @@ impl GraphColoring {
self.freeze_moves(m);
}
fn assign_colors(&mut self) -> Result<(), RegAllocFailure> {
fn assign_colors(&mut self) -> Result<(), ()> {
trace!("---coloring done---");
while !self.select_stack.is_empty() {
let n = self.select_stack.pop().unwrap();
......@@ -583,6 +611,49 @@ impl GraphColoring {
Ok(())
}
fn rewrite_program(&mut self, func: &mut MuFunctionVersion, cf: &mut CompiledFunction, vm: &VM) {
let spills = self.spills();
let mut spilled_mem = HashMap::new();
// allocating frame slots for every spilled temp
for reg_id in spills.iter() {
let ssa_entry = match func.context.get_value(*reg_id) {
Some(entry) => entry,
None => panic!("The spilled register {} is not in func context", reg_id)
};
let mem = cf.frame.alloc_slot_for_spilling(ssa_entry.value().clone(), vm);
spilled_mem.insert(*reg_id, mem);
}
let new_temps = backend::spill_rewrite(&spilled_mem, func, cf, vm);
//
// self.spilled_nodes.clear();
//
// self.initial = {
// let mut ret = vec![];
//
// for node in self.colored_nodes.iter() {
// vec_utils::add_unique(&mut ret, node.clone());
// }
// for node in self.coalesced_nodes.iter() {
// vec_utils::add_unique(&mut ret, node.clone());
// }
//
// // create nodes for every new temp
// for tmp in new_temps {
// let node = self.ig.new_node(tmp.id(), &func.context);
// vec_utils::add_unique(&mut ret, node.clone());
// }
//
// ret
// };
//
// self.colored_nodes.clear();
// self.coalesced_nodes.clear();
}
pub fn spills(&self) -> Vec<MuID> {
let mut spills = vec![];
......
......@@ -28,68 +28,45 @@ impl RegisterAllocation {
}
#[allow(unused_variables)]
// returns true if we spill registers (which requires another instruction selection)
fn coloring(&mut self, vm: &VM, func: &mut MuFunctionVersion) -> Result<(), RegAllocFailure> {
let compiled_funcs = vm.compiled_funcs().read().unwrap();
let mut cf = compiled_funcs.get(&func.id()).unwrap().write().unwrap();
cf.mc().trace_mc();
// initialize machine registers for the function context
init_machine_regs_for_func(&mut func.context);
let liveness = graph_coloring::build_inteference_graph(&mut cf, func);
liveness.print();
let coloring = match graph_coloring::GraphColoring::start(liveness) {
let coloring = match graph_coloring::GraphColoring::start(func, &mut cf, vm) {
Ok(coloring) => coloring,
Err(err) => {
return Err(err);
}
Err(_) => panic!("error during coloring - unexpected")
};
let spills = coloring.spills();
if !spills.is_empty() {
let mut spilled_mem = HashMap::new();
// allocating frame slots for every spilled temp
for reg_id in spills.iter() {
let ssa_entry = match func.context.get_value(*reg_id) {
Some(entry) => entry,
None => panic!("The spilled register {} is not in func context", reg_id)
};
let mem = cf.frame.alloc_slot_for_spilling(ssa_entry.value().clone(), vm);
spilled_mem.insert(*reg_id, mem);
}
backend::spill_rewrite(&spilled_mem, func, &mut cf, vm);
return Err(RegAllocFailure::FailedForSpilling);
}
// replace regs
trace!("Replacing Registers...");
for node in coloring.ig.nodes() {
let temp = coloring.ig.get_temp_of(node);
// skip machine registers
if temp < MACHINE_ID_END {
continue;
} else {
let alias = coloring.get_alias(node);
let machine_reg = coloring.ig.get_color_of(alias).unwrap();
let machine_reg = match coloring.ig.get_color_of(alias) {
Some(reg) => reg,
None => panic!(
"Reg{}/{:?} (aliased as Reg{}/{:?}) is not assigned with a color",
coloring.ig.get_temp_of(node), node,
coloring.ig.get_temp_of(alias), alias)
};
trace!("replacing {} with {}", temp, machine_reg);
cf.mc_mut().replace_reg(temp, machine_reg);
cf.temps.insert(temp, machine_reg);
}
}
cf.mc().trace_mc();
Ok(())
}
}
......
......@@ -60,7 +60,7 @@ impl CompilerPass for TreeGen {
let expr = entry_value.take_expr();
trace!("{} replaced by {}", ops[index], expr);
ops[index] = TreeNode::new_inst(vm.next_id(), expr);
ops[index] = TreeNode::new_inst(expr);
}
} else {
trace!("{} cant be replaced", ops[index]);
......
......@@ -23,6 +23,10 @@ impl<K: Hash + Eq> LinkedHashSet<K> {
ret
}
pub fn clear(&mut self) {
self.0.clear();
}
}
impl<K: Hash + Eq, S: BuildHasher> LinkedHashSet<K, S> {
......
......@@ -79,7 +79,8 @@ pub fn alloc_new() -> VM {
// %a = NEW <@int64_t>
let blk_0_a = func_ver.new_ssa(vm.next_id(), type_def_ref_int64.clone());
vm.set_name(blk_0_a.as_entity(), "blk_0_a".to_string());
let blk_0_inst0 = func_ver.new_inst(vm.next_id(), Instruction{
let blk_0_inst0 = func_ver.new_inst(Instruction{
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: Some(vec![blk_0_a.clone_value()]),
ops: RwLock::new(vec![]),
v: Instruction_::New(type_def_int64.clone())
......@@ -88,15 +89,17 @@ pub fn alloc_new() -> VM {
// %a_iref = GETIREF <@int_64> @a
let blk_0_a_iref = func_ver.new_ssa(vm.next_id(), type_def_iref_int64.clone());
vm.set_name(blk_0_a.as_entity(), "blk_0_a_iref".to_string());
let blk_0_inst1 = func_ver.new_inst(vm.next_id(), Instruction{
let blk_0_inst1 = func_ver.new_inst(Instruction{
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: Some(vec![blk_0_a_iref.clone_value()]),
ops: RwLock::new(vec![blk_0_a.clone()]),
v: Instruction_::GetIRef(0)
});
// STORE <@int_64> @a_iref @int_64_1
let blk_0_const_int64_1 = func_ver.new_constant(vm.next_id(), const_def_int64_1.clone());
let blk_0_inst2 = func_ver.new_inst(vm.next_id(), Instruction{
let blk_0_const_int64_1 = func_ver.new_constant(const_def_int64_1.clone());
let blk_0_inst2 = func_ver.new_inst(Instruction{
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![blk_0_a_iref.clone(), blk_0_const_int64_1.clone()]),
v: Instruction_::Store{
......@@ -120,7 +123,8 @@ pub fn alloc_new() -> VM {
// }
// });
let blk_0_term = func_ver.new_inst(vm.next_id(), Instruction {
let blk_0_term = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![]),
v: Instruction_::ThreadExit
......
......@@ -104,8 +104,9 @@ fn create_catch_exception_func (vm: &VM) {
let blk_normal_cont_id = vm.next_id();
let blk_exn_cont_id = vm.next_id();
let blk_0_throw = func_ver.new_constant(vm.next_id(), const_funcref_throw_exception.clone());
let blk_0_term = func_ver.new_inst(vm.next_id(), Instruction {
let blk_0_throw = func_ver.new_constant(const_funcref_throw_exception.clone());
let blk_0_term = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![blk_0_throw]),
v: Instruction_::Call {
......@@ -138,7 +139,8 @@ fn create_catch_exception_func (vm: &VM) {
// %blk_normal_cont():
let mut blk_normal_cont = Block::new(blk_normal_cont_id);
vm.set_name(blk_normal_cont.as_entity(), Mu("blk_normal_cont"));
let blk_normal_cont_thread_exit = func_ver.new_inst(vm.next_id(), Instruction {
let blk_normal_cont_thread_exit = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![]),
v: Instruction_::ThreadExit
......@@ -156,7 +158,8 @@ fn create_catch_exception_func (vm: &VM) {
let type_ref_int64 = vm.get_type(vm.id_of("ref_int64"));
let blk_exn_cont_exception_arg = func_ver.new_ssa(vm.next_id(), type_ref_int64.clone());
vm.set_name(blk_exn_cont_exception_arg.as_entity(), Mu("blk_0_exception_arg"));
let blk_exn_cont_thread_exit = func_ver.new_inst(vm.next_id(), Instruction {
let blk_exn_cont_thread_exit = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![]),
v: Instruction_::ThreadExit
......@@ -206,25 +209,28 @@ fn create_throw_exception_func (vm: &VM) {
// %exception_obj = NEW <@int64>
let blk_0_exception_obj = func_ver.new_ssa(vm.next_id(), type_ref_int64.clone());
vm.set_name(blk_0_exception_obj.as_entity(), Mu("blk_0_exception_obj"));
let blk_0_inst0 = func_ver.new_inst(vm.next_id(), Instruction {
value: Some(vec![blk_0_exception_obj.clone_value()]),
ops: RwLock::new(vec![]),
v: Instruction_::New(type_ref_int64.clone())
let blk_0_inst0 = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: Some(vec![blk_0_exception_obj.clone_value()]),
ops: RwLock::new(vec![]),
v: Instruction_::New(type_ref_int64.clone())
});
// %exception_obj_iref = GETIREF <@int64> %exception_obj
let blk_0_exception_obj_iref = func_ver.new_ssa(vm.next_id(), type_iref_int64.clone());
vm.set_name(blk_0_exception_obj_iref.as_entity(), Mu("blk_0_exception_obj_iref"));
let blk_0_inst1 = func_ver.new_inst(vm.next_id(), Instruction {
value: Some(vec![blk_0_exception_obj_iref.clone_value()]),
ops: RwLock::new(vec![blk_0_exception_obj.clone()]),
v: Instruction_::GetIRef(0)
let blk_0_inst1 = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: Some(vec![blk_0_exception_obj_iref.clone_value()]),
ops: RwLock::new(vec![blk_0_exception_obj.clone()]),
v: Instruction_::GetIRef(0)
});
// STORE <@int64> %exception_obj_iref @int64_1
let const_int64_1 = vm.get_const(vm.id_of("int64_1"));
let blk_0_const_int64_1 = func_ver.new_constant(vm.next_id(), const_int64_1);
let blk_0_inst2 = func_ver.new_inst(vm.next_id(), Instruction {
let blk_0_const_int64_1 = func_ver.new_constant(const_int64_1);
let blk_0_inst2 = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![blk_0_exception_obj_iref.clone(), blk_0_const_int64_1.clone()]),
v: Instruction_::Store {
......@@ -235,7 +241,8 @@ fn create_throw_exception_func (vm: &VM) {
}
});
let blk_0_term = func_ver.new_inst(vm.next_id(), Instruction {
let blk_0_term = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![blk_0_exception_obj.clone()]),
v: Instruction_::Throw(0)
......
......@@ -123,32 +123,33 @@ fn create_spill1() -> VM {
vm.set_name(blk_entry.as_entity(), Mu("entry"));
// callee
let blk_entry_spill1_funcref = func_ver.new_constant(vm.next_id(), const_func_spill1.clone());
let blk_entry_spill1_funcref = func_ver.new_constant(const_func_spill1.clone());
// args
let blk_entry_t1 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_t1.as_entity(), Mu("blk_entry_t1"));
let blk_entry_t2 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_t1.as_entity(), Mu("blk_entry_t2"));
vm.set_name(blk_entry_t2.as_entity(), Mu("blk_entry_t2"));
let blk_entry_t3 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_t1.as_entity(), Mu("blk_entry_t3"));
vm.set_name(blk_entry_t3.as_entity(), Mu("blk_entry_t3"));
let blk_entry_t4 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_t1.as_entity(), Mu("blk_entry_t4"));
vm.set_name(blk_entry_t4.as_entity(), Mu("blk_entry_t4"));
let blk_entry_t5 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_t1.as_entity(), Mu("blk_entry_t5"));
vm.set_name(blk_entry_t5.as_entity(), Mu("blk_entry_t5"));
let blk_entry_t6 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_t1.as_entity(), Mu("blk_entry_t6"));
vm.set_name(blk_entry_t6.as_entity(), Mu("blk_entry_t6"));
let blk_entry_t7 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_t1.as_entity(), Mu("blk_entry_t7"));
vm.set_name(blk_entry_t7.as_entity(), Mu("blk_entry_t7"));
let blk_entry_t8 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_t1.as_entity(), Mu("blk_entry_t8"));
vm.set_name(blk_entry_t8.as_entity(), Mu("blk_entry_t8"));
let blk_entry_t9 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_t1.as_entity(), Mu("blk_entry_t9"));
vm.set_name(blk_entry_t9.as_entity(), Mu("blk_entry_t9"));
let blk_entry_t10= func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_t1.as_entity(), Mu("blk_entry_t10"));
vm.set_name(blk_entry_t10.as_entity(), Mu("blk_entry_t10"));
// %x = CALL spill1(%t1, %t2, ... t10)
let blk_entry_x = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
let blk_entry_call = func_ver.new_inst(vm.next_id(), Instruction{
let blk_entry_call = func_ver.new_inst(Instruction{
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: Some(vec![blk_entry_x.clone_value()]),
ops: RwLock::new(vec![
blk_entry_spill1_funcref,
......@@ -176,7 +177,8 @@ fn create_spill1() -> VM {
// %res0 = ADD %t1 %t2
let blk_entry_res0 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_res0.as_entity(), Mu("blk_entry_res0"));
let blk_entry_add0 = func_ver.new_inst(vm.next_id(), Instruction {
let blk_entry_add0 = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: Some(vec![blk_entry_res0.clone_value()]),
ops: RwLock::new(vec![blk_entry_t1.clone(), blk_entry_t2.clone()]),
v: Instruction_::BinOp(BinOp::Add, 0, 1)
......@@ -185,7 +187,8 @@ fn create_spill1() -> VM {
// %res1 = ADD %res0 %t3
let blk_entry_res1 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_res1.as_entity(), Mu("blk_entry_res1"));
let blk_entry_add1 = func_ver.new_inst(vm.next_id(), Instruction {
let blk_entry_add1 = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: Some(vec![blk_entry_res1.clone_value()]),
ops: RwLock::new(vec![blk_entry_res0.clone(), blk_entry_t3.clone()]),
v: Instruction_::BinOp(BinOp::Add, 0, 1)
......@@ -194,7 +197,8 @@ fn create_spill1() -> VM {
// %res2 = ADD %res1 %t4
let blk_entry_res2 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_res2.as_entity(), Mu("blk_entry_res2"));
let blk_entry_add2 = func_ver.new_inst(vm.next_id(), Instruction {
let blk_entry_add2 = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: Some(vec![blk_entry_res2.clone_value()]),
ops: RwLock::new(vec![blk_entry_res1.clone(), blk_entry_t4.clone()]),
v: Instruction_::BinOp(BinOp::Add, 0, 1)
......@@ -203,14 +207,16 @@ fn create_spill1() -> VM {
// %res3 = ADD %res2 %t5
let blk_entry_res3 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_res3.as_entity(), Mu("blk_entry_res3"));
let blk_entry_add3 = func_ver.new_inst(vm.next_id(), Instruction {
let blk_entry_add3 = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: Some(vec![blk_entry_res3.clone_value()]),
ops: RwLock::new(vec![blk_entry_res2.clone(), blk_entry_t5.clone()]),
v: Instruction_::BinOp(BinOp::Add, 0, 1)
});
// RET %res3
let blk_entry_ret = func_ver.new_inst(vm.next_id(), Instruction{
let blk_entry_ret = func_ver.new_inst(Instruction{
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![blk_entry_res3.clone()]),
v: Instruction_::Return(vec![0])
......
......@@ -55,7 +55,8 @@ fn primordial_main() -> VM {
let mut blk_entry = Block::new(vm.next_id());
vm.set_name(blk_entry.as_entity(), "entry".to_string());
let thread_exit = func_ver.new_inst(vm.next_id(), Instruction {
let thread_exit = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),