GitLab will be upgraded to the 12.10.14-ce.0 on 28 Sept 2020 at 2.00pm (AEDT) to 2.30pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

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