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
let blk_0_v48 = func_ver.new_ssa(vm.next_id(), "blk_0_v48".to_string(), type_def_int64.clone());