Commit 37c19daa authored by Yi Lin's avatar Yi Lin

Merge branch 'develop' into 'master'

merge with develop

See merge request !50
parents b90588c0 a25abd66
Pipeline #1257 passed with stages
in 49 minutes and 40 seconds
image: "qinsoon/ubuntu-zebu-test:latest"
stages:
- build
- test
- mubench
- rustfmt
before_script:
- export PATH=$PATH:/root/.cargo/bin
- export MU_ZEBU=$CI_PROJECT_DIR
- export ZEBU_BUILD=release
- export CARGO_HOME=.cargo
- export CC=clang
- export LD_LIBRARY_PATH=$MU_ZEBU/target/$ZEBU_BUILD:$LD_LIBRARY_PATH
- source /home/gitlab-runner/ci/bin/activate
build:
stage: build
script:
- rustc --version
- time CARGO_HOME=.cargo RUST_BACKTRACE=1 CC=clang cargo test --release --no-run --color=always
- time CARGO_HOME=.cargo RUST_BACKTRACE=1 CC=clang cargo test -j6 --release --no-run --color=always
artifacts:
paths:
- target/release/libmu.so
......@@ -43,6 +43,40 @@ test:cargo:runtime:
script:
- RUST_BACKTRACE=1 RUST_TEST_THREADS=1 ./test-release --color=always test_runtime 2> /dev/null
.build_muc: &build_muc |
if [ -d "tests/test_muc/mu-tool-compiler" ]; then rm -Rf tests/test_muc/mu-tool-compiler; fi
cd tests/test_muc
git clone https://gitlab.anu.edu.au/mu/mu-tool-compiler
cd mu-tool-compiler
mkdir lib
ln -s $MU_ZEBU/target/release/libmu.so lib/
make
cd ..
testmuc:test_simple:
stage: test
script:
- *build_muc
- LD_LIBRARY_PATH=mu-tool-compiler/lib/ MUC=mu-tool-compiler/muc python2 -m pytest test_simple.py -v
testmuc:test_swapstack:
stage: test
script:
- *build_muc
- LD_LIBRARY_PATH=mu-tool-compiler/lib/ MUC=mu-tool-compiler/muc python2 -m pytest test_thread_and_stack.py -v
testmuc:test_cmp:
stage: test
script:
- *build_muc
- LD_LIBRARY_PATH=mu-tool-compiler/lib/ MUC=mu-tool-compiler/muc python2 -m pytest test_cmp.py -v
testmuc:test_binop:
stage: test
script:
- *build_muc
- LD_LIBRARY_PATH=mu-tool-compiler/lib/ MUC=mu-tool-compiler/muc python2 -m pytest test_binop.py -v
testjit:milestones:
stage: test
script:
......@@ -61,6 +95,8 @@ testjit:cmpops:
testjit:controlflow:
stage: test
script:
# run this test under test_jit directory
# as a C source file is expected in a relative path to current working directory
- cd tests/test_jit
- RUST_BACKTRACE=1 pytest test_controlflow.py -v --color=yes
......@@ -98,7 +134,7 @@ testjit:rpython:
- git checkout mu-rewrite
- git apply pypy.patch
- cd $CI_PROJECT_DIR/tests/test_jit
- MU_LOG_LEVEL=info LD_LIBRARY_PATH=./emit RUST_BACKTRACE=1 PYTHONPATH=mu-client-pypy pytest test_rpython*.py -v --color=yes
- MU_LOG_LEVEL=info LD_LIBRARY_PATH=./emit:$LD_LIBRARY_PATH RUST_BACKTRACE=1 PYTHONPATH=mu-client-pypy pytest test_rpython*.py -v --color=yes
testjit:som:
stage: test
......@@ -112,9 +148,28 @@ testjit:som:
- git checkout mu-rewrite
- git apply pypy.patch
- cd $CI_PROJECT_DIR/tests/test_jit
- MU_LOG_LEVEL=info LD_LIBRARY_PATH=./emit RUST_BACKTRACE=1 PYTHONPATH=mu-client-pypy:RPySOM/src RPYSOM=RPySOM pytest test_som.py -v --color=yes
- MU_LOG_LEVEL=info LD_LIBRARY_PATH=./emit:$LD_LIBRARY_PATH RUST_BACKTRACE=1 PYTHONPATH=mu-client-pypy:RPySOM/src RPYSOM=RPySOM pytest test_som.py -v --color=yes
mubench:
stage: mubench
script:
- deactivate
- git clone https://gitlab.anu.edu.au/mu/mu-perf-benchmarks.git
- git clone https://gitlab.anu.edu.au/mu/mu-client-pypy.git
- cd mu-client-pypy; git apply pypy.patch; git apply clang_opt_flag.patch; cd $CI_PROJECT_DIR
- git clone https://github.com/microvm/RPySOM.git
- cd RPySOM; git submodule init; git submodule update; cd $CI_PROJECT_DIR
- export RPYSOM=RPySOM
- export PYPY=mu-client-pypy
- virtualenv -p python3 mubench_venv
- source mubench_venv/bin/activate
- pip install -Ue ./mu-perf-benchmarks
- mkdir ci
- mubench local ./mu-perf-benchmarks/ci/*.yml --dump /home/gitlab-runner/results/$(git log -1 --pretty="%h_%at") --pipeline ""
- rsync -a /home/gitlab-runner/results/* squirrel:~/mu-impl-fast/angus
rustfmt:
stage: rustfmt
script:
- rustup run nightly cargo fmt -- --write-mode=diff src/ast/src/lib.rs src/gc/src/lib.rs src/utils/src/lib.rs --verbose
- cargo-fmt -- --write-mode=diff --verbose -- src/lib.rs src/ast/src/lib.rs src/gc/src/lib.rs src/utils/src/lib.rs
......@@ -26,16 +26,19 @@ doctest = false
default = ["aot"]
aot = []
jit = []
sel4-rumprun = []
sel4-rumprun-target-side = []
[build-dependencies]
gcc = "*"
built = "0.1"
#built = "0.1"
[dependencies]
mu_ast = {path = "src/ast"}
mu_utils = {path = "src/utils"}
mu_gc = {path = "src/gc"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", version = ">= 0.0.5" }
#mu_gc = {path = "src/gc"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "new", version = "^0.1.13" }
#rodal = { path = "./rodal", version = "*" }
libc="*"
field-offset = "*"
......@@ -55,4 +58,28 @@ docopt = "*"
petgraph = "*"
extprim = "*"
num-traits = "*"
#built = "0.1"
[target.aarch64-unknown-linux-gnu.dependencies]
mu_gc = { path = "src/gc", default-features = false}
built = "0.1"
[target.x86_64-unknown-linux-gnu.dependencies]
mu_gc = { path = "src/gc", default-features = false}
built = "0.1"
[target.x86_64-apple-darwin.dependencies]
mu_gc = { path = "src/gc", default-features = false}
built = "0.1"
[target.x86_64-rumprun-netbsd.dependencies]
mu_gc = { path = "src/gc", default-features = false, features = ["sel4-rumprun-target-side"], target = "x86_64-rumprun-netbsd"}
[target.aarch64-unknown-linux-gnu.build-dependencies]
built = "0.1"
[target.x86_64-unknown-linux-gnu.build-dependencies]
built = "0.1"
[target.x86_64-apple-darwin.build-dependencies]
built = "0.1"
......@@ -12,15 +12,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#[cfg(not(feature = "sel4-rumprun-target-side"))]
extern crate built;
extern crate gcc;
#[cfg(not(feature = "sel4-rumprun-target-side"))]
#[cfg(any(target_os = "macos", target_os = "linux"))]
#[cfg(target_arch = "x86_64")]
fn main() {
gcc::compile_library("libruntime_c.a", &["src/runtime/runtime_c_x64_sysv.c"]);
gcc::Build::new()
.flag("-O3")
.flag("-c")
.file("src/runtime/runtime_c_x64_sysv.c")
.compile("libruntime_c.a");
gcc::Config::new()
gcc::Build::new()
.flag("-O3")
.flag("-c")
.file("src/runtime/runtime_asm_x64_sysv.S")
......@@ -29,12 +36,17 @@ fn main() {
built();
}
#[cfg(not(feature = "sel4-rumprun-target-side"))]
#[cfg(target_os = "linux")]
#[cfg(target_arch = "aarch64")]
fn main() {
gcc::compile_library("libruntime_c.a", &["src/runtime/runtime_c_aarch64_sysv.c"]);
gcc::Build::new()
.flag("-O3")
.flag("-c")
.file("src/runtime/runtime_c_aarch64_sysv.c")
.compile("libruntime_c.a");
gcc::Config::new()
gcc::Build::new()
.flag("-O3")
.flag("-c")
.file("src/runtime/runtime_asm_aarch64_sysv.S")
......@@ -43,6 +55,34 @@ fn main() {
built();
}
#[cfg(not(feature = "sel4-rumprun-target-side"))]
fn built() {
built::write_built_file().expect("Failed to acquire build-time information");
}
#[cfg(feature = "sel4-rumprun-target-side")]
#[cfg(target_arch = "x86_64")]
fn main() {
use std::path::Path;
let mut compiler_name = String::new();
compiler_name.push_str("x86_64-rumprun-netbsd-gcc");
gcc::Build::new()
.flag("-O3")
.flag("-c")
.compiler(Path::new(compiler_name.as_str()))
.file("src/runtime/runtime_x64_sel4_rumprun_sysv.c")
.compile("libruntime_c.a");
gcc::Build::new()
.flag("-O3")
.flag("-c")
.compiler(Path::new(compiler_name.as_str()))
.file("src/runtime/runtime_asm_x64_sel4_rumprun_sysv.S")
.compile("libruntime_asm.a");
gcc::Build::new()
.flag("-O3")
.flag("-c")
.compiler(Path::new(compiler_name.as_str()))
.file("zebu_c_helpers.c")
.compile("libzebu_c_helpers.a");
}
#!/usr/bin/env bash
export ZEBU_TARGET=x86_64-rumprun-netbsd
cd ././../rumprun-sel4/
bash clean_and_build.sh
\ No newline at end of file
......@@ -21,7 +21,7 @@ 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 LD_LIBRARY_PATH="$MU_ZEBU/tests/test_jit/:$MU_ZEBU/tests/test_jit:$LD_LIBRARY_PATH"
export ZEBU_BUILD=release
rm -rf $MU_ZEBU/emit
......@@ -29,7 +29,7 @@ rm -rf $MU_ZEBU/tests/test_jit/emit
cargo update
#cargo clean
rustup run nightly cargo fmt -- --write-mode=diff src/ast/src/lib.rs src/gc/src/lib.rs src/utils/src/lib.rs --verbose | tee cargo_fmt_out.txt
cargo-fmt -- --write-mode=diff --verbose -- src/lib.rs src/ast/src/lib.rs src/gc/src/lib.rs src/utils/src/lib.rs | tee cargo_fmt_out.txt
cargo test --release --no-run --color=always 2>&1 | tee build_out.txt
$(exit ${PIPESTATUS[0]}) # this command will exit the shell but only if the above cargo test failed
......@@ -55,5 +55,5 @@ else
git -C ./RPySOM submodule init
git -C ./RPySOM submodule update
fi
pytest test_*.py -v --color=yes 2>&1 | tee $MU_ZEBU/pytest_out.txt
shopt -s extglob
pytest ./test_!(pypy).py -v --color=yes 2>&1 | tee $MU_ZEBU/pytest_out.txt
......@@ -25,4 +25,6 @@ mu_utils = {path = "../utils"}
lazy_static = "*"
log = "*"
simple_logger = "*"
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", version = ">= 0.0.5" }
regex = "*"
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "new", version = "^0.1.13" }
#rodal = { path = "../../rodal", version = "*" }
This diff is collapsed.
This diff is collapsed.
......@@ -33,6 +33,7 @@
#[macro_use]
extern crate rodal;
extern crate log;
extern crate simple_logger;
#[macro_use]
extern crate lazy_static;
......
......@@ -11,8 +11,8 @@
// 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)]
use std::fmt;
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum BinOp {
// BinOp Int(n) Int(n) -> Int(n)
Add,
......@@ -38,7 +38,21 @@ pub enum BinOp {
FDiv,
FRem
}
impl fmt::Display for BinOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", format!("{:?}", self).to_uppercase())
}
}
impl BinOp {
pub fn is_fp(self) -> bool {
use op::BinOp::*;
match self {
FAdd | FSub | FMul | FDiv | FRem => true,
_ => false
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum CmpOp {
// for Int comparison
......@@ -71,6 +85,11 @@ pub enum CmpOp {
FUNE,
FUNO
}
impl fmt::Display for CmpOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl CmpOp {
/// returns the CmpOp X for CmpOp Y, such that (a Y b) is equivalent to (b X a)
......@@ -174,6 +193,24 @@ impl CmpOp {
}
}
pub fn is_fp_cmp(self) -> bool {
!self.is_int_cmp()
}
pub fn is_eq_cmp(self) -> bool {
use op::CmpOp::*;
match self {
EQ | NE => true,
_ => false
}
}
pub fn is_ult_cmp(self) -> bool {
use op::CmpOp::*;
match self {
UGE | UGT | ULE | ULT => true,
_ => false
}
}
pub fn is_symmetric(self) -> bool {
use op::CmpOp::*;
match self {
......@@ -198,6 +235,11 @@ pub enum ConvOp {
REFCAST,
PTRCAST
}
impl fmt::Display for ConvOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AtomicRMWOp {
......@@ -213,3 +255,9 @@ pub enum AtomicRMWOp {
UMAX,
UMIN
}
impl fmt::Display for AtomicRMWOp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
......@@ -75,6 +75,14 @@ lazy_static! {
MuType::new(new_internal_id(), MuType_::iref(VOID_TYPE.clone()))
);
pub static ref STACKREF_TYPE : P<MuType> = P(
MuType::new(new_internal_id(), MuType_::StackRef)
);
pub static ref THREADREF_TYPE : P<MuType> = P(
MuType::new(new_internal_id(), MuType_::ThreadRef)
);
pub static ref INTERNAL_TYPES : Vec<P<MuType>> = vec![
ADDRESS_TYPE.clone(),
UINT1_TYPE.clone(),
......@@ -89,6 +97,8 @@ lazy_static! {
VOID_TYPE.clone(),
REF_VOID_TYPE.clone(),
IREF_VOID_TYPE.clone(),
STACKREF_TYPE.clone(),
THREADREF_TYPE.clone(),
];
}
......@@ -106,7 +116,7 @@ pub fn init_types() {
}
/// MuType represents a Mu type
#[derive(PartialEq, Debug)]
#[derive(Debug)]
pub struct MuType {
pub hdr: MuEntityHeader,
pub v: MuType_
......@@ -114,6 +124,15 @@ pub struct MuType {
rodal_struct!(MuType { hdr, v });
impl PartialEq for MuType {
fn eq(&self, other: &MuType) -> bool {
self.v == other.v
}
fn ne(&self, other: &MuType) -> bool {
self.v != other.v
}
}
impl MuType {
/// creates a new Mu type
pub fn new(id: MuID, v: MuType_) -> MuType {
......@@ -123,6 +142,27 @@ impl MuType {
}
}
pub fn is_tagref64(&self) -> bool {
match self.v {
MuType_::Tagref64 => true,
_ => false
}
}
pub fn is_stackref(&self) -> bool {
match self.v {
MuType_::StackRef => true,
_ => false
}
}
pub fn is_funcref(&self) -> bool {
match self.v {
MuType_::FuncRef(_) => true,
_ => false
}
}
/// is this type struct type?
pub fn is_struct(&self) -> bool {
match self.v {
......@@ -131,6 +171,13 @@ impl MuType {
}
}
pub fn is_void(&self) -> bool {
match self.v {
MuType_::Void => true,
_ => false
}
}
/// is this type hybrid type?
pub fn is_hybrid(&self) -> bool {
match self.v {
......@@ -155,6 +202,23 @@ impl MuType {
}
}
pub fn is_opaque_reference(&self) -> bool {
match self.v {
MuType_::FuncRef(_) | MuType_::StackRef | MuType_::ThreadRef => true,
_ => false
}
}
pub fn is_eq_comparable(&self) -> bool {
self.is_int() || self.is_ptr() || self.is_iref() || self.is_ref() ||
self.is_opaque_reference()
}
pub fn is_ult_comparable(&self) -> bool {
self.is_int() || self.is_ptr() || self.is_iref()
}
/// is this type a float type (single-precision floating point)
pub fn is_float(&self) -> bool {
match self.v {
......@@ -326,6 +390,14 @@ impl MuType {
}
}
/// gets the signature of a funcref or ufuncptr type
pub fn get_sig(&self) -> Option<P<MuFuncSig>> {
match self.v {
MuType_::FuncRef(ref sig) | MuType_::UFuncPtr(ref sig) => Some(sig.clone()),
_ => None
}
}
/// gets a field's type of a struct type,
/// returns None if the type is not a struct or hybrid type
pub fn get_field_ty(&self, index: usize) -> Option<P<MuType>> {
......@@ -369,6 +441,15 @@ impl MuType {
}
}
/// gets the function signature for FuncRef or UFuncPtr, return None if the type is not
/// those two types
pub fn get_func_sig(&self) -> Option<P<MuFuncSig>> {
match self.v {
MuType_::FuncRef(ref sig) | MuType_::UFuncPtr(ref sig) => Some(sig.clone()),
_ => None
}
}
/// gets the length (in bit) of a integer/pointer type (assume pointer types are always 64 bits)
// FIXME: should deprecate this function, and get the length from BackendType
pub fn get_int_length(&self) -> Option<usize> {
......@@ -393,7 +474,7 @@ pub type StructTag = MuName;
pub type HybridTag = MuName;
/// MuType_ is used for pattern matching for MuType
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Clone)]
pub enum MuType_ {
/// int <length>
Int(usize),
......@@ -441,7 +522,14 @@ pub enum MuType_ {
/// ufuncptr<@sig>
UFuncPtr(P<MuFuncSig>)
}
impl MuType_ {
pub fn strong_variant(&self) -> MuType_ {
match self {
&MuType_::WeakRef(ref t) => MuType_::Ref(t.clone()),
_ => self.clone()
}
}
}
rodal_enum!(MuType_{(Int: size), Float, Double, (Ref: ty), (IRef: ty), (WeakRef: ty), (UPtr: ty),
(Struct: tag), (Array: ty, size), (Hybrid: tag), Void, ThreadRef, StackRef, Tagref64,
(Vector: ty, size), (FuncRef: ty), (UFuncPtr: ty)});
......@@ -469,9 +557,9 @@ impl fmt::Display for MuType_ {
&MuType_::Tagref64 => write!(f, "tagref64"),
&MuType_::Vector(ref ty, size) => write!(f, "vector<{} {}>", ty, size),
&MuType_::FuncRef(ref sig) => write!(f, "funcref<{}>", sig),
&MuType_::UFuncPtr(ref sig) => write!(f, "ufuncref<{}>", sig),
&MuType_::Struct(ref tag) => write!(f, "{}(struct)", tag),
&MuType_::Hybrid(ref tag) => write!(f, "{}(hybrid)", tag)
&MuType_::UFuncPtr(ref sig) => write!(f, "ufuncptr<{}>", sig),
&MuType_::Struct(ref tag) => write!(f, "{}", tag),
&MuType_::Hybrid(ref tag) => write!(f, "{}", tag)
}
}
}
......@@ -572,7 +660,7 @@ impl fmt::Display for HybridType_ {
write!(f, " ").unwrap();
}
}
write!(f, "|{}>", self.var_ty)
write!(f, " {}>", self.var_ty)
}
}
......@@ -733,19 +821,24 @@ impl MuType_ {
}
/// MuFuncSig represents a Mu function signature
#[derive(PartialEq, Debug)]
#[derive(Debug)]
pub struct MuFuncSig {
pub hdr: MuEntityHeader,
pub ret_tys: Vec<P<MuType>>,
pub arg_tys: Vec<P<MuType>>
}
impl PartialEq for MuFuncSig {
fn eq(&self, other: &MuFuncSig) -> bool {
self.ret_tys == other.ret_tys && self.arg_tys == other.arg_tys
}
}
rodal_struct!(MuFuncSig{hdr, ret_tys, arg_tys});
impl fmt::Display for MuFuncSig {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}] -> [{}]",
vec_utils::as_str(&self.arg_tys), vec_utils::as_str(&self.ret_tys))
write!(f, "({})->({})",
vec_utils::as_str_sp(&self.arg_tys), vec_utils::as_str_sp(&self.ret_tys))
}
}
......
......@@ -120,26 +120,45 @@ pub trait CodeGenerator {
// Calls
fn emit_bl(
&mut self,
callsite: String,
callsite: Option<MuName>,
func: MuName,
pe: Option<MuName>,
args: Vec<P<Value>>,
ret: Vec<P<Value>>,
is_native: bool
) -> ValueLocation;
) -> Option<ValueLocation>;
fn emit_blr(
&mut self,
callsite: String,
callsite: Option<MuName>,
func: Reg,
pe: Option<MuName>,
args: Vec<P<Value>>
) -> ValueLocation;
args: Vec<P<Value>>,
ret: Vec<P<Value>>
) -> Option<ValueLocation>;
// Branches
fn emit_b(&mut self, dest_name: MuName);
fn emit_b_func(&mut self, func: MuName, args: Vec<P<Value>>); // For tail calls
fn emit_b_cond(&mut self, cond: &str, dest_name: MuName);
fn emit_br(&mut self, dest_address: Reg);
fn emit_br_func(&mut self, func_address: Reg, args: Vec<P<Value>>); // For tail calls
fn emit_b_call(
&mut self,
callsite: Option<MuName>,
func: MuName,
pe: Option<MuName>,
args: Vec<P<Value>>,
ret: Vec<P<Value>>,
is_native: bool,
may_return: bool
) -> Option<ValueLocation>;
fn emit_br_call(
&mut self,
callsite: Option<MuName>,
func: Reg,
pe: Option<MuName>,
args: Vec<P<Value>>,
ret: Vec<P<Value>>,
may_return: bool
) -> Option<ValueLocation>;
fn emit_ret(&mut self, src: Reg);
fn emit_cbnz(&mut self, src: Reg, dest_name: MuName);
......
This diff is collapsed.
use ast::ir::*;
use ast::ptr::*;
use ast::types::*;
use compiler::backend::RegGroup;
use compiler::backend::x86_64;
use compiler::backend::BackendType;
use utils::ByteSize;
use vm::VM;
#[derive(Clone, Debug)]
pub enum CallConvResult {
GPR(P<Value>),
GPREX(P<Value>, P<Value>),
FPR(P<Value>),
STACK
}
pub mod mu {
pub use super::c::*;