WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit bcc804b9 authored by qinsoon's avatar qinsoon
Browse files

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