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 9fd01dde authored by qinsoon's avatar qinsoon
Browse files

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

parents 9c4ed439 ca642057
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
name = "mu"
version = "0.0.1"
......@@ -21,6 +35,7 @@ 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"
......@@ -34,4 +49,5 @@ time = "0.1.34"
maplit = "0.1.4"
docopt = "0.6"
petgraph = "0.4.1"
extprim = "*"
\ No newline at end of file
extprim = "*"
num-traits = "*"
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
extern crate gcc;
#[cfg(any(target_os = "macos", target_os = "linux"))]
......
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
if [ -z "$MU_ZEBU" ]
then
export MU_ZEBU=$PWD
fi
export MU_LOG_LEVEL=none
export RUST_TEST_THREADS=1
export RUST_BACKTRACE=0
export PYTHONPATH="$MU_ZEBU/tests/test_jit/mu-client-pypy/:$MU_ZEBU/tests/test_jit/RPySOM/src"
export LD_LIBRARY_PATH="$MU_ZEBU/tests/test_jit/:$MU_ZEBU/tests/test_jit"
export ZEBU_BUILD=release
rm -rf $MU_ZEBU/emit
rm -rf $MU_ZEBU/tests/test_jit/emit
#cargo clean
cargo test --release --no-run --color=always 2>&1 | tee build_out.txt
/usr/bin/time -f "finished in %e secs" -a -o cargo_test_out.txt ./test-release --color=always 2>/dev/null | tee cargo_test_out.txt
cd $MU_ZEBU/tests/test_jit/mu-client-pypy
git pull
cd $MU_ZEBU/tests/test_jit/RPySOM
git pull
cd $MU_ZEBU/tests/test_jit/
ZEBU_BUILD=release LD_LIBRARY_PATH=. PYTHONPATH=mu-client-pypy:RPySOM/src pytest test_*.py -v --color=yes 2>&1 | tee $MU_ZEBU/pytest_out.txt
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
name = "ast"
version = "0.0.1"
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use ir::*;
use ptr::*;
use types::*;
......@@ -116,7 +130,8 @@ impl Instruction {
| CommonInst_Pin(_)
| CommonInst_Unpin(_)
| Move(_)
| PrintHex(_) => false,
| PrintHex(_)
| SetRetval(_) => false,
Return(_)
| ThreadExit
| Throw(_)
......@@ -189,7 +204,8 @@ impl Instruction {
CommonInst_Pin(_) => true,
CommonInst_Unpin(_) => true,
Move(_) => false,
PrintHex(_) => true
PrintHex(_) => true,
SetRetval(_) => true,
}
}
......@@ -243,7 +259,8 @@ impl Instruction {
| CommonInst_Pin(_)
| CommonInst_Unpin(_)
| Move(_)
| PrintHex(_) => false
| PrintHex(_)
| SetRetval(_) => false
}
}
......@@ -302,7 +319,8 @@ impl Instruction {
| CommonInst_Pin(_)
| CommonInst_Unpin(_)
| Move(_)
| PrintHex(_) => None
| PrintHex(_)
| SetRetval(_) => None
}
}
......@@ -555,7 +573,9 @@ pub enum Instruction_ {
/// internal use: move from value to value
Move(OpIndex),
/// internal use: print op as hex value
PrintHex(OpIndex)
PrintHex(OpIndex),
/// internal use: set return value for main
SetRetval(OpIndex)
}
impl Instruction_ {
......@@ -682,7 +702,9 @@ impl Instruction_ {
// move
&Instruction_::Move(from) => format!("MOVE {}", ops[from]),
// print hex
&Instruction_::PrintHex(i) => format!("PRINTHEX {}", ops[i])
&Instruction_::PrintHex(i) => format!("PRINTHEX {}", ops[i]),
// set retval
&Instruction_::SetRetval(val) => format!("SETRETVAL {}", ops[val]),
}
}
}
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use ptr::P;
use types::*;
use inst::*;
......@@ -781,6 +795,14 @@ impl Value {
})
}
pub fn is_int_ex_const(&self) -> bool {
match self.v {
Value_::Constant(Constant::IntEx(_)) => true,
_ => false
}
}
pub fn is_int_const(&self) -> bool {
match self.v {
Value_::Constant(Constant::Int(_)) => true,
......@@ -788,6 +810,14 @@ impl Value {
_ => false
}
}
pub fn is_fp_const(&self) -> bool {
match self.v {
Value_::Constant(Constant::Float(_)) => true,
Value_::Constant(Constant::Double(_)) => true,
_ => false
}
}
pub fn extract_int_const(&self) -> Option<u64> {
match self.v {
......@@ -797,6 +827,13 @@ impl Value {
}
}
pub fn extract_int_ex_const(&self) -> Vec<u64> {
match self.v {
Value_::Constant(Constant::IntEx(ref val)) => val.clone(),
_ => panic!("expect int ex const")
}
}
pub fn extract_ssa_id(&self) -> Option<MuID> {
match self.v {
Value_::SSAVar(id) => Some(id),
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! # MuIR AST crate
//!
//! This crate provides data structures to allow construct MuIR in Rust code, including:
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum BinOp {
// BinOp Int(n) Int(n) -> Int(n)
......@@ -83,7 +97,7 @@ impl CmpOp {
FUGT => FULT,
FULT => FUGT,
_ => self, // all other comparisons are reflexive
_ => self, // all other comparisons are symmetric
}
}
......@@ -132,6 +146,18 @@ impl CmpOp {
}
}
// gets the unsigned version of the comparison
pub fn get_unsigned(self) -> CmpOp {
use op::CmpOp::*;
match self {
SGE => UGE,
SLT => ULT,
SGT => UGT,
SLE => ULE,
_ => self,
}
}
pub fn is_signed(self) -> bool {
use op::CmpOp::*;
match self {
......@@ -156,6 +182,14 @@ impl CmpOp {
_ => false
}
}
pub fn is_symmetric(self) -> bool {
use op::CmpOp::*;
match self {
EQ | NE | FORD| FUNO| FUNE | FUEQ | FONE | FOEQ => true,
_ => false
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::sync::Arc;
/// P<T> is alias type for sharable Mu AST components (such as Value, MuFuncSig, MuType, etc)
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use ptr::P;
use ir::*;
......@@ -49,7 +63,11 @@ lazy_static! {
pub static ref VOID_TYPE : P<MuType> = P(
MuType::new(new_internal_id(), MuType_::void())
);
pub static ref REF_VOID_TYPE : P<MuType> = P(
MuType::new(new_internal_id(), MuType_::muref(VOID_TYPE.clone()))
);
pub static ref INTERNAL_TYPES : Vec<P<MuType>> = vec![
ADDRESS_TYPE.clone(),
UINT1_TYPE.clone(),
......@@ -60,8 +78,10 @@ lazy_static! {
UINT128_TYPE.clone(),
FLOAT_TYPE.clone(),
DOUBLE_TYPE.clone(),
VOID_TYPE.clone()
];
FLOAT_TYPE.clone(),
VOID_TYPE.clone(),
REF_VOID_TYPE.clone(),
];
}
/// clear struct/hybrid maps, called when creating new VM
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use compiler::backend::AOT_EMIT_CONTEXT_FILE;
use compiler::backend::RegGroup;
use utils::ByteSize;
......@@ -16,11 +30,9 @@ use utils::LinkedHashMap;
use ast::ptr::P;
use ast::ir::*;
use ast::types::*;
use std::str;
use std::usize;
use std::slice::Iter;
use std::ops;
use std::collections::HashSet;
......@@ -96,16 +108,6 @@ impl ASMCode {
panic!("didnt find any block for inst {}", inst)
}
fn get_block_by_start_inst(&self, inst: usize) -> Option<&ASMBlock> {
for block in self.blocks.values() {
if block.start_inst == inst {
return Some(block);
}
}
None
}
fn rewrite_insert(
&self,
insert_before: LinkedHashMap<usize, Vec<Box<ASMCode>>>,
......@@ -269,20 +271,8 @@ impl ASMCode {
// control flow analysis
let n_insts = self.number_of_insts();
let ref blocks = self.blocks;
let ref mut asm = self.code;
let block_start = {
let mut ret = vec![];
for block in blocks.values() {
if TRACE_CFA {
trace!("Block starts at {}", block.start_inst);
}
ret.push(block.start_inst);
}
ret
};
for i in 0..n_insts {
if TRACE_CFA {
trace!("---inst {}---", i);
......@@ -896,21 +886,6 @@ impl ASMInst {
spill_info: spill_info
}
}
fn nop() -> ASMInst {
ASMInst {
code: "".to_string(),
defines: LinkedHashMap::new(),
uses: LinkedHashMap::new(),
is_symbol: false,
is_mem_op_used: false,
preds: vec![],
succs: vec![],
branch: ASMBranchTarget::None,
spill_info: None
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
......@@ -993,14 +968,7 @@ impl ASMCodeGen {
self.cur().code.len()
}
fn add_asm_label(&mut self, code: String) {
let l = self.line();
trace!("emit: {}", code);
self.cur_mut().code.push(ASMInst::symbolic(code));
}
fn add_asm_block_label(&mut self, code: String, block_name: MuName) {
let l = self.line();
trace!("emit: [{}]{}", block_name, code);
self.cur_mut().code.push(ASMInst::symbolic(code));
}
......@@ -1010,10 +978,6 @@ impl ASMCodeGen {
self.cur_mut().code.push(ASMInst::symbolic(code));
}
fn prepare_machine_regs(&self, regs: Iter<P<Value>>) -> Vec<MuID> {
regs.map(|x| self.prepare_machine_reg(x)).collect()
}
fn add_asm_call(&mut self, code: String, potentially_excepting: Option<MuName>, target: Option<(MuID, ASMLocation)>) {
// a call instruction will use all the argument registers
// do not need
......@@ -1057,22 +1021,6 @@ impl ASMCodeGen {
}, None)
}
fn add_asm_ret(&mut self, code: String) {
// return instruction does not use anything (not RETURN REGS)
// otherwise it will keep RETURN REGS alive
// and if there is no actual move into RETURN REGS, it will keep RETURN REGS for alive for very long
// and prevents anything using those regsiters
self.add_asm_inst_internal(code, linked_hashmap! {}, linked_hashmap! {}, false, ASMBranchTarget::Return, None);
}
fn add_asm_branch(&mut self, code: String, target: MuName) {
self.add_asm_inst_internal(code, linked_hashmap! {}, linked_hashmap! {}, false, ASMBranchTarget::Unconditional(target), None);
}
fn add_asm_branch2(&mut self, code: String, target: MuName) {
self.add_asm_inst_internal(code, linked_hashmap! {}, linked_hashmap! {}, false, ASMBranchTarget::Conditional(target), None);
}
fn add_asm_inst(
&mut self,
code: String,
......@@ -1113,7 +1061,6 @@ impl ASMCodeGen {
target: ASMBranchTarget,
spill_info: Option<SpillMemInfo>)
{
let line = self.line();
trace!("asm: {}", code);
trace!(" defines: {:?}", defines);
trace!(" uses: {:?}", uses);
......@@ -1136,30 +1083,6 @@ impl ASMCodeGen {
(str, op.extract_ssa_id().unwrap(), ASMLocation::new(self.line(), loc, len, check_op_len(&op.ty)))
}
fn prepare_fpreg(&self, op: &P<Value>, loc: usize) -> (String, MuID, ASMLocation) {
if cfg!(debug_assertions) {
match op.v {
Value_::SSAVar(_) => {},
_ => panic!("expecting register op")
}
}
let str = self.asm_reg_op(op);
let len = str.len();
(str, op.extract_ssa_id().unwrap(), ASMLocation::new(self.line(), loc, len, 64))
}
fn prepare_machine_reg(&self, op: &P<Value>) -> MuID {
if cfg!(debug_assertions) {
match op.v {
Value_::SSAVar(_) => {},
_ => panic!("expecting machine register op")
}
}
op.extract_ssa_id().unwrap()
}
fn prepare_mem(&self, op: &P<Value>, loc: usize) -> (String, LinkedHashMap<MuID, Vec<ASMLocation>>) {
if cfg!(debug_assertions) {
match op.v {
......@@ -1203,7 +1126,9 @@ impl ASMCodeGen {
result_str.push_str(",");
let n = offset.ty.get_int_length().unwrap();
let shift_type =
if n == 64 { if signed { "SXTX" } else { "LSL" } } else if n == 32 { if signed { "SXTW" } else { "UXTW" } } else { panic!("Unexpected size for offset register") };
if n == 64 { if signed { "SXTX" } else { "LSL" } }
else if n == 32 { if signed { "SXTW" } else { "UXTW" } }
else { panic!("Unexpected size for offset register") };
result_str.push_str(&shift_type);
result_str.push_str(" #");
......@@ -1426,6 +1351,23 @@ impl ASMCodeGen {
)
}
fn internal_binop_str(&mut self, inst: &str, dest: &P<Value>, src1: &P<Value>, src2: &str) {
let inst = inst.to_string();
trace!("emit: \t{} {}, {} -> {}", inst, src1, src2, dest);
let (reg1, id1, loc1) = self.prepare_reg(dest, inst.len() + 1);
let (reg2, id2, loc2) = self.prepare_reg(src1, inst.len() + 1 + reg1.len() + 1);
let asm = format!("{} {},{},#{}", inst, reg1, reg2, src2);
self.add_asm_inst(
asm,
ignore_zero_register(id1, vec![loc1]),
ignore_zero_register(id2, vec![loc2]),
false
)
}
// dest <= inst(src1, src2)
fn internal_unop_shift(&mut self, inst: &str, dest: &P<Value>, src: &P<Value>, shift: &str, amount: u8) {
let inst = inst.to_string();
......@@ -1781,7 +1723,6 @@ impl ASMCodeGen {
}
};
trace!("emit: \t{} {} -> {}", inst, src, dest);
let (reg, id, loc) = self.prepare_reg(dest, inst.len() + 1);
......@@ -1819,8 +1760,8 @@ impl ASMCodeGen {
let inst = inst.to_string();
trace!("emit: \t{} {} -> {},{}", inst, src, dest1, dest2);
let (reg1, id1, loc1) = self.prepare_reg(dest1, 3 + 1);
let (reg2, id2, loc2) = self.prepare_reg(dest2, 3 + 1 + reg1.len()