Commit bcc804b9 authored by qinsoon's avatar qinsoon

a few refactoring

parent 72f4cbd5
......@@ -11,7 +11,6 @@ use std::default;
use std::sync::RwLock;
use std::cell::Cell;
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use utils::Address;
pub type WPID = usize;
pub type MuID = usize;
......@@ -122,15 +121,14 @@ impl MuFunctionVersion {
self.content = Some(content)
}
pub fn new_ssa(&mut self, id: MuID, tag: MuName, ty: P<MuType>) -> P<TreeNode> {
self.context.value_tags.insert(tag.clone(), id);
self.context.values.insert(id, SSAVarEntry{id: id, name: Some(tag.clone()), ty: ty.clone(), use_count: Cell::new(0), expr: None});
pub fn new_ssa(&mut self, id: MuID, ty: P<MuType>) -> P<TreeNode> {
self.context.values.insert(id, SSAVarEntry::new(id, ty.clone()));
P(TreeNode {
hdr: MuEntityHeader::unnamed(id),
op: pick_op_code_for_ssa(&ty),
v: TreeNode_::Value(P(Value{
hdr: MuEntityHeader::named(id, tag),
hdr: MuEntityHeader::unnamed(id),
ty: ty,
v: Value_::SSAVar(id)
}))
......@@ -197,34 +195,16 @@ impl FunctionContent {
#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct FunctionContext {
pub value_tags: HashMap<MuName, MuID>,
pub values: HashMap<MuID, SSAVarEntry>
}
impl FunctionContext {
fn new() -> FunctionContext {
FunctionContext {
value_tags: 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> {
self.values.get(&id)
}
......@@ -536,21 +516,67 @@ pub enum Value_ {
Memory(MemoryLocation)
}
#[derive(Debug, RustcEncodable, RustcDecodable)]
#[derive(Debug)]
pub struct SSAVarEntry {
pub id: MuID,
pub name: Option<MuName>,
id: MuID,
pub ty: P<MuType>,
// how many times this entry is used
// availalbe after DefUse pass
pub use_count: Cell<usize>,
pub use_count: AtomicUsize,
// this field is only used during TreeGeneration pass
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 {
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) {
self.expr = Some(expr)
}
......@@ -558,11 +584,7 @@ impl SSAVarEntry {
impl fmt::Display for SSAVarEntry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.name.is_some() {
write!(f, "{} {}#{}", self.ty, self.name.as_ref().unwrap(), self.id)
} else {
write!(f, "{} {}#{}", self.ty, "???", self.id)
}
write!(f, "{} #{}", self.ty, self.id)
}
}
......
......@@ -36,10 +36,10 @@
//! 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.
use std::fmt::{self, Display, Debug};
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
//use std::fmt::{self, Display, Debug};
//use std::hash::{Hash, Hasher};
//use std::ops::Deref;
//use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::sync::Arc;
......
......@@ -6,8 +6,6 @@ use std::fmt;
use std::collections::HashMap;
use std::sync::RwLock;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
pub struct MuType {
pub hdr: MuEntityHeader,
......
......@@ -247,19 +247,10 @@ lazy_static! {
}
pub fn init_machine_regs_for_func (func_context: &mut FunctionContext) {
use std::cell::Cell;
for reg in ALL_MACHINE_REGs.values() {
let reg_id = reg.extract_ssa_id().unwrap();
let entry = SSAVarEntry {
id: reg_id,
name: reg.name(),
ty: reg.ty.clone(),
use_count: Cell::new(0),
expr: None
};
let entry = SSAVarEntry::new(reg_id, reg.ty.clone());
func_context.value_tags.insert(reg.name().unwrap(), reg_id);
func_context.values.insert(reg_id, entry);
}
}
......
......@@ -3,6 +3,7 @@ use ast::ptr::*;
use vm::VM;
use compiler::CompilerPass;
use std::sync::atomic::Ordering;
pub struct DefUse {
name: &'static str,
......@@ -27,7 +28,7 @@ fn use_value(val: &P<Value>, func_context: &mut FunctionContext) {
match val.v {
Value_::SSAVar(ref id) => {
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
}
......@@ -67,7 +68,7 @@ impl CompilerPass for DefUse {
debug!("check use count for variables");
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;
use compiler::CompilerPass;
use compiler::PassExecutionResult;
use std::sync::atomic::Ordering;
pub struct TreeGen {
name: &'static str
}
......@@ -77,7 +79,7 @@ impl CompilerPass for TreeGen {
// we can put the expression as a child node to its use
if left.len() == 1 {
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) {
lhs.expr = Some(inst.clone()); // FIXME: should be able to move the inst here
......
......@@ -2,6 +2,7 @@ use std::collections::HashMap;
use ast::ptr::P;
use ast::ir::*;
use ast::types;
use ast::types::*;
use compiler::backend;
use compiler::backend::BackendTypeInfo;
......@@ -14,9 +15,12 @@ use utils::Address;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::path;
use std::sync::RwLock;
use std::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT, Ordering};
use std::thread::JoinHandle;
use std::os::raw::c_char;
use std::sync::Arc;
pub struct VM {
// serialize
......@@ -57,7 +61,8 @@ const VM_SERIALIZE_FIELDS : usize = 12;
impl Encodable for VM {
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| {
// next_id
try!(s.emit_struct_field("next_id", 0, |s| {
......@@ -81,35 +86,40 @@ impl Encodable for VM {
let types = &self.types.read().unwrap();
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
{
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
{
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
{
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
{
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
{
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| {
let mut i = 0;
for (k,v) in funcs.iter() {
......@@ -126,7 +136,7 @@ impl Encodable for VM {
// func_vers
{
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| {
let mut i = 0;
for (k, v) in func_vers.iter() {
......@@ -143,12 +153,12 @@ impl Encodable for VM {
// primordial
{
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
{
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(())
......@@ -158,7 +168,7 @@ impl Encodable for VM {
impl Decodable for VM {
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
let next_id = try!(d.read_struct_field("next_id", 0, |d| {
d.read_usize()
......@@ -172,6 +182,16 @@ impl Decodable for VM {
// types
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
let backend_type_info = try!(d.read_struct_field("backend_type_info", 4, |d| Decodable::decode(d)));
......@@ -477,4 +497,23 @@ impl <'a> VM {
let mut threads = self.threads.write().unwrap();
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::*;
use self::mu::compiler::*;
use std::sync::Arc;
use std::sync::atomic::Ordering;
#[test]
fn test_use_count() {
......@@ -27,13 +28,13 @@ fn test_use_count() {
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_by_tag("blk_0_v48").unwrap().use_count.get() == 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_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_by_tag("blk_1_v50").unwrap().use_count.get() == 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_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_0_n_3")).unwrap().use_count.load(Ordering::SeqCst) == 2, "blk_0_n_3 use should be 2");
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(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(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(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(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(vm.id_of("blk_1_v52")).unwrap().use_count.load(Ordering::SeqCst) == 1, "blk_1_v52 use should be 1");
}
#[test]
......
......@@ -37,7 +37,7 @@ fn test_ir_liveness_fac() {
// block 0
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]));
let block_0_liveout = cf.mc.get_ir_block_liveout("blk_0").unwrap();
......@@ -46,17 +46,17 @@ fn test_ir_liveness_fac() {
// block 1
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]));
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]));
// block 2
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]));
let block_2_liveout = cf.mc.get_ir_block_liveout("blk_2").unwrap();
......
......@@ -61,7 +61,8 @@ pub fn sum() -> VM {
let mut blk_entry = Block::new(vm.next_id());
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_1_local = func_ver.new_constant(vm.next_id(), const_def_int64_1.clone());
......@@ -86,12 +87,16 @@ pub fn sum() -> VM {
// %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_s = func_ver.new_ssa(vm.next_id(), "blk_head_s".to_string(), type_def_int64.clone());
let blk_head_i = func_ver.new_ssa(vm.next_id(), "blk_head_i".to_string(), type_def_int64.clone());
let blk_head_n = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_head_n.as_entity(), "blk_head_n".to_string());
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
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 {
value: Some(vec![blk_head_s2.clone_value()]),
ops: RwLock::new(vec![blk_head_s.clone(), blk_head_i.clone()]),
......@@ -99,7 +104,8 @@ pub fn sum() -> VM {
});
// %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 {
value: Some(vec![blk_head_i2.clone_value()]),
ops: RwLock::new(vec![blk_head_i.clone(), const_def_int64_1_local.clone()]),
......@@ -107,7 +113,8 @@ pub fn sum() -> VM {
});
// %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 {
value: Some(vec![blk_head_cond.clone_value()]),
ops: RwLock::new(vec![blk_head_i.clone(), blk_head_n.clone()]),
......@@ -142,7 +149,8 @@ pub fn sum() -> VM {
blk_head.content = Some(blk_head_content);
// %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
let blk_ret_term = func_ver.new_inst(vm.next_id(), Instruction{
......@@ -224,11 +232,13 @@ pub fn factorial() -> VM {
// %blk_0(<@int_64> %n_3):
let mut blk_0 = Block::new(vm.next_id());
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());
// %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());
let blk_0_v48 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_0_v48.as_entity(), "blk_0_v48".to_string());
let blk_0_inst0 = func_ver.new_inst(vm.next_id(), Instruction {
value: Some(vec![blk_0_v48.clone_value()]),
ops: RwLock::new(vec![blk_0_n_3.clone(), const_def_int64_1_local.clone()]),
......@@ -265,7 +275,8 @@ pub fn factorial() -> VM {
blk_0.content = Some(blk_0_content);
// %blk_2(<@int_64> %v53):
let blk_2_v53 = func_ver.new_ssa(vm.next_id(), "blk_2_v53".to_string(), type_def_int64.clone());
let blk_2_v53 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_2_v53.as_entity(), "blk_2_v53".to_string());
// RET %v53
let blk_2_term = func_ver.new_inst(vm.next_id(), Instruction{
......@@ -282,10 +293,12 @@ pub fn factorial() -> VM {
blk_2.content = Some(blk_2_content);
// %blk_1(<@int_64> %n_3):
let blk_1_n_3 = func_ver.new_ssa(vm.next_id(), "blk_1_n_3".to_string(), type_def_int64.clone());
let blk_1_n_3 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_1_n_3.as_entity(), "blk_1_n_3".to_string());
// %v50 = SUB <@int_64> %n_3 @int_64_1
let blk_1_v50 = func_ver.new_ssa(vm.next_id(), "blk_1_v50".to_string(), type_def_int64.clone());
let blk_1_v50 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_1_v50.as_entity(), "blk_1_v50".to_string());
let blk_1_inst0 = func_ver.new_inst(vm.next_id(), Instruction{
value: Some(vec![blk_1_v50.clone_value()]),
ops: RwLock::new(vec![blk_1_n_3.clone(), const_def_int64_1_local.clone()]),
......@@ -293,7 +306,8 @@ pub fn factorial() -> VM {
});
// %v51 = CALL <@fac_sig> @fac (%v50)
let blk_1_v51 = func_ver.new_ssa(vm.next_id(), "blk_1_v51".to_string(), type_def_int64.clone());
let blk_1_v51 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_1_v51.as_entity(), "blk_1_v51".to_string());
let blk_1_fac = func_ver.new_constant(vm.next_id(), const_func_fac.clone());
let blk_1_inst1 = func_ver.new_inst(vm.next_id(), Instruction{
value: Some(vec![blk_1_v51.clone_value()]),
......@@ -309,7 +323,8 @@ pub fn factorial() -> VM {
});
// %v52 = MUL <@int_64> %n_3 %v51
let blk_1_v52 = func_ver.new_ssa(vm.next_id(), "blk_1_v52".to_string(), type_def_int64.clone());
let blk_1_v52 = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_1_v52.as_entity(), "blk_1_v52".to_string());
let blk_1_inst2 = func_ver.new_inst(vm.next_id(), Instruction{
value: Some(vec![blk_1_v52.clone_value()]),
ops: RwLock::new(vec![blk_1_n_3.clone(), blk_1_v51.clone()]),
......@@ -404,7 +419,8 @@ pub fn global_access() -> VM {
});
// %x = LOAD <@int_64> @a
let blk_0_x = func_ver.new_ssa(vm.next_id(), "blk_0_x".to_string(), type_def_int64.clone());
let blk_0_x = func_ver.new_ssa(vm.next_id(), type_def_int64.clone());
vm.set_name(blk_0_x.as_entity(), "blk_0_x".to_string());
let blk_0_inst1 = func_ver.new_inst(vm.next_id(), Instruction{
value: Some(vec![blk_0_x.clone_value()]),
ops: RwLock::new(vec![blk_0_a.clone()]),
......
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