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 bcc804b9 authored by qinsoon's avatar qinsoon

a few refactoring

parent 72f4cbd5
...@@ -11,7 +11,6 @@ use std::default; ...@@ -11,7 +11,6 @@ use std::default;
use std::sync::RwLock; use std::sync::RwLock;
use std::cell::Cell; use std::cell::Cell;
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use utils::Address;
pub type WPID = usize; pub type WPID = usize;
pub type MuID = usize; pub type MuID = usize;
...@@ -122,15 +121,14 @@ impl MuFunctionVersion { ...@@ -122,15 +121,14 @@ impl MuFunctionVersion {
self.content = Some(content) self.content = Some(content)
} }
pub fn new_ssa(&mut self, id: MuID, tag: MuName, ty: P<MuType>) -> P<TreeNode> { pub fn new_ssa(&mut self, id: MuID, ty: P<MuType>) -> P<TreeNode> {
self.context.value_tags.insert(tag.clone(), id); self.context.values.insert(id, SSAVarEntry::new(id, ty.clone()));
self.context.values.insert(id, SSAVarEntry{id: id, name: Some(tag.clone()), ty: ty.clone(), use_count: Cell::new(0), expr: None});
P(TreeNode { P(TreeNode {
hdr: MuEntityHeader::unnamed(id), hdr: MuEntityHeader::unnamed(id),
op: pick_op_code_for_ssa(&ty), op: pick_op_code_for_ssa(&ty),
v: TreeNode_::Value(P(Value{ v: TreeNode_::Value(P(Value{
hdr: MuEntityHeader::named(id, tag), hdr: MuEntityHeader::unnamed(id),
ty: ty, ty: ty,
v: Value_::SSAVar(id) v: Value_::SSAVar(id)
})) }))
...@@ -197,34 +195,16 @@ impl FunctionContent { ...@@ -197,34 +195,16 @@ impl FunctionContent {
#[derive(Debug, RustcEncodable, RustcDecodable)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct FunctionContext { pub struct FunctionContext {
pub value_tags: HashMap<MuName, MuID>,
pub values: HashMap<MuID, SSAVarEntry> pub values: HashMap<MuID, SSAVarEntry>
} }
impl FunctionContext { impl FunctionContext {
fn new() -> FunctionContext { fn new() -> FunctionContext {
FunctionContext { FunctionContext {
value_tags: HashMap::new(),
values: HashMap::new() values: HashMap::new()
} }
} }
pub fn get_value_by_tag(&self, tag: &str) -> Option<&SSAVarEntry> {
match self.value_tags.get(&tag.to_string()) {
Some(id) => self.get_value(*id),
None => None
}
}
pub fn get_value_mut_by_tag(&mut self, tag: &str) -> Option<&mut SSAVarEntry> {
let id : MuID = match self.value_tags.get(&tag.to_string()) {
Some(id) => *id,
None => return None
};
self.get_value_mut(id)
}
pub fn get_value(&self, id: MuID) -> Option<&SSAVarEntry> { pub fn get_value(&self, id: MuID) -> Option<&SSAVarEntry> {
self.values.get(&id) self.values.get(&id)
} }
...@@ -536,21 +516,67 @@ pub enum Value_ { ...@@ -536,21 +516,67 @@ pub enum Value_ {
Memory(MemoryLocation) Memory(MemoryLocation)
} }
#[derive(Debug, RustcEncodable, RustcDecodable)] #[derive(Debug)]
pub struct SSAVarEntry { pub struct SSAVarEntry {
pub id: MuID, id: MuID,
pub name: Option<MuName>,
pub ty: P<MuType>, pub ty: P<MuType>,
// how many times this entry is used // how many times this entry is used
// availalbe after DefUse pass // availalbe after DefUse pass
pub use_count: Cell<usize>, pub use_count: AtomicUsize,
// this field is only used during TreeGeneration pass // this field is only used during TreeGeneration pass
pub expr: Option<Instruction> pub expr: Option<Instruction>
} }
impl Encodable for SSAVarEntry {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("SSAVarEntry", 4, |s| {
try!(s.emit_struct_field("id", 0, |s| self.id.encode(s)));
try!(s.emit_struct_field("ty", 1, |s| self.ty.encode(s)));
let count = self.use_count.load(Ordering::SeqCst);
try!(s.emit_struct_field("use_count", 2, |s| s.emit_usize(count)));
try!(s.emit_struct_field("expr", 3, |s| self.expr.encode(s)));
Ok(())
})
}
}
impl Decodable for SSAVarEntry {
fn decode<D: Decoder>(d: &mut D) -> Result<SSAVarEntry, D::Error> {
d.read_struct("SSAVarEntry", 4, |d| {
let id = try!(d.read_struct_field("id", 0, |d| Decodable::decode(d)));
let ty = try!(d.read_struct_field("ty", 1, |d| Decodable::decode(d)));
let count = try!(d.read_struct_field("use_count", 2, |d| d.read_usize()));
let expr = try!(d.read_struct_field("expr", 3, |d| Decodable::decode(d)));
let ret = SSAVarEntry {
id: id,
ty: ty,
use_count: ATOMIC_USIZE_INIT,
expr: expr
};
ret.use_count.store(count, Ordering::SeqCst);
Ok(ret)
})
}
}
impl SSAVarEntry { impl SSAVarEntry {
pub fn new(id: MuID, ty: P<MuType>) -> SSAVarEntry {
let ret = SSAVarEntry {
id: id,
ty: ty,
use_count: ATOMIC_USIZE_INIT,
expr: None
};
ret.use_count.store(0, Ordering::SeqCst);
ret
}
pub fn assign_expr(&mut self, expr: Instruction) { pub fn assign_expr(&mut self, expr: Instruction) {
self.expr = Some(expr) self.expr = Some(expr)
} }
...@@ -558,11 +584,7 @@ impl SSAVarEntry { ...@@ -558,11 +584,7 @@ impl SSAVarEntry {
impl fmt::Display for SSAVarEntry { impl fmt::Display for SSAVarEntry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.name.is_some() { write!(f, "{} #{}", self.ty, self.id)
write!(f, "{} {}#{}", self.ty, self.name.as_ref().unwrap(), self.id)
} else {
write!(f, "{} {}#{}", self.ty, "???", self.id)
}
} }
} }
......
...@@ -36,10 +36,10 @@ ...@@ -36,10 +36,10 @@
//! implementation changes (using a special thread-local heap, for example). //! implementation changes (using a special thread-local heap, for example).
//! Moreover, a switch to, e.g. `P<'a, T>` would be easy and mostly automated. //! Moreover, a switch to, e.g. `P<'a, T>` would be easy and mostly automated.
use std::fmt::{self, Display, Debug}; //use std::fmt::{self, Display, Debug};
use std::hash::{Hash, Hasher}; //use std::hash::{Hash, Hasher};
use std::ops::Deref; //use std::ops::Deref;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; //use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::sync::Arc; use std::sync::Arc;
......
...@@ -6,8 +6,6 @@ use std::fmt; ...@@ -6,8 +6,6 @@ use std::fmt;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::RwLock; use std::sync::RwLock;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)] #[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
pub struct MuType { pub struct MuType {
pub hdr: MuEntityHeader, pub hdr: MuEntityHeader,
......
...@@ -247,19 +247,10 @@ lazy_static! { ...@@ -247,19 +247,10 @@ lazy_static! {
} }
pub fn init_machine_regs_for_func (func_context: &mut FunctionContext) { pub fn init_machine_regs_for_func (func_context: &mut FunctionContext) {
use std::cell::Cell;
for reg in ALL_MACHINE_REGs.values() { for reg in ALL_MACHINE_REGs.values() {
let reg_id = reg.extract_ssa_id().unwrap(); let reg_id = reg.extract_ssa_id().unwrap();
let entry = SSAVarEntry { let entry = SSAVarEntry::new(reg_id, reg.ty.clone());
id: reg_id,
name: reg.name(),
ty: reg.ty.clone(),
use_count: Cell::new(0),
expr: None
};
func_context.value_tags.insert(reg.name().unwrap(), reg_id);
func_context.values.insert(reg_id, entry); func_context.values.insert(reg_id, entry);
} }
} }
......
...@@ -3,6 +3,7 @@ use ast::ptr::*; ...@@ -3,6 +3,7 @@ use ast::ptr::*;
use vm::VM; use vm::VM;
use compiler::CompilerPass; use compiler::CompilerPass;
use std::sync::atomic::Ordering;
pub struct DefUse { pub struct DefUse {
name: &'static str, name: &'static str,
...@@ -27,7 +28,7 @@ fn use_value(val: &P<Value>, func_context: &mut FunctionContext) { ...@@ -27,7 +28,7 @@ fn use_value(val: &P<Value>, func_context: &mut FunctionContext) {
match val.v { match val.v {
Value_::SSAVar(ref id) => { Value_::SSAVar(ref id) => {
let entry = func_context.values.get_mut(id).unwrap(); let entry = func_context.values.get_mut(id).unwrap();
entry.use_count.set(entry.use_count.get() + 1); entry.use_count.fetch_add(1, Ordering::SeqCst);
}, },
_ => {} // dont worry about constants _ => {} // dont worry about constants
} }
...@@ -67,7 +68,7 @@ impl CompilerPass for DefUse { ...@@ -67,7 +68,7 @@ impl CompilerPass for DefUse {
debug!("check use count for variables"); debug!("check use count for variables");
for entry in func.context.values.values() { for entry in func.context.values.values() {
debug!("{}: {}", entry, entry.use_count.get()) debug!("{}: {}", entry, entry.use_count.load(Ordering::SeqCst))
} }
} }
} }
...@@ -6,6 +6,8 @@ use vm::VM; ...@@ -6,6 +6,8 @@ use vm::VM;
use compiler::CompilerPass; use compiler::CompilerPass;
use compiler::PassExecutionResult; use compiler::PassExecutionResult;
use std::sync::atomic::Ordering;
pub struct TreeGen { pub struct TreeGen {
name: &'static str name: &'static str
} }
...@@ -77,7 +79,7 @@ impl CompilerPass for TreeGen { ...@@ -77,7 +79,7 @@ impl CompilerPass for TreeGen {
// we can put the expression as a child node to its use // we can put the expression as a child node to its use
if left.len() == 1 { if left.len() == 1 {
let lhs = context.get_value_mut(left[0].extract_ssa_id().unwrap()).unwrap(); let lhs = context.get_value_mut(left[0].extract_ssa_id().unwrap()).unwrap();
if lhs.use_count.get() == 1{ if lhs.use_count.load(Ordering::SeqCst) == 1{
if is_movable(&inst.v) { if is_movable(&inst.v) {
lhs.expr = Some(inst.clone()); // FIXME: should be able to move the inst here lhs.expr = Some(inst.clone()); // FIXME: should be able to move the inst here
......
...@@ -2,6 +2,7 @@ use std::collections::HashMap; ...@@ -2,6 +2,7 @@ use std::collections::HashMap;
use ast::ptr::P; use ast::ptr::P;
use ast::ir::*; use ast::ir::*;
use ast::types;
use ast::types::*; use ast::types::*;
use compiler::backend; use compiler::backend;
use compiler::backend::BackendTypeInfo; use compiler::backend::BackendTypeInfo;
...@@ -14,9 +15,12 @@ use utils::Address; ...@@ -14,9 +15,12 @@ use utils::Address;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::path;
use std::sync::RwLock; use std::sync::RwLock;
use std::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT, Ordering}; use std::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT, Ordering};
use std::thread::JoinHandle; use std::thread::JoinHandle;
use std::os::raw::c_char;
use std::sync::Arc;
pub struct VM { pub struct VM {
// serialize // serialize
...@@ -57,7 +61,8 @@ const VM_SERIALIZE_FIELDS : usize = 12; ...@@ -57,7 +61,8 @@ const VM_SERIALIZE_FIELDS : usize = 12;
impl Encodable for VM { impl Encodable for VM {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> { fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
// serialize 11 fields // serialize VM_SERIALIZE_FIELDS fields
// PLUS ONE extra global STRUCT_TAG_MAP
s.emit_struct("VM", VM_SERIALIZE_FIELDS, |s| { s.emit_struct("VM", VM_SERIALIZE_FIELDS, |s| {
// next_id // next_id
try!(s.emit_struct_field("next_id", 0, |s| { try!(s.emit_struct_field("next_id", 0, |s| {
...@@ -81,35 +86,40 @@ impl Encodable for VM { ...@@ -81,35 +86,40 @@ impl Encodable for VM {
let types = &self.types.read().unwrap(); let types = &self.types.read().unwrap();
try!(s.emit_struct_field("types", 3, |s| types.encode(s))); try!(s.emit_struct_field("types", 3, |s| types.encode(s)));
} }
// STRUCT_TAG_MAP
{
let struct_tag_map = types::STRUCT_TAG_MAP.read().unwrap();
try!(s.emit_struct_field("struct_tag_map", 4, |s| struct_tag_map.encode(s)));
}
// backend_type_info // backend_type_info
{ {
let backend_type_info : &HashMap<_, _> = &self.backend_type_info.read().unwrap(); let backend_type_info : &HashMap<_, _> = &self.backend_type_info.read().unwrap();
try!(s.emit_struct_field("backend_type_info", 4, |s| backend_type_info.encode(s))); try!(s.emit_struct_field("backend_type_info", 5, |s| backend_type_info.encode(s)));
} }
// constants // constants
{ {
let constants : &HashMap<_, _> = &self.constants.read().unwrap(); let constants : &HashMap<_, _> = &self.constants.read().unwrap();
try!(s.emit_struct_field("constants", 5, |s| constants.encode(s))); try!(s.emit_struct_field("constants", 6, |s| constants.encode(s)));
} }
// globals // globals
{ {
let globals: &HashMap<_, _> = &self.globals.read().unwrap(); let globals: &HashMap<_, _> = &self.globals.read().unwrap();
try!(s.emit_struct_field("globals", 6, |s| globals.encode(s))); try!(s.emit_struct_field("globals", 7, |s| globals.encode(s)));
} }
// func sigs // func sigs
{ {
let func_sigs: &HashMap<_, _> = &self.func_sigs.read().unwrap(); let func_sigs: &HashMap<_, _> = &self.func_sigs.read().unwrap();
try!(s.emit_struct_field("func_sigs", 7, |s| func_sigs.encode(s))); try!(s.emit_struct_field("func_sigs", 8, |s| func_sigs.encode(s)));
} }
// funcs // funcs
{ {
let funcs : &HashMap<_, _> = &self.funcs.read().unwrap(); let funcs : &HashMap<_, _> = &self.funcs.read().unwrap();
try!(s.emit_struct_field("funcs", 8, |s| { try!(s.emit_struct_field("funcs", 9, |s| {
s.emit_map(funcs.len(), |s| { s.emit_map(funcs.len(), |s| {
let mut i = 0; let mut i = 0;
for (k,v) in funcs.iter() { for (k,v) in funcs.iter() {
...@@ -126,7 +136,7 @@ impl Encodable for VM { ...@@ -126,7 +136,7 @@ impl Encodable for VM {
// func_vers // func_vers
{ {
let func_vers : &HashMap<_, _> = &self.func_vers.read().unwrap(); let func_vers : &HashMap<_, _> = &self.func_vers.read().unwrap();
try!(s.emit_struct_field("func_vers", 9, |s| { try!(s.emit_struct_field("func_vers", 10, |s| {
s.emit_map(func_vers.len(), |s| { s.emit_map(func_vers.len(), |s| {
let mut i = 0; let mut i = 0;
for (k, v) in func_vers.iter() { for (k, v) in func_vers.iter() {
...@@ -143,12 +153,12 @@ impl Encodable for VM { ...@@ -143,12 +153,12 @@ impl Encodable for VM {
// primordial // primordial
{ {
let primordial = &self.primordial.read().unwrap(); let primordial = &self.primordial.read().unwrap();
try!(s.emit_struct_field("primordial", 10, |s| primordial.encode(s))); try!(s.emit_struct_field("primordial", 11, |s| primordial.encode(s)));
} }
// is_running // is_running
{ {
try!(s.emit_struct_field("is_running", 11, |s| self.is_running.load(Ordering::SeqCst).encode(s))); try!(s.emit_struct_field("is_running", 12, |s| self.is_running.load(Ordering::SeqCst).encode(s)));
} }
Ok(()) Ok(())
...@@ -158,7 +168,7 @@ impl Encodable for VM { ...@@ -158,7 +168,7 @@ impl Encodable for VM {
impl Decodable for VM { impl Decodable for VM {
fn decode<D: Decoder>(d: &mut D) -> Result<VM, D::Error> { fn decode<D: Decoder>(d: &mut D) -> Result<VM, D::Error> {
d.read_struct("VM", VM_SERIALIZE_FIELDS, |d| { d.read_struct("VM", VM_SERIALIZE_FIELDS + 1, |d| {
// next_id // next_id
let next_id = try!(d.read_struct_field("next_id", 0, |d| { let next_id = try!(d.read_struct_field("next_id", 0, |d| {
d.read_usize() d.read_usize()
...@@ -172,6 +182,16 @@ impl Decodable for VM { ...@@ -172,6 +182,16 @@ impl Decodable for VM {
// types // types
let types = try!(d.read_struct_field("types", 3, |d| Decodable::decode(d))); let types = try!(d.read_struct_field("types", 3, |d| Decodable::decode(d)));
{
// struct tag map
let mut struct_tag_map : HashMap<MuName, StructType_> = try!(d.read_struct_field("struct_tag_map", 4, |d| Decodable::decode(d)));
let mut map_guard = types::STRUCT_TAG_MAP.write().unwrap();
map_guard.clear();
for (k, v) in struct_tag_map.drain() {
map_guard.insert(k, v);
}
}
// backend_type_info // backend_type_info
let backend_type_info = try!(d.read_struct_field("backend_type_info", 4, |d| Decodable::decode(d))); let backend_type_info = try!(d.read_struct_field("backend_type_info", 4, |d| Decodable::decode(d)));
...@@ -477,4 +497,23 @@ impl <'a> VM { ...@@ -477,4 +497,23 @@ impl <'a> VM {
let mut threads = self.threads.write().unwrap(); let mut threads = self.threads.write().unwrap();
threads.push(handle); threads.push(handle);
} }
#[allow(unused_variables)]
pub fn make_boot_image(self, output: &path::Path) {
use rustc_serialize::json;
let serialized = json::encode(&self).unwrap();
unimplemented!()
}
#[no_mangle]
pub extern fn mu_primorial_main(serialized_vm : *const c_char, len: usize) {
use rustc_serialize::json;
let str_vm = unsafe {String::from_raw_parts(serialized_vm as *mut u8, len, len)};
let vm : Arc<VM> = Arc::new(json::decode(&str_vm).unwrap());
unimplemented!()
}
} }
...@@ -9,6 +9,7 @@ use self::mu::ast::ir::*; ...@@ -9,6 +9,7 @@ use self::mu::ast::ir::*;
use self::mu::compiler::*; use self::mu::compiler::*;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::Ordering;
#[test] #[test]
fn test_use_count() { fn test_use_count() {
...@@ -27,13 +28,13 @@ fn test_use_count() { ...@@ -27,13 +28,13 @@ fn test_use_count() {
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
assert!(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!(func_ver.context.get_value(vm.id_of("blk_0_n_3")).unwrap().use_count.load(Ordering::SeqCst) == 2, "blk_0_n_3 use should be 2");
assert!(func_ver.context.get_value_by_tag("blk_0_v48").unwrap().use_count.get() == 1, "blk_0_v48 use should be 1"); assert!(func_ver.context.get_value(vm.id_of("blk_0_v48")).unwrap().use_count.load(Ordering::SeqCst) == 1, "blk_0_v48 use should be 1");
assert!(func_ver.context.get_value_by_tag("blk_2_v53").unwrap().use_count.get() == 1, "blk_2_v53 use should be 1"); assert!(func_ver.context.get_value(vm.id_of("blk_2_v53")).unwrap().use_count.load(Ordering::SeqCst) == 1, "blk_2_v53 use should be 1");
assert!(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!(func_ver.context.get_value(vm.id_of("blk_1_n_3")).unwrap().use_count.load(Ordering::SeqCst) == 2, "blk_1_n_3 use should be 2");
assert!(func_ver.context.get_value_by_tag("blk_1_v50").unwrap().use_count.get() == 1, "blk_1_v50 use should be 1"); assert!(func_ver.context.get_value(vm.id_of("blk_1_v50")).unwrap().use_count.load(Ordering::SeqCst) == 1, "blk_1_v50 use should be 1");
assert!(func_ver.context.get_value_by_tag("blk_1_v51").unwrap().use_count.get() == 1, "blk_1_v51 use should be 1"); assert!(func_ver.context.get_value(vm.id_of("blk_1_v51")).unwrap().use_count.load(Ordering::SeqCst) == 1, "blk_1_v51 use should be 1");
assert!(func_ver.context.get_value_by_tag("blk_1_v52").unwrap().use_count.get() == 1, "blk_1_v52 use should be 1"); assert!(func_ver.context.get_value(vm.id_of("blk_1_v52")).unwrap().use_count.load(Ordering::SeqCst) == 1, "blk_1_v52 use should be 1");
} }
#[test] #[test]
......
...@@ -37,7 +37,7 @@ fn test_ir_liveness_fac() { ...@@ -37,7 +37,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 = func_ver.context.get_value_by_tag("blk_0_n_3").unwrap().id; let blk_0_n_3 = vm.id_of("blk_0_n_3");;
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();
...@@ -46,17 +46,17 @@ fn test_ir_liveness_fac() { ...@@ -46,17 +46,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 = func_ver.context.get_value_by_tag("blk_1_n_3").unwrap().id; let blk_1_n_3 = vm.id_of("blk_1_n_3");
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 = func_ver.context.get_value_by_tag("blk_1_v52").unwrap().id; let blk_1_v52 = vm.id_of("blk_1_v52");
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 = func_ver.context.get_value_by_tag("blk_2_v53").unwrap().id; let blk_2_v53 = vm.id_of("blk_2_v53");
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();
......
...@@ -61,7 +61,8 @@ pub fn sum() -> VM { ...@@ -61,7 +61,8 @@ pub fn sum() -> VM {
let mut blk_entry = Block::new(vm.next_id()); let mut blk_entry = Block::new(vm.next_id());
vm.set_name(blk_entry.as_entity(), "entry".to_string()); vm.set_name(blk_entry.as_entity(), "entry".to_string());
let blk_entry_n = func_ver.new_ssa(vm.next_id(), "blk_entry_n".to_string(), type_def_int64.clone()); let blk_entry_n = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_entry_n.as_entity(), "blk_entry_n".to_string());
let const_def_int64_0_local = func_ver.new_constant(vm.next_id(), const_def_int64_0.clone()); // FIXME: why we need a local version? let const_def_int64_0_local = func_ver.new_constant(vm.next_id(), const_def_int64_0.clone()); // FIXME: why we need a local version?
let const_def_int64_1_local = func_ver.new_constant(vm.next_id(), const_def_int64_1.clone()); let const_def_int64_1_local = func_ver.new_constant(vm.next_id(), const_def_int64_1.clone());
...@@ -86,12 +87,16 @@ pub fn sum() -> VM { ...@@ -86,12 +87,16 @@ pub fn sum() -> VM {
// %head(<@int_64> %n, <@int_64> %s, <@int_64> %i): // %head(<@int_64> %n, <@int_64> %s, <@int_64> %i):
let blk_head_n = func_ver.new_ssa(vm.next_id(), "blk_head_n".to_string(), type_def_int64.clone()); let blk_head_n = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
let blk_head_s = func_ver.new_ssa(vm.next_id(), "blk_head_s".to_string(), type_def_int64.clone()); vm.set_name(blk_head_n.as_entity(), "blk_head_n".to_string());
let blk_head_i = func_ver.new_ssa(vm.next_id(), "blk_head_i".to_string(), type_def_int64.clone()); let blk_head_s = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_head_s.as_entity(), "blk_head_s".to_string());
let blk_head_i = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_head_i.as_entity(), "blk_head_i".to_string());
// %s2 = ADD %s %i // %s2 = ADD %s %i
let blk_head_s2 = func_ver.new_ssa(vm.next_id(), "blk_head_s2".to_string(), type_def_int64.clone()); let blk_head_s2 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_head_s2.as_entity(), "blk_head_s2".to_string());
let blk_head_inst0 = func_ver.new_inst(vm.next_id(), Instruction { let blk_head_inst0 = func_ver.new_inst(vm.next_id(), Instruction {
value: Some(vec![blk_head_s2.clone_value()]), value: Some(vec![blk_head_s2.clone_value()]),
ops: RwLock::new(vec![blk_head_s.clone(), blk_head_i.clone()]), ops: RwLock::new(vec![blk_head_s.clone(), blk_head_i.clone()]),
...@@ -99,7 +104,8 @@ pub fn sum() -> VM { ...@@ -99,7 +104,8 @@ pub fn sum() -> VM {
}); });
// %i2 = ADD %i 1 // %i2 = ADD %i 1
let blk_head_i2 = func_ver.new_ssa(vm.next_id(), "blk_head_i2".to_string(), type_def_int64.clone()); let blk_head_i2 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_head_i2.as_entity(), "blk_head_i2".to_string());
let blk_head_inst1 = func_ver.new_inst(vm.next_id(), Instruction { let blk_head_inst1 = func_ver.new_inst(vm.next_id(), Instruction {
value: Some(vec![blk_head_i2.clone_value()]), value: Some(vec![blk_head_i2.clone_value()]),
ops: RwLock::new(vec![blk_head_i.clone(), const_def_int64_1_local.clone()]), ops: RwLock::new(vec![blk_head_i.clone(), const_def_int64_1_local.clone()]),
...@@ -107,7 +113,8 @@ pub fn sum() -> VM { ...@@ -107,7 +113,8 @@ pub fn sum() -> VM {
}); });
// %cond = UGT %i %n // %cond = UGT %i %n
let blk_head_cond = func_ver.new_ssa(vm.next_id(), "blk_head_cond".to_string(), type_def_int1.clone()); let blk_head_cond = func_ver.new_ssa(vm.next_id(), type_def_int1.clone());
vm.set_name(blk_head_cond.as_entity(), "blk_head_cond".to_string());
let blk_head_inst2 = func_ver.new_inst(vm.next_id(), Instruction { let blk_head_inst2 = func_ver.new_inst(vm.next_id(), Instruction {
value: Some(vec![blk_head_cond.clone_value()]), value: Some(vec![blk_head_cond.clone_value()]),
ops: RwLock::new(vec![blk_head_i.clone(), blk_head_n.clone()]), ops: RwLock::new(vec![blk_head_i.clone(), blk_head_n.clone()]),
...@@ -142,7 +149,8 @@ pub fn sum() -> VM { ...@@ -142,7 +149,8 @@ pub fn sum() -> VM {
blk_head.content = Some(blk_head_content); blk_head.content = Some(blk_head_content);
// %ret(<@int_64> %s): // %ret(<@int_64> %s):
let blk_ret_s = func_ver.new_ssa(vm.next_id(), "blk_ret_s".to_string(), type_def_int64.clone()); let blk_ret_s = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_ret_s.as_entity(), "blk_ret_s".to_string());
// RET %s // RET %s
let blk_ret_term = func_ver.new_inst(vm.next_id(), Instruction{ let blk_ret_term = func_ver.new_inst(vm.next_id(), Instruction{
...@@ -224,11 +232,13 @@ pub fn factorial() -> VM { ...@@ -224,11 +232,13 @@ pub fn factorial() -> VM {
// %blk_0(<@int_64> %n_3): // %blk_0(<@int_64> %n_3):
let mut blk_0 = Block::new(vm.next_id()); let mut blk_0 = Block::new(vm.next_id());
vm.set_name(blk_0.as_entity(), "blk_0".to_string()); vm.set_name(blk_0.as_entity(), "blk_0".to_string());
let blk_0_n_3 = func_ver.new_ssa(vm.next_id(), "blk_0_n_3".to_string(), type_def_int64.clone()); let blk_0_n_3 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_0_n_3.as_entity(), "blk_0_n_3".to_string());
let const_def_int64_1_local = func_ver.new_constant(vm.next_id(), const_def_int64_1.clone()); let const_def_int64_1_local = func_ver.new_constant(vm.next_id(), const_def_int64_1.clone());
// %v48 = EQ <@int_64> %n_3 @int_64_1 // %v48 = EQ <@int_64> %n_3 @int_64_1