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.

Commit e716d22f authored by qinsoon's avatar qinsoon
Browse files

[wip] refactoring: type

parent cee7d9be
...@@ -17,6 +17,12 @@ pub type Address = usize; // TODO: replace this with Address(usize) ...@@ -17,6 +17,12 @@ pub type Address = usize; // TODO: replace this with Address(usize)
pub type OpIndex = usize; pub type OpIndex = usize;
pub const MACHINE_ID_START : usize = 0;
pub const MACHINE_ID_END : usize = 100;
pub const INTERNAL_ID_START: usize = 101;
pub const INTERNAL_ID_END : usize = 200;
pub const USER_ID_START : usize = 201;
#[derive(Debug)] #[derive(Debug)]
pub struct MuFunction { pub struct MuFunction {
pub id: MuID, pub id: MuID,
...@@ -72,8 +78,6 @@ impl fmt::Display for MuFunctionVersion { ...@@ -72,8 +78,6 @@ impl fmt::Display for MuFunctionVersion {
} }
} }
pub const RESERVED_NODE_IDS_FOR_MACHINE : usize = 100;
impl MuFunctionVersion { impl MuFunctionVersion {
pub fn new(id: MuID, func: MuID, sig: P<MuFuncSig>) -> MuFunctionVersion { pub fn new(id: MuID, func: MuID, sig: P<MuFuncSig>) -> MuFunctionVersion {
MuFunctionVersion{ MuFunctionVersion{
...@@ -468,9 +472,9 @@ impl Value { ...@@ -468,9 +472,9 @@ impl Value {
pub fn is_int_const(&self) -> bool { pub fn is_int_const(&self) -> bool {
match self.v { match self.v {
Value_::Constant(_) => { Value_::Constant(_) => {
let ty : &MuType_ = &self.ty; let ty : &MuType = &self.ty;
match ty { match ty.v {
&MuType_::Int(_) => true, MuType_::Int(_) => true,
_ => false _ => false
} }
} }
......
...@@ -56,59 +56,59 @@ pub enum OpCode { ...@@ -56,59 +56,59 @@ pub enum OpCode {
pub fn pick_op_code_for_ssa(ty: &P<MuType>) -> OpCode { pub fn pick_op_code_for_ssa(ty: &P<MuType>) -> OpCode {
use ast::types::MuType_::*; use ast::types::MuType_::*;
let a : &MuType_ = ty; let a : &MuType = ty;
match a { match a.v {
// currently use i64 for all ints // currently use i64 for all ints
&Int(_) => OpCode::RegI64, Int(_) => OpCode::RegI64,
// currently do not differentiate float and double // currently do not differentiate float and double
&Float Float
| &Double => OpCode::RegFP, | Double => OpCode::RegFP,
// ref and pointer types use RegI64 // ref and pointer types use RegI64
&Ref(_) Ref(_)
| &IRef(_) | IRef(_)
| &WeakRef(_) | WeakRef(_)
| &UPtr(_) | UPtr(_)
| &ThreadRef | ThreadRef
| &StackRef | StackRef
| &Tagref64 | Tagref64
| &FuncRef(_) | FuncRef(_)
| &UFuncPtr(_) => OpCode::RegI64, | UFuncPtr(_) => OpCode::RegI64,
// we are not supposed to have these as SSA // we are not supposed to have these as SSA
&Struct(_) Struct(_)
| &Array(_, _) | Array(_, _)
| &Hybrid(_, _) | Hybrid(_, _)
| &Void => panic!("Not expecting {} as SSA", ty), | Void => panic!("Not expecting {} as SSA", ty),
// unimplemented // unimplemented
&Vector(_, _) => unimplemented!() Vector(_, _) => unimplemented!()
} }
} }
pub fn pick_op_code_for_value(ty: &P<MuType>) -> OpCode { pub fn pick_op_code_for_value(ty: &P<MuType>) -> OpCode {
use ast::types::MuType_::*; use ast::types::MuType_::*;
let a : &MuType_ = ty; let a : &MuType = ty;
match a { match a.v {
// currently use i64 for all ints // currently use i64 for all ints
&Int(_) => OpCode::IntImmI64, Int(_) => OpCode::IntImmI64,
// currently do not differentiate float and double // currently do not differentiate float and double
&Float Float
| &Double => OpCode::FPImm, | Double => OpCode::FPImm,
// ref and pointer types use RegI64 // ref and pointer types use RegI64
&Ref(_) Ref(_)
| &IRef(_) | IRef(_)
| &WeakRef(_) | WeakRef(_)
| &UPtr(_) | UPtr(_)
| &ThreadRef | ThreadRef
| &StackRef | StackRef
| &Tagref64 | Tagref64
| &FuncRef(_) | FuncRef(_)
| &UFuncPtr(_) => OpCode::IntImmI64, | UFuncPtr(_) => OpCode::IntImmI64,
// we are not supposed to have these as SSA // we are not supposed to have these as SSA
&Struct(_) Struct(_)
| &Array(_, _) | Array(_, _)
| &Hybrid(_, _) | Hybrid(_, _)
| &Void => unimplemented!(), | Void => unimplemented!(),
// unimplemented // unimplemented
&Vector(_, _) => unimplemented!() Vector(_, _) => unimplemented!()
} }
} }
......
...@@ -6,7 +6,22 @@ use std::fmt; ...@@ -6,7 +6,22 @@ use std::fmt;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::RwLock; use std::sync::RwLock;
pub type MuType = MuType_; #[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct MuType {
pub id: MuID,
pub name: Option<MuName>,
pub v: MuType_
}
impl MuType {
pub fn new(id: MuID, v: MuType_) -> MuType {
MuType {
id: id,
name: None,
v: v
}
}
}
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub enum MuType_ { pub enum MuType_ {
...@@ -57,6 +72,12 @@ pub enum MuType_ { ...@@ -57,6 +72,12 @@ pub enum MuType_ {
UFuncPtr (P<MuFuncSig>), UFuncPtr (P<MuFuncSig>),
} }
impl fmt::Display for MuType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.v)
}
}
impl fmt::Display for MuType_ { impl fmt::Display for MuType_ {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
...@@ -88,7 +109,7 @@ lazy_static! { ...@@ -88,7 +109,7 @@ lazy_static! {
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
pub struct StructType_ { pub struct StructType_ {
tys: Vec<P<MuType_>> tys: Vec<P<MuType>>
} }
impl fmt::Display for StructType_ { impl fmt::Display for StructType_ {
...@@ -111,7 +132,7 @@ impl StructType_ { ...@@ -111,7 +132,7 @@ impl StructType_ {
self.tys.append(&mut list); self.tys.append(&mut list);
} }
pub fn get_tys(&self) -> &Vec<P<MuType_>> { pub fn get_tys(&self) -> &Vec<P<MuType>> {
&self.tys &self.tys
} }
} }
...@@ -126,19 +147,16 @@ impl MuType_ { ...@@ -126,19 +147,16 @@ impl MuType_ {
pub fn double() -> MuType_ { pub fn double() -> MuType_ {
MuType_::Double MuType_::Double
} }
pub fn muref(referent: P<MuType_>) -> MuType_ { pub fn muref(referent: P<MuType>) -> MuType_ {
MuType_::Ref(referent) MuType_::Ref(referent)
} }
pub fn muref_void() -> MuType_ { pub fn iref(referent: P<MuType>) -> MuType_ {
MuType_::Ref(P(MuType_::void()))
}
pub fn iref(referent: P<MuType_>) -> MuType_ {
MuType_::IRef(referent) MuType_::IRef(referent)
} }
pub fn weakref(referent: P<MuType_>) -> MuType_ { pub fn weakref(referent: P<MuType>) -> MuType_ {
MuType_::WeakRef(referent) MuType_::WeakRef(referent)
} }
pub fn uptr(referent: P<MuType_>) -> MuType_ { pub fn uptr(referent: P<MuType>) -> MuType_ {
MuType_::UPtr(referent) MuType_::UPtr(referent)
} }
pub fn mustruct_empty(tag: MuName) -> MuType_ { pub fn mustruct_empty(tag: MuName) -> MuType_ {
...@@ -147,7 +165,7 @@ impl MuType_ { ...@@ -147,7 +165,7 @@ impl MuType_ {
MuType_::Struct(tag) MuType_::Struct(tag)
} }
pub fn mustruct(tag: MuName, list: Vec<P<MuType_>>) -> MuType_ { pub fn mustruct(tag: MuName, list: Vec<P<MuType>>) -> MuType_ {
let struct_ty_ = StructType_{tys: list}; let struct_ty_ = StructType_{tys: list};
// if there is an attempt to use a same tag for different struct, // if there is an attempt to use a same tag for different struct,
...@@ -167,10 +185,10 @@ impl MuType_ { ...@@ -167,10 +185,10 @@ impl MuType_ {
MuType_::Struct(tag) MuType_::Struct(tag)
} }
pub fn array(ty: P<MuType_>, len: usize) -> MuType_ { pub fn array(ty: P<MuType>, len: usize) -> MuType_ {
MuType_::Array(ty, len) MuType_::Array(ty, len)
} }
pub fn hybrid(fix_tys: Vec<P<MuType_>>, var_ty: P<MuType_>) -> MuType_ { pub fn hybrid(fix_tys: Vec<P<MuType>>, var_ty: P<MuType>) -> MuType_ {
MuType_::Hybrid(fix_tys, var_ty) MuType_::Hybrid(fix_tys, var_ty)
} }
pub fn void() -> MuType_ { pub fn void() -> MuType_ {
...@@ -185,7 +203,7 @@ impl MuType_ { ...@@ -185,7 +203,7 @@ impl MuType_ {
pub fn tagref64() -> MuType_ { pub fn tagref64() -> MuType_ {
MuType_::Tagref64 MuType_::Tagref64
} }
pub fn vector(ty: P<MuType_>, len: usize) -> MuType_ { pub fn vector(ty: P<MuType>, len: usize) -> MuType_ {
MuType_::Vector(ty, len) MuType_::Vector(ty, len)
} }
pub fn funcref(sig: P<MuFuncSig>) -> MuType_ { pub fn funcref(sig: P<MuFuncSig>) -> MuType_ {
...@@ -198,7 +216,7 @@ impl MuType_ { ...@@ -198,7 +216,7 @@ impl MuType_ {
/// is a type floating-point type? /// is a type floating-point type?
pub fn is_fp(ty: &MuType) -> bool { pub fn is_fp(ty: &MuType) -> bool {
match *ty { match ty.v {
MuType_::Float | MuType_::Double => true, MuType_::Float | MuType_::Double => true,
_ => false _ => false
} }
...@@ -206,7 +224,7 @@ pub fn is_fp(ty: &MuType) -> bool { ...@@ -206,7 +224,7 @@ pub fn is_fp(ty: &MuType) -> bool {
/// is a type raw pointer? /// is a type raw pointer?
pub fn is_ptr(ty: &MuType) -> bool { pub fn is_ptr(ty: &MuType) -> bool {
match *ty { match ty.v {
MuType_::UPtr(_) | MuType_::UFuncPtr(_) => true, MuType_::UPtr(_) | MuType_::UFuncPtr(_) => true,
_ => false _ => false
} }
...@@ -214,7 +232,7 @@ pub fn is_ptr(ty: &MuType) -> bool { ...@@ -214,7 +232,7 @@ pub fn is_ptr(ty: &MuType) -> bool {
/// is a type scalar type? /// is a type scalar type?
pub fn is_scalar(ty: &MuType) -> bool { pub fn is_scalar(ty: &MuType) -> bool {
match *ty { match ty.v {
MuType_::Int(_) MuType_::Int(_)
| MuType_::Float | MuType_::Float
| MuType_::Double | MuType_::Double
...@@ -234,7 +252,7 @@ pub fn is_scalar(ty: &MuType) -> bool { ...@@ -234,7 +252,7 @@ pub fn is_scalar(ty: &MuType) -> bool {
/// is a type traced by the garbage collector? /// is a type traced by the garbage collector?
/// Note: An aggregated type is traced if any of its part is traced. /// Note: An aggregated type is traced if any of its part is traced.
pub fn is_traced(ty: &MuType) -> bool { pub fn is_traced(ty: &MuType) -> bool {
match *ty { match ty.v {
MuType_::Ref(_) => true, MuType_::Ref(_) => true,
MuType_::IRef(_) => true, MuType_::IRef(_) => true,
MuType_::WeakRef(_) => true, MuType_::WeakRef(_) => true,
...@@ -263,7 +281,7 @@ pub fn is_traced(ty: &MuType) -> bool { ...@@ -263,7 +281,7 @@ pub fn is_traced(ty: &MuType) -> bool {
/// is a type native safe? /// is a type native safe?
/// Note: An aggregated type is native safe if all of its parts are native safe. /// Note: An aggregated type is native safe if all of its parts are native safe.
pub fn is_native_safe(ty: &MuType) -> bool { pub fn is_native_safe(ty: &MuType) -> bool {
match *ty { match ty.v {
MuType_::Int(_) => true, MuType_::Int(_) => true,
MuType_::Float => true, MuType_::Float => true,
MuType_::Double => true, MuType_::Double => true,
...@@ -290,10 +308,10 @@ pub fn is_native_safe(ty: &MuType) -> bool { ...@@ -290,10 +308,10 @@ pub fn is_native_safe(ty: &MuType) -> bool {
} }
pub fn get_referent_ty(ty: &MuType) -> Option<P<MuType>> { pub fn get_referent_ty(ty: &MuType) -> Option<P<MuType>> {
match ty { match ty.v {
&MuType_::Ref(ref referent) MuType_::Ref(ref referent)
| &MuType_::IRef(ref referent) | MuType_::IRef(ref referent)
| &MuType_::WeakRef(ref referent) => Some(referent.clone()), | MuType_::WeakRef(ref referent) => Some(referent.clone()),
_ => None _ => None
} }
} }
......
...@@ -496,7 +496,7 @@ impl ASMCodeGen { ...@@ -496,7 +496,7 @@ impl ASMCodeGen {
fn asm_reg_op(&self, op: &P<Value>) -> String { fn asm_reg_op(&self, op: &P<Value>) -> String {
let id = op.extract_ssa_id().unwrap(); let id = op.extract_ssa_id().unwrap();
if id < RESERVED_NODE_IDS_FOR_MACHINE { if id < MACHINE_ID_END {
// machine reg // machine reg
format!("%{}", op.name.unwrap()) format!("%{}", op.name.unwrap())
} else { } else {
......
...@@ -7,7 +7,7 @@ use ast::inst::Instruction_; ...@@ -7,7 +7,7 @@ use ast::inst::Instruction_;
use ast::inst::MemoryOrder; use ast::inst::MemoryOrder;
use ast::op; use ast::op;
use ast::types; use ast::types;
use ast::types::MuType_; use ast::types::*;
use vm::VM; use vm::VM;
use vm::CompiledFunction; use vm::CompiledFunction;
...@@ -113,10 +113,10 @@ impl <'a> InstructionSelection { ...@@ -113,10 +113,10 @@ impl <'a> InstructionSelection {
let ref func = ops[data.func]; let ref func = ops[data.func];
let ref func_sig = match func.v { let ref func_sig = match func.v {
TreeNode_::Value(ref pv) => { TreeNode_::Value(ref pv) => {
let ty : &MuType_ = &pv.ty; let ty : &MuType = &pv.ty;
match ty { match ty.v {
&MuType_::FuncRef(ref sig) MuType_::FuncRef(ref sig)
| &MuType_::UFuncPtr(ref sig) => sig, | MuType_::UFuncPtr(ref sig) => sig,
_ => panic!("expected funcref/ptr type") _ => panic!("expected funcref/ptr type")
} }
}, },
......
...@@ -39,8 +39,8 @@ macro_rules! FPR { ...@@ -39,8 +39,8 @@ macro_rules! FPR {
} }
lazy_static! { lazy_static! {
pub static ref GPR_TY : P<MuType> = P(MuType::int(64)); pub static ref GPR_TY : P<MuType> = P(MuType::new(INTERNAL_ID_START + 0, MuType_::int(64)));
pub static ref FPR_TY : P<MuType> = P(MuType::double()); pub static ref FPR_TY : P<MuType> = P(MuType::new(INTERNAL_ID_START + 1, MuType_::double()));
} }
// put into several segments to avoid 'recursion limit reached' error // put into several segments to avoid 'recursion limit reached' error
......
...@@ -43,9 +43,9 @@ use vm::VM; ...@@ -43,9 +43,9 @@ use vm::VM;
use ast::types::*; use ast::types::*;
use ast::ptr::*; use ast::ptr::*;
pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo { pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo {
match ty { match ty.v {
// integral // integral
&MuType_::Int(size_in_bit) => { MuType_::Int(size_in_bit) => {
match size_in_bit { match size_in_bit {
8 => BackendTypeInfo{size: 1, alignment: 1, struct_layout: None}, 8 => BackendTypeInfo{size: 1, alignment: 1, struct_layout: None},
16 => BackendTypeInfo{size: 2, alignment: 2, struct_layout: None}, 16 => BackendTypeInfo{size: 2, alignment: 2, struct_layout: None},
...@@ -55,26 +55,26 @@ pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo { ...@@ -55,26 +55,26 @@ pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo {
} }
}, },
// pointer of any type // pointer of any type
&MuType_::Ref(_) MuType_::Ref(_)
| &MuType_::IRef(_) | MuType_::IRef(_)
| &MuType_::WeakRef(_) | MuType_::WeakRef(_)
| &MuType_::UPtr(_) | MuType_::UPtr(_)
| &MuType_::FuncRef(_) | MuType_::FuncRef(_)
| &MuType_::UFuncPtr(_) | MuType_::UFuncPtr(_)
| &MuType_::Tagref64 | MuType_::Tagref64
| &MuType_::ThreadRef | MuType_::ThreadRef
| &MuType_::StackRef => BackendTypeInfo{size: 8, alignment: 8, struct_layout: None}, | MuType_::StackRef => BackendTypeInfo{size: 8, alignment: 8, struct_layout: None},
// floating point // floating point
&MuType_::Float => BackendTypeInfo{size: 4, alignment: 4, struct_layout: None}, MuType_::Float => BackendTypeInfo{size: 4, alignment: 4, struct_layout: None},
&MuType_::Double => BackendTypeInfo{size: 8, alignment: 8, struct_layout: None}, MuType_::Double => BackendTypeInfo{size: 8, alignment: 8, struct_layout: None},
// array // array
&MuType_::Array(ref ty, len) => { MuType_::Array(ref ty, len) => {
let ele_ty = vm.get_backend_type_info(ty); let ele_ty = vm.get_backend_type_info(ty);
BackendTypeInfo{size: ele_ty.size * len, alignment: ele_ty.alignment, struct_layout: None} BackendTypeInfo{size: ele_ty.size * len, alignment: ele_ty.alignment, struct_layout: None}
} }
// struct // struct
&MuType_::Struct(name) => { MuType_::Struct(name) => {
let read_lock = STRUCT_TAG_MAP.read().unwrap(); let read_lock = STRUCT_TAG_MAP.read().unwrap();
let struc = read_lock.get(name).unwrap(); let struc = read_lock.get(name).unwrap();
let tys = struc.get_tys(); let tys = struc.get_tys();
...@@ -86,7 +86,7 @@ pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo { ...@@ -86,7 +86,7 @@ pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo {
// - align is the most strict aligned element (from all fix tys and var ty) // - align is the most strict aligned element (from all fix tys and var ty)
// - size is fixed tys size // - size is fixed tys size
// - layout is fixed tys layout // - layout is fixed tys layout
&MuType_::Hybrid(ref fix_tys, ref var_ty) => { MuType_::Hybrid(ref fix_tys, ref var_ty) => {
// treat fix_tys as struct // treat fix_tys as struct
let mut ret = layout_struct(fix_tys, vm); let mut ret = layout_struct(fix_tys, vm);
...@@ -100,13 +100,13 @@ pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo { ...@@ -100,13 +100,13 @@ pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo {
ret ret
} }
// void // void
&MuType_::Void => BackendTypeInfo{size: 0, alignment: 8, struct_layout: None}, MuType_::Void => BackendTypeInfo{size: 0, alignment: 8, struct_layout: None},
// vector // vector
&MuType_::Vector(_, _) => unimplemented!() MuType_::Vector(_, _) => unimplemented!()
} }
} }
fn layout_struct(tys: &Vec<P<MuType_>>, vm: &VM) -> BackendTypeInfo { fn layout_struct(tys: &Vec<P<MuType>>, vm: &VM) -> BackendTypeInfo {
let mut offsets : Vec<ByteSize> = vec![]; let mut offsets : Vec<ByteSize> = vec![];
let mut cur : ByteSize = 0; let mut cur : ByteSize = 0;
let mut struct_align : ByteSize = 0; let mut struct_align : ByteSize = 0;
......
...@@ -254,7 +254,7 @@ impl InterferenceGraph { ...@@ -254,7 +254,7 @@ impl InterferenceGraph {
} }
pub fn is_machine_reg(reg: MuID) -> bool { pub fn is_machine_reg(reg: MuID) -> bool {
if reg < RESERVED_NODE_IDS_FOR_MACHINE { if reg < MACHINE_ID_END {
true true
} else { } else {
false false
......
...@@ -48,7 +48,7 @@ impl RegisterAllocation { ...@@ -48,7 +48,7 @@ impl RegisterAllocation {
let temp = coloring.ig.get_temp_of(node); let temp = coloring.ig.get_temp_of(node);
// skip machine registers // skip machine registers
if temp < RESERVED_NODE_IDS_FOR_MACHINE { if temp < MACHINE_ID_END {
continue; continue;
} else { } else {
let alias = coloring.get_alias(node); let alias = coloring.get_alias(node);
......
...@@ -444,4 +444,5 @@ macro_rules! mu_entity { ...@@ -444,4 +444,5 @@ macro_rules! mu_entity {
mu_entity!(MuFunction); mu_entity!(MuFunction);
mu_entity!(MuFunctionVersion); mu_entity!(MuFunctionVersion);
mu_entity!(Block); mu_entity!(Block);
mu_entity!(TreeNode); mu_entity!(TreeNode);
\ No newline at end of file mu_entity!(MuType);
\ No newline at end of file
...@@ -9,6 +9,7 @@ use compiler::backend; ...@@ -9,6 +9,7 @@ use compiler::backend;
use compiler::backend::BackendTypeInfo; use compiler::backend::BackendTypeInfo;
use vm::machine_code::CompiledFunction; use vm::machine_code::CompiledFunction;