To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit 55d83865 authored by qinsoon's avatar qinsoon
Browse files

Merge remote-tracking branch 'origin/develop' into open-source

parents 25edf86a e9d49a43
.gitignore
**/target/*
**/__pycache__/*
**/.cache/*
......@@ -18,3 +19,5 @@ cmake-build-debug/*
Notes/*
CMakeLists.txt
*.iml
.rsync-filter
*.so
......@@ -28,26 +28,27 @@ aot = []
jit = []
[build-dependencies]
gcc = "0.3"
gcc = "*"
[dependencies]
ast = {path = "src/ast"}
utils = {path = "src/utils"}
gc = {path = "src/gc"}
field-offset = "0.1.1"
libloading = "0.3"
lazy_static = "0.1.15"
log = "0.3.5"
stderrlog = "0.2.2"
hprof = "0.1.3"
memmap = "0.4.0"
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal" }
libc="*"
field-offset = "*"
libloading = "*"
lazy_static = "*"
log = "*"
stderrlog = "*"
hprof = "*"
memmap = "*"
memsec = "0.1.9"
rustc-serialize = "*"
time = "0.1.34"
maplit = "0.1.4"
docopt = "0.6"
petgraph = "0.4.1"
serde = "*"
serde_derive = "*"
time = "*"
maplit = "*"
docopt = "*"
petgraph = "*"
extprim = "*"
num-traits = "*"
......@@ -22,7 +22,8 @@ crate-type = ["rlib"]
[dependencies]
utils = {path = "../utils"}
lazy_static = "0.1.15"
log = "0.3.5"
simple_logger = "0.4.0"
rustc-serialize = "*"
\ No newline at end of file
lazy_static = "*"
log = "*"
simple_logger = "*"
#rodal = {path = "../../rodal"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal" }
......@@ -22,7 +22,7 @@ use utils::vec_utils;
use std::fmt;
/// Instruction represents a Mu instruction
#[derive(Debug)] // RustcEncodable, RustcDecodable, Clone and Display
#[derive(Debug)] // this implements Clone and Display
pub struct Instruction {
pub hdr: MuEntityHeader,
/// the values this instruction holds
......@@ -38,43 +38,6 @@ pub struct Instruction {
// Instruction implements MuEntity
impl_mu_entity!(Instruction);
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
impl Encodable for Instruction {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("Instruction", 4, |s| {
try!(s.emit_struct_field("hdr", 0, |s| self.hdr.encode(s)));
try!(s.emit_struct_field("value", 1, |s| self.value.encode(s)));
let ref ops = self.ops;
try!(s.emit_struct_field("ops", 2, |s| ops.encode(s)));
try!(s.emit_struct_field("v", 3, |s| self.v.encode(s)));
Ok(())
})
}
}
impl Decodable for Instruction {
fn decode<D: Decoder>(d: &mut D) -> Result<Instruction, D::Error> {
d.read_struct("Instruction", 4, |d| {
let hdr = try!(d.read_struct_field("hdr", 0, |d| Decodable::decode(d)));
let value = try!(d.read_struct_field("value", 1, |d| Decodable::decode(d)));
let ops = try!(d.read_struct_field("ops", 2, |d| Decodable::decode(d)));
let v = try!(d.read_struct_field("v", 3, |d| Decodable::decode(d)));
Ok(Instruction{
hdr: hdr,
value: value,
ops: ops,
v: v
})
})
}
}
impl Clone for Instruction {
fn clone(&self) -> Self {
Instruction {
......@@ -129,6 +92,16 @@ impl Instruction {
| CommonInst_SetThreadLocal(_)
| CommonInst_Pin(_)
| CommonInst_Unpin(_)
| CommonInst_Tr64IsFp(_)
| CommonInst_Tr64IsInt(_)
| CommonInst_Tr64IsRef(_)
| CommonInst_Tr64FromFp(_)
| CommonInst_Tr64FromInt(_)
| CommonInst_Tr64FromRef(_, _)
| CommonInst_Tr64ToFp(_)
| CommonInst_Tr64ToInt(_)
| CommonInst_Tr64ToRef(_)
| CommonInst_Tr64ToTag(_)
| Move(_)
| PrintHex(_)
| SetRetval(_) => false,
......@@ -203,6 +176,16 @@ impl Instruction {
CommonInst_SetThreadLocal(_) => true,
CommonInst_Pin(_) => true,
CommonInst_Unpin(_) => true,
CommonInst_Tr64IsFp(_)
| CommonInst_Tr64IsInt(_)
| CommonInst_Tr64IsRef(_) => false,
CommonInst_Tr64FromFp(_)
| CommonInst_Tr64FromInt(_)
| CommonInst_Tr64FromRef(_, _) => false,
CommonInst_Tr64ToFp(_)
| CommonInst_Tr64ToInt(_)
| CommonInst_Tr64ToRef(_)
| CommonInst_Tr64ToTag(_) => false,
Move(_) => false,
PrintHex(_) => true,
SetRetval(_) => true,
......@@ -258,6 +241,16 @@ impl Instruction {
| CommonInst_SetThreadLocal(_)
| CommonInst_Pin(_)
| CommonInst_Unpin(_)
| CommonInst_Tr64IsFp(_)
| CommonInst_Tr64IsInt(_)
| CommonInst_Tr64IsRef(_)
| CommonInst_Tr64FromFp(_)
| CommonInst_Tr64FromInt(_)
| CommonInst_Tr64FromRef(_, _)
| CommonInst_Tr64ToFp(_)
| CommonInst_Tr64ToInt(_)
| CommonInst_Tr64ToRef(_)
| CommonInst_Tr64ToTag(_)
| Move(_)
| PrintHex(_)
| SetRetval(_) => false
......@@ -318,6 +311,16 @@ impl Instruction {
| CommonInst_SetThreadLocal(_)
| CommonInst_Pin(_)
| CommonInst_Unpin(_)
| CommonInst_Tr64IsFp(_)
| CommonInst_Tr64IsInt(_)
| CommonInst_Tr64IsRef(_)
| CommonInst_Tr64FromFp(_)
| CommonInst_Tr64FromInt(_)
| CommonInst_Tr64FromRef(_, _)
| CommonInst_Tr64ToFp(_)
| CommonInst_Tr64ToInt(_)
| CommonInst_Tr64ToRef(_)
| CommonInst_Tr64ToTag(_)
| Move(_)
| PrintHex(_)
| SetRetval(_) => None
......@@ -342,7 +345,7 @@ impl fmt::Display for Instruction {
/// Instruction_ is used for pattern matching for Instruction
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone)]
pub enum Instruction_ {
// non-terminal instruction
......@@ -570,6 +573,27 @@ pub enum Instruction_ {
/// common inst: unpin an object (the object is automatically managed by GC)
CommonInst_Unpin(OpIndex),
/// common inst: is the tagref a floating point?
CommonInst_Tr64IsFp(OpIndex),
/// common inst: is the tagref an int?
CommonInst_Tr64IsInt(OpIndex),
/// common inst: is the tagref a ref?
CommonInst_Tr64IsRef(OpIndex),
/// common inst: creates a tagref from floating point (double)
CommonInst_Tr64FromFp(OpIndex),
/// common inst: creates a tagref from int<52>
CommonInst_Tr64FromInt(OpIndex),
/// common inst: creates a tagref from reference (a ref-void typed ref, 6 bits tag)
CommonInst_Tr64FromRef(OpIndex, OpIndex),
/// common inst: converts a tagref to floating point (double)
CommonInst_Tr64ToFp(OpIndex),
/// common inst: converts a tagref to integer (int<52>)
CommonInst_Tr64ToInt(OpIndex),
/// common inst: converts a tagref to reference
CommonInst_Tr64ToRef(OpIndex),
/// common inst: converts a tagref to a tag (int<64>)
CommonInst_Tr64ToTag(OpIndex),
/// internal use: move from value to value
Move(OpIndex),
/// internal use: print op as hex value
......@@ -699,6 +723,18 @@ impl Instruction_ {
&Instruction_::CommonInst_Pin(op) => format!("COMMONINST Pin {}", ops[op]),
&Instruction_::CommonInst_Unpin(op) => format!("COMMONINST Unpin {}", ops[op]),
// Tagerf64
&Instruction_::CommonInst_Tr64IsFp (op) => format!("COMMONINST Tr64IsFp {}", ops[op]),
&Instruction_::CommonInst_Tr64IsInt (op) => format!("COMMONINST Tr64IsInt {}", ops[op]),
&Instruction_::CommonInst_Tr64IsRef (op) => format!("COMMONINST Tr64IsRef {}", ops[op]),
&Instruction_::CommonInst_Tr64FromFp (op) => format!("COMMONINST Tr64FromFp {}", ops[op]),
&Instruction_::CommonInst_Tr64FromInt(op) => format!("COMMONINST Tr64FromInt {}", ops[op]),
&Instruction_::CommonInst_Tr64FromRef(op1, op2) => format!("COMMONINST Tr64FromRet {} {}", ops[op1], ops[op2]),
&Instruction_::CommonInst_Tr64ToFp (op) => format!("COMMONINST Tr64ToFp {}", ops[op]),
&Instruction_::CommonInst_Tr64ToInt(op) => format!("COMMONINST Tr64ToInt {}", ops[op]),
&Instruction_::CommonInst_Tr64ToRef(op) => format!("COMMONINST Tr64ToRef {}", ops[op]),
&Instruction_::CommonInst_Tr64ToTag(op) => format!("COMMONINST Tr64ToTag {}", ops[op]),
// move
&Instruction_::Move(from) => format!("MOVE {}", ops[from]),
// print hex
......@@ -710,7 +746,7 @@ impl Instruction_ {
}
/// BinOpStatus represents status flags from a binary operation
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone)]
pub struct BinOpStatus {
/// negative flag
pub flag_n: bool,
......@@ -762,7 +798,7 @@ impl fmt::Debug for BinOpStatus {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum MemoryOrder {
NotAtomic,
Relaxed,
......@@ -773,18 +809,18 @@ pub enum MemoryOrder {
SeqCst
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum CallConvention {
Mu,
Foreign(ForeignFFI)
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum ForeignFFI {
C
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct CallData {
pub func: OpIndex,
pub args: Vec<OpIndex>,
......@@ -801,7 +837,7 @@ impl CallData {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct ResumptionData {
pub normal_dest: Destination,
pub exn_dest: Destination
......@@ -813,7 +849,7 @@ impl ResumptionData {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct Destination {
pub target: MuID,
pub args: Vec<DestArg>
......@@ -856,7 +892,7 @@ impl Destination {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub enum DestArg {
/// a normal destination argument is an SSA value (appears in the ops field of the instruction)
Normal(OpIndex),
......
......@@ -20,6 +20,7 @@ use utils::vec_utils;
use utils::LinkedHashMap;
use utils::LinkedHashSet;
use std;
use std::fmt;
use std::default;
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
......@@ -81,7 +82,7 @@ pub fn new_internal_id() -> MuID {
/// MuFunction represents a Mu function (not a specific definition of a function)
/// This stores function signature, and a list of all versions of this function (as ID),
/// and its current version (as ID)
#[derive(Debug, RustcEncodable, RustcDecodable)]
#[derive(Debug)]
pub struct MuFunction {
pub hdr: MuEntityHeader,
......@@ -90,6 +91,8 @@ pub struct MuFunction {
pub all_vers: Vec<MuID>
}
rodal_struct!(MuFunction{hdr, sig, cur_ver, all_vers});
impl MuFunction {
pub fn new(entity: MuEntityHeader, sig: P<MuFuncSig>) -> MuFunction {
MuFunction {
......@@ -122,7 +125,6 @@ impl fmt::Display for MuFunction {
// FIXME: currently part of compilation information is also stored in this data structure
// we should move them (see Issue #18)
#[derive(RustcEncodable, RustcDecodable)]
pub struct MuFunctionVersion {
pub hdr: MuEntityHeader,
......@@ -323,7 +325,7 @@ impl MuFunctionVersion {
}
/// FunctionContent contains all blocks (which include all instructions) for the function
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(Clone)]
pub struct FunctionContent {
pub entry: MuID,
pub blocks: LinkedHashMap<MuID, Block>,
......@@ -393,7 +395,7 @@ impl FunctionContent {
/// FunctionContext contains compilation information about the function
// FIXME: should move this out of ast crate and bind its lifetime with compilation (Issue #18)
#[derive(Default, Debug, RustcEncodable, RustcDecodable)]
#[derive(Default, Debug)]
pub struct FunctionContext {
pub values: LinkedHashMap<MuID, SSAVarEntry>
}
......@@ -442,7 +444,7 @@ impl FunctionContext {
/// Block contains BlockContent, which includes all the instructions for the block
// FIXME: control_flow field should be moved out of ast crate (Issue #18)
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Clone)]
pub struct Block {
pub hdr: MuEntityHeader,
pub content: Option<BlockContent>,
......@@ -488,7 +490,7 @@ impl Block {
/// ControlFlow stores compilation info about control flows of a block
// FIXME: Issue #18
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Clone)]
pub struct ControlFlow {
pub preds : Vec<MuID>,
pub succs : Vec<BlockEdge>
......@@ -530,7 +532,7 @@ impl default::Default for ControlFlow {
}
/// BlockEdge represents an edge in control flow graph
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub struct BlockEdge {
pub target: MuID,
pub kind: EdgeKind,
......@@ -544,13 +546,13 @@ impl fmt::Display for BlockEdge {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum EdgeKind {
Forward, Backward
}
/// BlockContent describes arguments to this block, and owns all the IR instructions
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Clone)]
pub struct BlockContent {
pub args: Vec<P<Value>>,
pub exn_arg: Option<P<Value>>,
......@@ -649,7 +651,7 @@ impl BlockContent {
/// TreeNode represents a node in the AST, it could either be an instruction,
/// or an value (SSA, constant, global, etc)
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Clone)]
pub struct TreeNode {
pub v: TreeNode_,
}
......@@ -735,7 +737,7 @@ impl fmt::Display for TreeNode {
}
/// TreeNode_ is used for pattern matching for TreeNode
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Clone)]
pub enum TreeNode_ {
Value(P<Value>),
Instruction(Instruction)
......@@ -746,13 +748,15 @@ pub enum TreeNode_ {
/// we need to represent memory as well)
///
/// Value should always be used with P<Value> (sharable)
#[derive(PartialEq, RustcEncodable, RustcDecodable)]
#[derive(PartialEq)]
pub struct Value {
pub hdr: MuEntityHeader,
pub ty: P<MuType>,
pub v: Value_
}
rodal_struct!(Value{hdr, ty, v});
impl Value {
/// creates an int constant value
pub fn make_int_const(id: MuID, val: u64) -> P<Value> {
......@@ -896,7 +900,7 @@ impl fmt::Display for Value {
}
/// Value_ is used for pattern matching for Value
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone, PartialEq)]
pub enum Value_ {
SSAVar(MuID),
Constant(Constant),
......@@ -904,6 +908,8 @@ pub enum Value_ {
Memory(MemoryLocation)
}
rodal_enum!(Value_{(SSAVar: id), (Constant: val), (Global: ty), (Memory: location)});
/// SSAVarEntry represent compilation info for an SSA variable
// FIXME: Issue#18
#[derive(Debug)]
......@@ -921,41 +927,6 @@ pub struct SSAVarEntry {
split: Option<Vec<P<Value>>>
}
impl Encodable for SSAVarEntry {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("SSAVarEntry", 3, |s| {
try!(s.emit_struct_field("val", 0, |s| self.val.encode(s)));
let count = self.use_count.load(Ordering::SeqCst);
try!(s.emit_struct_field("use_count", 1, |s| s.emit_usize(count)));
try!(s.emit_struct_field("expr", 2, |s| self.expr.encode(s)));
try!(s.emit_struct_field("split", 3, |s| self.split.encode(s)));
Ok(())
})
}
}
impl Decodable for SSAVarEntry {
fn decode<D: Decoder>(d: &mut D) -> Result<SSAVarEntry, D::Error> {
d.read_struct("SSAVarEntry", 3, |d| {
let val = try!(d.read_struct_field("val", 0, |d| Decodable::decode(d)));
let count = try!(d.read_struct_field("use_count", 1, |d| d.read_usize()));
let expr = try!(d.read_struct_field("expr", 2, |d| Decodable::decode(d)));
let split = try!(d.read_struct_field("split", 3, |d| Decodable::decode(d)));
let ret = SSAVarEntry {
val: val,
use_count: ATOMIC_USIZE_INIT,
expr: expr,
split: split
};
ret.use_count.store(count, Ordering::SeqCst);
Ok(ret)
})
}
}
impl SSAVarEntry {
pub fn new(val: P<Value>) -> SSAVarEntry {
let ret = SSAVarEntry {
......@@ -1017,7 +988,7 @@ impl fmt::Display for SSAVarEntry {
}
/// Constant presents all kinds of constant that can appear in MuIR
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone, PartialEq)]
pub enum Constant {
/// all integer constants are stored as u64
Int(u64),
......@@ -1038,6 +1009,9 @@ pub enum Constant {
List(Vec<P<Value>>)
}
rodal_enum!(Constant{(Int: val), (IntEx: val), (Float: val), (Double: val), (FuncRef: val),
(Vector: val), NullRef, (ExternSym: val), (List: val)});
impl fmt::Display for Constant {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
......@@ -1074,11 +1048,11 @@ impl fmt::Display for Constant {
/// MemoryLocation represents a memory value
/// This enumerate type is target dependent
#[cfg(target_arch = "x86_64")]
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone, PartialEq)]
pub enum MemoryLocation {
/// addr = base + offset + index * scale
Address{
base: P<Value>,
base: P<Value>, // +8
offset: Option<P<Value>>,
index: Option<P<Value>>,
scale: Option<u8>
......@@ -1091,6 +1065,9 @@ pub enum MemoryLocation {
}
}
#[cfg(target_arch = "x86_64")]
rodal_enum!(MemoryLocation{{Address: scale, base, offset, index}, {Symbolic: is_global, base, label}});
#[cfg(target_arch = "x86_64")]
impl fmt::Display for MemoryLocation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
......@@ -1122,17 +1099,17 @@ impl fmt::Display for MemoryLocation {
/// MemoryLocation represents a memory value
/// This enumerate type is target dependent
#[cfg(target_arch = "aarch64")]
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone, PartialEq)]
pub enum MemoryLocation {
/// Represents how an address should be computed,
/// will need to be converted to a real Address before being used
VirtualAddress{
/// Represents base + offset*scale
/// With offset being inerpreted as signed if 'signed' is true
base: P<Value>,
offset: Option<P<Value>>,
scale: u64,
signed: bool
/// With offset being interpreted as signed if 'signed' is true
base: P<Value>, //+8
offset: Option<P<Value>>, //+16
signed: bool, //+1
scale: u64 //+24
},
Address{
/// Must be a normal 64-bit register or SP
......@@ -1194,6 +1171,8 @@ pub struct MuEntityHeader {
name: Option<MuName>
}
rodal_struct!(MuEntityHeader{id, name});
impl Clone for MuEntityHeader {
fn clone(&self) -> Self {
MuEntityHeader {
......@@ -1203,34 +1182,6 @@ impl Clone for MuEntityHeader {
}
}
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
impl Encodable for MuEntityHeader {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("MuEntityHeader", 2, |s| {
try!(s.emit_struct_field("id", 0, |s| self.id.encode(s)));
let name = &self.name;
try!(s.emit_struct_field("name", 1, |s| name.encode(s)));
Ok(())
})
}
}
impl Decodable for MuEntityHeader {
fn decode<D: Decoder>(d: &mut D) -> Result<MuEntityHeader, D::Error> {
d.read_struct("MuEntityHeader", 2, |d| {
let id = try!(d.read_struct_field("id", 0, |d| {d.read_usize()}));
let name = try!(d.read_struct_field("name", 1, |d| Decodable::decode(d)));
Ok(MuEntityHeader{
id: id,
name: name
})
})
}
}
/// turns a client supplied name into a valid name for internal use and code generation.
/// The name should not contain special characters that may be escaped.
/// This name is stored with every Mu Entity while the original name from client is
......
......@@ -30,11 +30,11 @@
//!
//! Client should not create MuIR via this crate, use API instead.
extern crate log;
#[macro_use]
extern crate rodal;
extern crate simple_logger;
#[macro_use]
extern crate lazy_static;
extern crate rustc_serialize;
extern crate utils;
/// all data structures for MuIR is an *MuEntity*
......
......@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BinOp {
// BinOp Int(n) Int(n) -> Int(n)
Add,
......@@ -39,7 +39,7 @@ pub enum BinOp {
FRem
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]