Commit e10103b7 authored by qinsoon's avatar qinsoon

introduce MuFunction (different from MuFunctionVersion)

parent 39945140
...@@ -17,9 +17,29 @@ pub type Address = usize; // TODO: replace this with Address(usize) ...@@ -17,9 +17,29 @@ pub type Address = usize; // TODO: replace this with Address(usize)
pub type OpIndex = usize; pub type OpIndex = usize;
#[derive(Debug)]
pub struct MuFunction {
pub fn_name: MuTag,
pub sig: P<MuFuncSig>,
pub cur_ver: Option<MuTag>,
pub all_vers: Vec<MuTag>
}
impl MuFunction {
pub fn new(fn_name: MuTag, sig: P<MuFuncSig>) -> MuFunction {
MuFunction {
fn_name: fn_name,
sig: sig,
cur_ver: None,
all_vers: vec![]
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct MuFunctionVersion { pub struct MuFunctionVersion {
pub fn_name: MuTag, pub fn_name: MuTag,
pub version: MuTag,
pub next_id: MuID, pub next_id: MuID,
...@@ -33,9 +53,10 @@ pub struct MuFunctionVersion { ...@@ -33,9 +53,10 @@ pub struct MuFunctionVersion {
pub const RESERVED_NODE_IDS_FOR_MACHINE : usize = 100; pub const RESERVED_NODE_IDS_FOR_MACHINE : usize = 100;
impl MuFunctionVersion { impl MuFunctionVersion {
pub fn new(fn_name: MuTag, sig: P<MuFuncSig>) -> MuFunctionVersion { pub fn new(fn_name: MuTag, ver: MuTag, sig: P<MuFuncSig>) -> MuFunctionVersion {
MuFunctionVersion{ MuFunctionVersion{
fn_name: fn_name, fn_name: fn_name,
version: ver,
next_id: RESERVED_NODE_IDS_FOR_MACHINE, next_id: RESERVED_NODE_IDS_FOR_MACHINE,
sig: sig, sig: sig,
content: None, content: None,
......
...@@ -12,7 +12,9 @@ pub struct VMContext { ...@@ -12,7 +12,9 @@ pub struct VMContext {
constants: RwLock<HashMap<MuTag, P<Value>>>, constants: RwLock<HashMap<MuTag, P<Value>>>,
types: RwLock<HashMap<MuTag, P<MuType>>>, types: RwLock<HashMap<MuTag, P<MuType>>>,
func_sigs: RwLock<HashMap<MuTag, P<MuFuncSig>>>, func_sigs: RwLock<HashMap<MuTag, P<MuFuncSig>>>,
funcs: RwLock<HashMap<MuTag, RefCell<MuFunctionVersion>>>,
func_vers: RwLock<HashMap<(MuTag, MuTag), RefCell<MuFunctionVersion>>>,
funcs: RwLock<HashMap<MuTag, RefCell<MuFunction>>>,
compiled_funcs: RwLock<HashMap<MuTag, RefCell<CompiledFunction>>> compiled_funcs: RwLock<HashMap<MuTag, RefCell<CompiledFunction>>>
} }
...@@ -23,6 +25,8 @@ impl <'a> VMContext { ...@@ -23,6 +25,8 @@ impl <'a> VMContext {
constants: RwLock::new(HashMap::new()), constants: RwLock::new(HashMap::new()),
types: RwLock::new(HashMap::new()), types: RwLock::new(HashMap::new()),
func_sigs: RwLock::new(HashMap::new()), func_sigs: RwLock::new(HashMap::new()),
func_vers: RwLock::new(HashMap::new()),
funcs: RwLock::new(HashMap::new()), funcs: RwLock::new(HashMap::new()),
compiled_funcs: RwLock::new(HashMap::new()) compiled_funcs: RwLock::new(HashMap::new())
} }
...@@ -57,23 +61,54 @@ impl <'a> VMContext { ...@@ -57,23 +61,54 @@ impl <'a> VMContext {
ret ret
} }
pub fn declare_func (&self, func: MuFunctionVersion) { pub fn declare_func (&self, func: MuFunction) {
info!("declare function {}", func.fn_name);
let mut funcs = self.funcs.write().unwrap(); let mut funcs = self.funcs.write().unwrap();
debug_assert!(!funcs.contains_key(func.fn_name));
funcs.insert(func.fn_name, RefCell::new(func)); funcs.insert(func.fn_name, RefCell::new(func));
} }
pub fn define_func_version (&self, func_ver: MuFunctionVersion) {
info!("define function {} with version {}", func_ver.fn_name, func_ver.version);
// record this version
let func_ver_key = (func_ver.fn_name, func_ver.version);
{
let mut func_vers = self.func_vers.write().unwrap();
func_vers.insert(func_ver_key, RefCell::new(func_ver));
}
// acquire a reference to the func_ver
let func_vers = self.func_vers.read().unwrap();
let func_ver = func_vers.get(&func_ver_key).unwrap().borrow();
// change current version to this (obsolete old versions)
let funcs = self.funcs.read().unwrap();
debug_assert!(funcs.contains_key(func_ver.fn_name)); // it should be declared before defining
let mut func = funcs.get(func_ver.fn_name).unwrap().borrow_mut();
if func.cur_ver.is_some() {
let obsolete_ver = func.cur_ver.unwrap();
func.all_vers.push(obsolete_ver);
// redefinition happens here
// do stuff
}
func.cur_ver = Some(func_ver.version);
}
pub fn add_compiled_func (&self, func: CompiledFunction) { pub fn add_compiled_func (&self, func: CompiledFunction) {
debug_assert!(self.funcs.read().unwrap().contains_key(func.fn_name)); debug_assert!(self.funcs.read().unwrap().contains_key(func.fn_name));
self.compiled_funcs.write().unwrap().insert(func.fn_name, RefCell::new(func)); self.compiled_funcs.write().unwrap().insert(func.fn_name, RefCell::new(func));
} }
pub fn funcs(&self) -> &RwLock<HashMap<MuTag, RefCell<MuFunctionVersion>>> { pub fn funcs(&self) -> &RwLock<HashMap<MuTag, RefCell<MuFunction>>> {
&self.funcs &self.funcs
} }
pub fn func_vers(&self) -> &RwLock<HashMap<(MuTag, MuTag), RefCell<MuFunctionVersion>>> {
&self.func_vers
}
pub fn compiled_funcs(&self) -> &RwLock<HashMap<MuTag, RefCell<CompiledFunction>>> { pub fn compiled_funcs(&self) -> &RwLock<HashMap<MuTag, RefCell<CompiledFunction>>> {
&self.compiled_funcs &self.compiled_funcs
} }
......
...@@ -22,7 +22,9 @@ fn test_instsel_fac() { ...@@ -22,7 +22,9 @@ fn test_instsel_fac() {
]), vm_context.clone()); ]), vm_context.clone());
let funcs = vm_context.funcs().read().unwrap(); let funcs = vm_context.funcs().read().unwrap();
let mut factorial_func = funcs.get("fac").unwrap().borrow_mut(); let factorial_func = funcs.get("fac").unwrap().borrow();
let func_vers = vm_context.func_vers().read().unwrap();
let mut factorial_func_ver = func_vers.get(&(factorial_func.fn_name, factorial_func.cur_ver.unwrap())).unwrap().borrow_mut();
compiler.compile(&mut factorial_func); compiler.compile(&mut factorial_func_ver);
} }
...@@ -20,17 +20,19 @@ fn test_use_count() { ...@@ -20,17 +20,19 @@ fn test_use_count() {
), vm_context.clone()); ), vm_context.clone());
let funcs = vm_context.funcs().read().unwrap(); let funcs = vm_context.funcs().read().unwrap();
let mut factorial_func = funcs.get("fac").unwrap().borrow_mut(); let factorial_func = funcs.get("fac").unwrap().borrow();
let func_vers = vm_context.func_vers().read().unwrap();
compiler.compile(&mut factorial_func); let mut factorial_func_ver = func_vers.get(&(factorial_func.fn_name, factorial_func.cur_ver.unwrap())).unwrap().borrow_mut();
assert!(factorial_func.context.get_value_by_tag("blk_0_n_3").unwrap().use_count.get() == 2, "blk_0_n_3 use should be 2"); compiler.compile(&mut factorial_func_ver);
assert!(factorial_func.context.get_value_by_tag("blk_0_v48").unwrap().use_count.get() == 1, "blk_0_v48 use should be 1");
assert!(factorial_func.context.get_value_by_tag("blk_2_v53").unwrap().use_count.get() == 1, "blk_2_v53 use should be 1"); assert!(factorial_func_ver.context.get_value_by_tag("blk_0_n_3").unwrap().use_count.get() == 2, "blk_0_n_3 use should be 2");
assert!(factorial_func.context.get_value_by_tag("blk_1_n_3").unwrap().use_count.get() == 2, "blk_1_n_3 use should be 2"); assert!(factorial_func_ver.context.get_value_by_tag("blk_0_v48").unwrap().use_count.get() == 1, "blk_0_v48 use should be 1");
assert!(factorial_func.context.get_value_by_tag("blk_1_v50").unwrap().use_count.get() == 1, "blk_1_v50 use should be 1"); assert!(factorial_func_ver.context.get_value_by_tag("blk_2_v53").unwrap().use_count.get() == 1, "blk_2_v53 use should be 1");
assert!(factorial_func.context.get_value_by_tag("blk_1_v51").unwrap().use_count.get() == 1, "blk_1_v51 use should be 1"); assert!(factorial_func_ver.context.get_value_by_tag("blk_1_n_3").unwrap().use_count.get() == 2, "blk_1_n_3 use should be 2");
assert!(factorial_func.context.get_value_by_tag("blk_1_v52").unwrap().use_count.get() == 1, "blk_1_v52 use should be 1"); assert!(factorial_func_ver.context.get_value_by_tag("blk_1_v50").unwrap().use_count.get() == 1, "blk_1_v50 use should be 1");
assert!(factorial_func_ver.context.get_value_by_tag("blk_1_v51").unwrap().use_count.get() == 1, "blk_1_v51 use should be 1");
assert!(factorial_func_ver.context.get_value_by_tag("blk_1_v52").unwrap().use_count.get() == 1, "blk_1_v52 use should be 1");
} }
#[test] #[test]
...@@ -44,9 +46,11 @@ fn test_build_tree() { ...@@ -44,9 +46,11 @@ fn test_build_tree() {
), vm_context.clone()); ), vm_context.clone());
let funcs = vm_context.funcs().read().unwrap(); let funcs = vm_context.funcs().read().unwrap();
let mut factorial_func = funcs.get("fac").unwrap().borrow_mut(); let factorial_func = funcs.get("fac").unwrap().borrow();
let func_vers = vm_context.func_vers().read().unwrap();
let mut factorial_func_ver = func_vers.get(&(factorial_func.fn_name, factorial_func.cur_ver.unwrap())).unwrap().borrow_mut();
compiler.compile(&mut factorial_func); compiler.compile(&mut factorial_func_ver);
} }
#[test] #[test]
...@@ -61,12 +65,14 @@ fn test_cfa_factorial() { ...@@ -61,12 +65,14 @@ fn test_cfa_factorial() {
]), vm_context.clone()); ]), vm_context.clone());
let funcs = vm_context.funcs().read().unwrap(); let funcs = vm_context.funcs().read().unwrap();
let mut factorial_func = funcs.get("fac").unwrap().borrow_mut(); let factorial_func = funcs.get("fac").unwrap().borrow();
let func_vers = vm_context.func_vers().read().unwrap();
let mut factorial_func_ver = func_vers.get(&(factorial_func.fn_name, factorial_func.cur_ver.unwrap())).unwrap().borrow_mut();
compiler.compile(&mut factorial_func); compiler.compile(&mut factorial_func_ver);
// assert cfa // assert cfa
let content = factorial_func.content.as_ref().unwrap(); let content = factorial_func_ver.content.as_ref().unwrap();
// blk_0: preds=[], succs=[blk_2, blk_1] // blk_0: preds=[], succs=[blk_2, blk_1]
let blk_0 = content.get_block("blk_0"); let blk_0 = content.get_block("blk_0");
...@@ -96,12 +102,14 @@ fn test_cfa_sum() { ...@@ -96,12 +102,14 @@ fn test_cfa_sum() {
]), vm_context.clone()); ]), vm_context.clone());
let funcs = vm_context.funcs().read().unwrap(); let funcs = vm_context.funcs().read().unwrap();
let mut sum_func = funcs.get("sum").unwrap().borrow_mut(); let sum_func = funcs.get("sum").unwrap().borrow();
let func_vers = vm_context.func_vers().read().unwrap();
let mut sum_func_ver = func_vers.get(&(sum_func.fn_name, sum_func.cur_ver.unwrap())).unwrap().borrow_mut();
compiler.compile(&mut sum_func); compiler.compile(&mut sum_func_ver);
// assert cfa // assert cfa
let content = sum_func.content.as_ref().unwrap(); let content = sum_func_ver.content.as_ref().unwrap();
// entry: preds=[], succs=[head] // entry: preds=[], succs=[head]
let entry = content.get_block("entry"); let entry = content.get_block("entry");
...@@ -140,11 +148,13 @@ fn test_trace_factorial() { ...@@ -140,11 +148,13 @@ fn test_trace_factorial() {
]), vm_context.clone()); ]), vm_context.clone());
let funcs = vm_context.funcs().read().unwrap(); let funcs = vm_context.funcs().read().unwrap();
let mut factorial_func = funcs.get("fac").unwrap().borrow_mut(); let factorial_func = funcs.get("fac").unwrap().borrow();
let func_vers = vm_context.func_vers().read().unwrap();
let mut factorial_func_ver = func_vers.get(&(factorial_func.fn_name, factorial_func.cur_ver.unwrap())).unwrap().borrow_mut();
compiler.compile(&mut factorial_func); compiler.compile(&mut factorial_func_ver);
assert_vector_ordered(factorial_func.block_trace.as_ref().unwrap(), &vec!["blk_0", "blk_1", "blk_2"]); assert_vector_ordered(factorial_func_ver.block_trace.as_ref().unwrap(), &vec!["blk_0", "blk_1", "blk_2"]);
} }
#[test] #[test]
...@@ -160,9 +170,11 @@ fn test_trace_sum() { ...@@ -160,9 +170,11 @@ fn test_trace_sum() {
]), vm_context.clone()); ]), vm_context.clone());
let funcs = vm_context.funcs().read().unwrap(); let funcs = vm_context.funcs().read().unwrap();
let mut sum_func = funcs.get("sum").unwrap().borrow_mut(); let sum_func = funcs.get("sum").unwrap().borrow();
let func_vers = vm_context.func_vers().read().unwrap();
let mut sum_func_ver = func_vers.get(&(sum_func.fn_name, sum_func.cur_ver.unwrap())).unwrap().borrow_mut();
compiler.compile(&mut sum_func); compiler.compile(&mut sum_func_ver);
assert_vector_ordered(sum_func.block_trace.as_ref().unwrap(), &vec!["entry", "head", "ret"]); assert_vector_ordered(sum_func_ver.block_trace.as_ref().unwrap(), &vec!["entry", "head", "ret"]);
} }
...@@ -24,9 +24,11 @@ fn test_ir_liveness_fac() { ...@@ -24,9 +24,11 @@ fn test_ir_liveness_fac() {
]), vm_context.clone()); ]), vm_context.clone());
let funcs = vm_context.funcs().read().unwrap(); let funcs = vm_context.funcs().read().unwrap();
let mut factorial_func = funcs.get("fac").unwrap().borrow_mut(); let factorial_func = funcs.get("fac").unwrap().borrow();
let func_vers = vm_context.func_vers().read().unwrap();
let mut factorial_func_ver = func_vers.get(&(factorial_func.fn_name, factorial_func.cur_ver.unwrap())).unwrap().borrow_mut();
compiler.compile(&mut factorial_func); compiler.compile(&mut factorial_func_ver);
let cf_lock = vm_context.compiled_funcs().read().unwrap(); let cf_lock = vm_context.compiled_funcs().read().unwrap();
let cf = cf_lock.get("fac").unwrap().borrow(); let cf = cf_lock.get("fac").unwrap().borrow();
...@@ -34,7 +36,7 @@ fn test_ir_liveness_fac() { ...@@ -34,7 +36,7 @@ fn test_ir_liveness_fac() {
// block 0 // block 0
let block_0_livein = cf.mc.get_ir_block_livein("blk_0").unwrap(); let block_0_livein = cf.mc.get_ir_block_livein("blk_0").unwrap();
let blk_0_n_3 = factorial_func.context.get_value_by_tag("blk_0_n_3").unwrap().id; let blk_0_n_3 = factorial_func_ver.context.get_value_by_tag("blk_0_n_3").unwrap().id;
assert!(vec_utils::is_identical_to_str_ignore_order(block_0_livein, vec![blk_0_n_3])); assert!(vec_utils::is_identical_to_str_ignore_order(block_0_livein, vec![blk_0_n_3]));
let block_0_liveout = cf.mc.get_ir_block_liveout("blk_0").unwrap(); let block_0_liveout = cf.mc.get_ir_block_liveout("blk_0").unwrap();
...@@ -43,17 +45,17 @@ fn test_ir_liveness_fac() { ...@@ -43,17 +45,17 @@ fn test_ir_liveness_fac() {
// block 1 // block 1
let block_1_livein = cf.mc.get_ir_block_livein("blk_1").unwrap(); let block_1_livein = cf.mc.get_ir_block_livein("blk_1").unwrap();
let blk_1_n_3 = factorial_func.context.get_value_by_tag("blk_1_n_3").unwrap().id; let blk_1_n_3 = factorial_func_ver.context.get_value_by_tag("blk_1_n_3").unwrap().id;
assert!(vec_utils::is_identical_to_str_ignore_order(block_1_livein, vec![blk_1_n_3])); assert!(vec_utils::is_identical_to_str_ignore_order(block_1_livein, vec![blk_1_n_3]));
let block_1_liveout = cf.mc.get_ir_block_liveout("blk_1").unwrap(); let block_1_liveout = cf.mc.get_ir_block_liveout("blk_1").unwrap();
let blk_1_v52 = factorial_func.context.get_value_by_tag("blk_1_v52").unwrap().id; let blk_1_v52 = factorial_func_ver.context.get_value_by_tag("blk_1_v52").unwrap().id;
assert!(vec_utils::is_identical_to_str_ignore_order(block_1_liveout, vec![blk_1_v52])); assert!(vec_utils::is_identical_to_str_ignore_order(block_1_liveout, vec![blk_1_v52]));
// block 2 // block 2
let block_2_livein = cf.mc.get_ir_block_livein("blk_2").unwrap(); let block_2_livein = cf.mc.get_ir_block_livein("blk_2").unwrap();
let blk_2_v53 = factorial_func.context.get_value_by_tag("blk_2_v53").unwrap().id; let blk_2_v53 = factorial_func_ver.context.get_value_by_tag("blk_2_v53").unwrap().id;
assert!(vec_utils::is_identical_to_str_ignore_order(block_2_livein, vec![blk_2_v53])); assert!(vec_utils::is_identical_to_str_ignore_order(block_2_livein, vec![blk_2_v53]));
let block_2_liveout = cf.mc.get_ir_block_liveout("blk_2").unwrap(); let block_2_liveout = cf.mc.get_ir_block_liveout("blk_2").unwrap();
...@@ -79,7 +81,9 @@ fn test_regalloc_fac() { ...@@ -79,7 +81,9 @@ fn test_regalloc_fac() {
]), vm_context.clone()); ]), vm_context.clone());
let funcs = vm_context.funcs().read().unwrap(); let funcs = vm_context.funcs().read().unwrap();
let mut factorial_func = funcs.get("fac").unwrap().borrow_mut(); let factorial_func = funcs.get("fac").unwrap().borrow();
let func_vers = vm_context.func_vers().read().unwrap();
let mut factorial_func_ver = func_vers.get(&(factorial_func.fn_name, factorial_func.cur_ver.unwrap())).unwrap().borrow_mut();
compiler.compile(&mut factorial_func); compiler.compile(&mut factorial_func_ver);
} }
...@@ -37,17 +37,21 @@ pub fn sum() -> VMContext { ...@@ -37,17 +37,21 @@ pub fn sum() -> VMContext {
// .funcsig @sum_sig = (@int_64) -> (@int_64) // .funcsig @sum_sig = (@int_64) -> (@int_64)
let sum_sig = vm.declare_func_sig("sum_sig", vec![type_def_int64.clone()], vec![type_def_int64.clone()]); let sum_sig = vm.declare_func_sig("sum_sig", vec![type_def_int64.clone()], vec![type_def_int64.clone()]);
// .funcdef @sum VERSION @sum_v1 <@sum_sig> // .funcdecl @sum <@sum_sig>
let mut func = MuFunctionVersion::new("sum", sum_sig.clone()); let func = MuFunction::new("sum", sum_sig.clone());
vm.declare_func(func);
// .funcdef @sum VERSION @sum_v1 <@sum_sig>
let mut func_ver = MuFunctionVersion::new("sum", "sum_v1", sum_sig.clone());
// %entry(<@int_64> %n): // %entry(<@int_64> %n):
let mut blk_entry = Block::new("entry"); let mut blk_entry = Block::new("entry");
let blk_entry_n = func.new_ssa("blk_entry_n", type_def_int64.clone()); let blk_entry_n = func_ver.new_ssa("blk_entry_n", type_def_int64.clone());
let const_def_int64_0_local = func.new_constant(const_def_int64_0.clone()); // FIXME: why we need a local version? let const_def_int64_0_local = func_ver.new_constant(const_def_int64_0.clone()); // FIXME: why we need a local version?
let const_def_int64_1_local = func.new_constant(const_def_int64_1.clone()); let const_def_int64_1_local = func_ver.new_constant(const_def_int64_1.clone());
// BRANCH %head // BRANCH %head
let blk_entry_term = func.new_inst(Instruction { let blk_entry_term = func_ver.new_inst(Instruction {
value: None, value: None,
ops: RefCell::new(vec![blk_entry_n.clone(), const_def_int64_0_local.clone(), const_def_int64_0_local.clone()]), ops: RefCell::new(vec![blk_entry_n.clone(), const_def_int64_0_local.clone(), const_def_int64_0_local.clone()]),
v: Instruction_::Branch1(Destination{ v: Instruction_::Branch1(Destination{
...@@ -65,36 +69,36 @@ pub fn sum() -> VMContext { ...@@ -65,36 +69,36 @@ pub fn sum() -> VMContext {
// %head(<@int_64> %n, <@int_64> %s, <@int_64> %i): // %head(<@int_64> %n, <@int_64> %s, <@int_64> %i):
let mut blk_head = Block::new("head"); let mut blk_head = Block::new("head");
let blk_head_n = func.new_ssa("blk_head_n", type_def_int64.clone()); let blk_head_n = func_ver.new_ssa("blk_head_n", type_def_int64.clone());
let blk_head_s = func.new_ssa("blk_head_s", type_def_int64.clone()); let blk_head_s = func_ver.new_ssa("blk_head_s", type_def_int64.clone());
let blk_head_i = func.new_ssa("blk_head_i", type_def_int64.clone()); let blk_head_i = func_ver.new_ssa("blk_head_i", type_def_int64.clone());
// %s2 = ADD %s %i // %s2 = ADD %s %i
let blk_head_s2 = func.new_ssa("blk_head_s2", type_def_int64.clone()); let blk_head_s2 = func_ver.new_ssa("blk_head_s2", type_def_int64.clone());
let blk_head_inst0 = func.new_inst(Instruction { let blk_head_inst0 = func_ver.new_inst(Instruction {
value: Some(vec![blk_head_s2.clone_value()]), value: Some(vec![blk_head_s2.clone_value()]),
ops: RefCell::new(vec![blk_head_s.clone(), blk_head_i.clone()]), ops: RefCell::new(vec![blk_head_s.clone(), blk_head_i.clone()]),
v: Instruction_::BinOp(BinOp::Add, 0, 1) v: Instruction_::BinOp(BinOp::Add, 0, 1)
}); });
// %i2 = ADD %i 1 // %i2 = ADD %i 1
let blk_head_i2 = func.new_ssa("blk_head_i2", type_def_int64.clone()); let blk_head_i2 = func_ver.new_ssa("blk_head_i2", type_def_int64.clone());
let blk_head_inst1 = func.new_inst(Instruction { let blk_head_inst1 = func_ver.new_inst(Instruction {
value: Some(vec![blk_head_i2.clone_value()]), value: Some(vec![blk_head_i2.clone_value()]),
ops: RefCell::new(vec![blk_head_i.clone(), const_def_int64_1_local.clone()]), ops: RefCell::new(vec![blk_head_i.clone(), const_def_int64_1_local.clone()]),
v: Instruction_::BinOp(BinOp::Add, 0, 1) v: Instruction_::BinOp(BinOp::Add, 0, 1)
}); });
// %cond = UGT %i %n // %cond = UGT %i %n
let blk_head_cond = func.new_ssa("blk_head_cond", type_def_int1.clone()); let blk_head_cond = func_ver.new_ssa("blk_head_cond", type_def_int1.clone());
let blk_head_inst2 = func.new_inst(Instruction { let blk_head_inst2 = func_ver.new_inst(Instruction {
value: Some(vec![blk_head_cond.clone_value()]), value: Some(vec![blk_head_cond.clone_value()]),
ops: RefCell::new(vec![blk_head_i.clone(), blk_head_n.clone()]), ops: RefCell::new(vec![blk_head_i.clone(), blk_head_n.clone()]),
v: Instruction_::CmpOp(CmpOp::UGT, 0, 1) v: Instruction_::CmpOp(CmpOp::UGT, 0, 1)
}); });
// BRANCH2 %cond %ret(%s2) %head(%n %s2 %i2) // BRANCH2 %cond %ret(%s2) %head(%n %s2 %i2)
let blk_head_term = func.new_inst(Instruction{ let blk_head_term = func_ver.new_inst(Instruction{
value: None, value: None,
ops: RefCell::new(vec![blk_head_cond.clone(), blk_head_n.clone(), blk_head_s2.clone(), blk_head_i2.clone()]), ops: RefCell::new(vec![blk_head_cond.clone(), blk_head_n.clone(), blk_head_s2.clone(), blk_head_i2.clone()]),
v: Instruction_::Branch2 { v: Instruction_::Branch2 {
...@@ -120,10 +124,10 @@ pub fn sum() -> VMContext { ...@@ -120,10 +124,10 @@ pub fn sum() -> VMContext {
// %ret(<@int_64> %s): // %ret(<@int_64> %s):
let mut blk_ret = Block::new("ret"); let mut blk_ret = Block::new("ret");
let blk_ret_s = func.new_ssa("blk_ret_s", type_def_int64.clone()); let blk_ret_s = func_ver.new_ssa("blk_ret_s", type_def_int64.clone());
// RET %s // RET %s
let blk_ret_term = func.new_inst(Instruction{ let blk_ret_term = func_ver.new_inst(Instruction{
value: None, value: None,
ops: RefCell::new(vec![blk_ret_s.clone()]), ops: RefCell::new(vec![blk_ret_s.clone()]),
v: Instruction_::Return(vec![0]) v: Instruction_::Return(vec![0])
...@@ -137,7 +141,7 @@ pub fn sum() -> VMContext { ...@@ -137,7 +141,7 @@ pub fn sum() -> VMContext {
blk_ret.content = Some(blk_ret_content); blk_ret.content = Some(blk_ret_content);
// wrap into a function // wrap into a function
func.define(FunctionContent{ func_ver.define(FunctionContent{
entry: "entry", entry: "entry",
blocks: { blocks: {
let mut blocks = HashMap::new(); let mut blocks = HashMap::new();
...@@ -148,7 +152,7 @@ pub fn sum() -> VMContext { ...@@ -148,7 +152,7 @@ pub fn sum() -> VMContext {
} }
}); });
vm.declare_func(func); vm.define_func_version(func_ver);
vm vm
} }
...@@ -179,25 +183,29 @@ pub fn factorial() -> VMContext { ...@@ -179,25 +183,29 @@ pub fn factorial() -> VMContext {
let fac_sig = vm.declare_func_sig("fac_sig", vec![type_def_int64.clone()], vec![type_def_int64.clone()]); let fac_sig = vm.declare_func_sig("fac_sig", vec![type_def_int64.clone()], vec![type_def_int64.clone()]);
let type_def_funcref_fac = vm.declare_type("fac_sig", P(MuType::funcref(fac_sig.clone()))); let type_def_funcref_fac = vm.declare_type("fac_sig", P(MuType::funcref(fac_sig.clone())));
// .funcdecl @fac <@fac_sig>
let func = MuFunction::new("fac", fac_sig.clone());
vm.declare_func(func);
// .funcdef @fac VERSION @fac_v1 <@fac_sig> // .funcdef @fac VERSION @fac_v1 <@fac_sig>
let const_func_fac = vm.declare_const("fac", type_def_funcref_fac, Constant::FuncRef("fac")); let const_func_fac = vm.declare_const("fac", type_def_funcref_fac, Constant::FuncRef("fac"));
let mut func = MuFunctionVersion::new("fac", fac_sig.clone()); let mut func_ver = MuFunctionVersion::new("fac", "fac_v1", fac_sig.clone());
// %blk_0(<@int_64> %n_3): // %blk_0(<@int_64> %n_3):
let mut blk_0 = Block::new("blk_0"); let mut blk_0 = Block::new("blk_0");
let blk_0_n_3 = func.new_ssa("blk_0_n_3", type_def_int64.clone()); let blk_0_n_3 = func_ver.new_ssa("blk_0_n_3", type_def_int64.clone());
let const_def_int64_1_local = func.new_constant(const_def_int64_1.clone()); let const_def_int64_1_local = func_ver.new_constant(const_def_int64_1.clone());
// %v48 = EQ <@int_64> %n_3 @int_64_1 // %v48 = EQ <@int_64> %n_3 @int_64_1
let blk_0_v48 = func.new_ssa("blk_0_v48", type_def_int64.clone()); let blk_0_v48 = func_ver.new_ssa("blk_0_v48", type_def_int64.clone());
let blk_0_inst0 = func.new_inst(Instruction { let blk_0_inst0 = func_ver.new_inst(Instruction {
value: Some(vec![blk_0_v48.clone_value()]), value: Some(vec![blk_0_v48.clone_value()]),
ops: RefCell::new(vec![blk_0_n_3.clone(), const_def_int64_1_local.clone()]), ops: RefCell::new(vec![blk_0_n_3.clone(), const_def_int64_1_local.clone()]),
v: Instruction_::CmpOp(CmpOp::EQ, 0, 1) v: Instruction_::CmpOp(CmpOp::EQ, 0, 1)
}); });
// BRANCH2 %v48 %blk_2(@int_64_1) %blk_1(%n_3) // BRANCH2 %v48 %blk_2(@int_64_1) %blk_1(%n_3)
let blk_0_term = func.new_inst(Instruction{ let blk_0_term = func_ver.new_inst(Instruction{
value: None, value: None,
ops: RefCell::new(vec![blk_0_v48.clone(), const_def_int64_1_local.clone(), blk_0_n_3.clone()]), ops: RefCell::new(vec![blk_0_v48.clone(), const_def_int64_1_local.clone(), blk_0_n_3.clone()]),
v: Instruction_::Branch2 { v: Instruction_::Branch2 {
...@@ -223,10 +231,10 @@ pub fn factorial() -> VMContext { ...@@ -223,10 +231,10 @@ pub fn factorial() -> VMContext {
// %blk_2(<@int_64> %v53): // %blk_2(<@int_64> %v53):
let mut blk_2 = Block::new("blk_2"); let mut blk_2 = Block::new("blk_2");
let blk_2_v53 = func.new_ssa("blk_2_v53", type_def_int64.clone()); let blk_2_v53 = func_ver.new_ssa("blk_2_v53", type_def_int64.clone());
// RET %v53 // RET %v53
let blk_2_term = func.new_inst(Instruction{ let blk_2_term = func_ver.new_inst(Instruction{
value: None, value: None,
ops: RefCell::new(vec![blk_2_v53.clone()]), ops: RefCell::new(vec![blk_2_v53.clone()]),
v: Instruction_::Return(vec![0]) v: Instruction_::Return(vec![0])
...@@ -241,20 +249,20 @@ pub fn factorial() -> VMContext { ...@@ -241,20 +249,20 @@ pub fn factorial() -> VMContext {
// %blk_1(<@int_64> %n_3): // %blk_1(<@int_64> %n_3):
let mut blk_1 = Block::new("blk_1"); let mut blk_1 = Block::new("blk_1");
let blk_1_n_3 = func.new_ssa("blk_1_n_3", type_def_int64.clone()); let blk_1_n_3 = func_ver.new_ssa("blk_1_n_3", type_def_int64.clone());
// %v50 = SUB <@int_64> %n_3 @int_64_1 // %v50 = SUB <@int_64> %n_3 @int_64_1
let blk_1_v50 = func.new_ssa("blk_1_v50", type_def_int64.clone()); let blk_1_v50 = func_ver.new_ssa("blk_1_v50", type_def_int64.clone());
let blk_1_inst0 = func.new_inst(Instruction{ let blk_1_inst0 = func_ver.new_inst(Instruction{
value: Some(vec![blk_1_v50.clone_value()]), value: Some(vec![blk_1_v50.clone_value()]),
ops: RefCell::new(vec![blk_1_n_3.clone(), const_def_int64_1_local.clone()]), ops: RefCell::new(vec![blk_1_n_3.clone(), const_def_int64_1_local.clone()]),
v: Instruction_::BinOp(BinOp::Sub, 0, 1) v: Instruction_::BinOp(BinOp::Sub, 0, 1)
}); });
// %v51 = CALL <@fac_sig> @fac (%v50) // %v51 = CALL <@fac_sig> @fac (%v50)
let blk_1_v51 = func.new_ssa("blk_1_v51", type_def_int64.clone()); let blk_1_v51 = func_ver.new_ssa("blk_1_v51", type_def_int64.clone());
let blk_1_fac = func.new_constant(const_func_fac.clone()); let blk_1_fac = func_ver.new_constant(const_func_fac.clone());
let blk_1_inst1 = func.new_inst(Instruction{ let blk_1_inst1 = func_ver.new_inst(Instruction{
value: Some(vec![blk_1_v51.clone_value()]), value: Some(vec![blk_1_v51.clone_value()]),
ops: RefCell::new(vec![blk_1_fac, blk_1_v50.clone()]), ops: RefCell::new(vec![blk_1_fac, blk_1_v50.clone()]),
v: Instruction_::ExprCall { v: Instruction_::ExprCall {
...@@ -268,15 +276,15 @@ pub fn factorial() -> VMContext { ...@@ -268,15 +276,15 @@ pub fn factorial() -> VMContext {
}); });
// %v52 = MUL <@int_64> %n_3 %v51 // %v52 = MUL <@int_64> %n_3 %v51
let blk_1_v52 = func.new_ssa("blk_1_v52", type_def_int64.clone()); let blk_1_v52 = func_ver.new_ssa("blk_1_v52", type_def_int64.clone());
let blk_1_inst2 = func.new_inst(Instruction{ let blk_1_inst2 = func_ver.new_inst(Instruction{
value: Some(vec![blk_1_v52.clone_value()]), value: Some(vec![blk_1_v52.clone_value()]),
ops: RefCell::new(vec![blk_1_n_3.clone(), blk_1_v51.clone()]), ops: RefCell::new(vec![blk_1_n_3.clone(), blk_1_v51.clone()]),
v: Instruction_::BinOp(BinOp::Mul, 0, 1) v: Instruction_::BinOp(BinOp::Mul, 0, 1)
}); });
// BRANCH blk_2 (%blk_1_v52) // BRANCH blk_2 (%blk_1_v52)
let blk_1_term = func.new_inst(Instruction{ let blk_1_term = func_ver.new_inst(Instruction{
value: None, value: None,
ops: RefCell::new(vec![blk_1_v52.clone()]), ops: RefCell::new(vec![blk_1_v52.clone()]),
v: Instruction_::Branch1(Destination { v: Instruction_::Branch1(Destination {
...@@ -293,7 +301,7 @@ pub fn factorial() -> VMContext { ...@@ -293,7 +301,7 @@ pub fn factorial() -> VMContext {
blk_1.content = Some(blk_1_content); blk_1.content = Some(blk_1_content);
// wrap into a function // wrap into a function
func.define(FunctionContent{ func_ver.define(FunctionContent{
entry: "blk_0", entry: "blk_0",
blocks: { blocks: {
let mut blocks = HashMap::new(); let mut blocks = HashMap::new();
...@@ -304,7 +312,7 @@ pub fn factorial() -> VMContext { ...@@ -304,7 +312,7 @@ pub fn factorial() -> VMContext {
} }
}); });
vm.declare_func(func); vm.define_func_version(func_ver);
vm vm
} }
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