Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mu-impl-fast
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
40
Issues
40
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
mu
mu-impl-fast
Commits
c3ba71ac
Commit
c3ba71ac
authored
Nov 03, 2016
by
John Zhang
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into ci-script
parents
00c57362
a241c754
Changes
56
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
56 changed files
with
2637 additions
and
736 deletions
+2637
-736
.gitignore
.gitignore
+1
-0
.gitlab-ci.yml
.gitlab-ci.yml
+15
-6
run_test.sh
run_test.sh
+2
-0
src/ast/src/inst.rs
src/ast/src/inst.rs
+9
-0
src/ast/src/ir.rs
src/ast/src/ir.rs
+4
-0
src/ast/src/ir_semantics.rs
src/ast/src/ir_semantics.rs
+2
-0
src/ast/src/op.rs
src/ast/src/op.rs
+18
-0
src/ast/src/types.rs
src/ast/src/types.rs
+10
-0
src/compiler/backend/arch/x86_64/asm_backend.rs
src/compiler/backend/arch/x86_64/asm_backend.rs
+731
-416
src/compiler/backend/arch/x86_64/codegen.rs
src/compiler/backend/arch/x86_64/codegen.rs
+184
-35
src/compiler/backend/arch/x86_64/inst_sel.rs
src/compiler/backend/arch/x86_64/inst_sel.rs
+259
-25
src/compiler/backend/arch/x86_64/mod.rs
src/compiler/backend/arch/x86_64/mod.rs
+16
-16
src/compiler/backend/mod.rs
src/compiler/backend/mod.rs
+27
-0
src/compiler/backend/reg_alloc/graph_coloring/liveness.rs
src/compiler/backend/reg_alloc/graph_coloring/liveness.rs
+1
-12
src/testutil/aot.rs
src/testutil/aot.rs
+23
-0
src/testutil/mod.rs
src/testutil/mod.rs
+6
-1
src/vm/api/api_bridge.rs
src/vm/api/api_bridge.rs
+4
-2
src/vm/api/api_c.rs
src/vm/api/api_c.rs
+1
-1
src/vm/api/api_impl/irnodes.rs
src/vm/api/api_impl/irnodes.rs
+4
-1
src/vm/api/api_impl/muirbuilder.rs
src/vm/api/api_impl/muirbuilder.rs
+379
-167
src/vm/api/api_impl/muvm.rs
src/vm/api/api_impl/muvm.rs
+2
-2
src/vm/api/muapi.h
src/vm/api/muapi.h
+1
-1
src/vm/vm.rs
src/vm/vm.rs
+75
-0
tests/test_compiler/test_binop.rs
tests/test_compiler/test_binop.rs
+170
-0
tests/test_compiler/test_int.rs
tests/test_compiler/test_int.rs
+191
-21
tests/test_ir/test_builder_api.rs
tests/test_ir/test_builder_api.rs
+143
-6
tests/test_jit/suite/test_add.c
tests/test_jit/suite/test_add.c
+1
-1
tests/test_jit/suite/test_and.c
tests/test_jit/suite/test_and.c
+1
-1
tests/test_jit/suite/test_ccall.c
tests/test_jit/suite/test_ccall.c
+51
-0
tests/test_jit/suite/test_ccall_fnc.c
tests/test_jit/suite/test_ccall_fnc.c
+4
-0
tests/test_jit/suite/test_constfunc.c
tests/test_jit/suite/test_constfunc.c
+1
-1
tests/test_jit/suite/test_eq_int.c
tests/test_jit/suite/test_eq_int.c
+1
-1
tests/test_jit/suite/test_eq_ref.c
tests/test_jit/suite/test_eq_ref.c
+1
-1
tests/test_jit/suite/test_fib.c
tests/test_jit/suite/test_fib.c
+1
-1
tests/test_jit/suite/test_lshr.c
tests/test_jit/suite/test_lshr.c
+1
-1
tests/test_jit/suite/test_milsum.c
tests/test_jit/suite/test_milsum.c
+105
-0
tests/test_jit/suite/test_mul.c
tests/test_jit/suite/test_mul.c
+1
-1
tests/test_jit/suite/test_multifunc.c
tests/test_jit/suite/test_multifunc.c
+1
-1
tests/test_jit/suite/test_ne_int.c
tests/test_jit/suite/test_ne_int.c
+1
-1
tests/test_jit/suite/test_ne_ref.c
tests/test_jit/suite/test_ne_ref.c
+1
-1
tests/test_jit/suite/test_sdiv.c
tests/test_jit/suite/test_sdiv.c
+1
-1
tests/test_jit/suite/test_sext.c
tests/test_jit/suite/test_sext.c
+49
-0
tests/test_jit/suite/test_sge.c
tests/test_jit/suite/test_sge.c
+1
-1
tests/test_jit/suite/test_sgt.c
tests/test_jit/suite/test_sgt.c
+1
-1
tests/test_jit/suite/test_shl.c
tests/test_jit/suite/test_shl.c
+1
-1
tests/test_jit/suite/test_sle.c
tests/test_jit/suite/test_sle.c
+1
-1
tests/test_jit/suite/test_slt.c
tests/test_jit/suite/test_slt.c
+1
-1
tests/test_jit/suite/test_sub.c
tests/test_jit/suite/test_sub.c
+1
-1
tests/test_jit/suite/test_trunc.c
tests/test_jit/suite/test_trunc.c
+49
-0
tests/test_jit/suite/test_ult.c
tests/test_jit/suite/test_ult.c
+1
-1
tests/test_jit/suite/test_urem.c
tests/test_jit/suite/test_urem.c
+1
-1
tests/test_jit/suite/test_xor.c
tests/test_jit/suite/test_xor.c
+1
-1
tests/test_jit/suite/test_zext.c
tests/test_jit/suite/test_zext.c
+49
-0
tests/test_jit/test_controlflow.py
tests/test_jit/test_controlflow.py
+7
-0
tests/test_jit/test_convops.py
tests/test_jit/test_convops.py
+15
-0
tests/test_jit/test_milestones.py
tests/test_jit/test_milestones.py
+9
-3
No files found.
.gitignore
View file @
c3ba71ac
**/target/*
**/__pycache__/*
**/.cache/*
emit/*
**/temp/*
Cargo.lock
...
...
.gitlab-ci.yml
View file @
c3ba71ac
...
...
@@ -35,21 +35,21 @@ test:cargo:api:
dependencies
:
-
build_test
script
:
-
RUST_BACKTRACE=1 CC=clang cargo test test_api
-
RUST_BACKTRACE=1
RUST_TEST_THREADS=1
CC=clang cargo test test_api
test:cargo:ir:
stage
:
test
dependencies
:
-
build_test
script
:
-
RUST_BACKTRACE=1 CC=clang cargo test test_ir
-
RUST_BACKTRACE=1
RUST_TEST_THREADS=1
CC=clang cargo test test_ir
test:cargo:compiler:
stage
:
test
dependencies
:
-
build_test
script
:
-
RUST_BACKTRACE=1 CC=clang cargo test test_compiler
-
RUST_BACKTRACE=1
RUST_TEST_THREADS=1
CC=clang cargo test test_compiler
test:cargo:runtime:
stage
:
test
...
...
@@ -63,18 +63,27 @@ testjit:milestones:
dependencies
:
-
build_test
script
:
-
RUST_BACKTRACE=1 pytest tests/test_jit/test_milestones.py
-
RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
-
RUST_BACKTRACE=1 pytest tests/test_jit/test_milestones.py
testjit:binops:
stage
:
test
dependencies
:
-
build_test
script
:
-
RUST_BACKTRACE=1 pytest tests/test_jit/test_binops.py
-
RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
-
RUST_BACKTRACE=1 pytest tests/test_jit/test_binops.py
testjit:cmpops:
stage
:
test
dependencies
:
-
build_test
script
:
-
RUST_BACKTRACE=1 pytest tests/test_jit/test_cmpops.py
-
RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
-
RUST_BACKTRACE=1 pytest tests/test_jit/test_cmpops.py
testjit:cmpops:
stage
:
test
script
:
-
RUST_BACKTRACE=1 RUST_TEST_THREADS=1 CC=clang cargo build 2>/dev/null
-
RUST_BACKTRACE=1 pytest tests/test_jit/test_convops.py
\ No newline at end of file
run_test.sh
View file @
c3ba71ac
...
...
@@ -64,6 +64,8 @@ echo "KERNEL: $KERNEL"
echo
"ARCH:
$MACH
"
echo
"---------"
rm
emit/
*
if
[
"
$OS
"
==
"linux"
]
;
then
RUSTFLAGS
=
-Zincremental
=
target/incr-cache
RUST_BACKTRACE
=
1
RUST_TEST_THREADS
=
1
CC
=
clang-3.8 cargo
test
"
$@
"
elif
[
"
$OS
"
==
"Darwin"
]
;
then
...
...
src/ast/src/inst.rs
View file @
c3ba71ac
...
...
@@ -91,6 +91,12 @@ pub enum Instruction_ {
BinOp
(
BinOp
,
OpIndex
,
OpIndex
),
CmpOp
(
CmpOp
,
OpIndex
,
OpIndex
),
ConvOp
{
operation
:
ConvOp
,
from_ty
:
P
<
MuType
>
,
to_ty
:
P
<
MuType
>
,
operand
:
OpIndex
},
// yields a tuple of results from the call
ExprCall
{
...
...
@@ -254,6 +260,9 @@ impl Instruction_ {
match
self
{
&
Instruction_
::
BinOp
(
op
,
op1
,
op2
)
=>
format!
(
"{:?} {} {}"
,
op
,
ops
[
op1
],
ops
[
op2
]),
&
Instruction_
::
CmpOp
(
op
,
op1
,
op2
)
=>
format!
(
"{:?} {} {}"
,
op
,
ops
[
op1
],
ops
[
op2
]),
&
Instruction_
::
ConvOp
{
operation
,
ref
from_ty
,
ref
to_ty
,
operand
}
=>
{
format!
(
"{:?} {} {} {}"
,
operation
,
from_ty
,
to_ty
,
ops
[
operand
])
}
&
Instruction_
::
ExprCall
{
ref
data
,
is_abort
}
=>
{
let
abort
=
select_value!
(
is_abort
,
"ABORT_ON_EXN"
,
"RETHROW"
);
format!
(
"CALL {} {}"
,
data
.debug_str
(
ops
),
abort
)
...
...
src/ast/src/ir.rs
View file @
c3ba71ac
...
...
@@ -4,6 +4,7 @@ use inst::*;
use
op
::
*
;
use
utils
::
vec_utils
;
use
utils
::
Address
;
use
std
::
collections
::
HashMap
;
use
std
::
fmt
;
...
...
@@ -735,6 +736,8 @@ pub enum Constant {
FuncRef
(
MuID
),
UFuncRef
(
MuID
),
Vector
(
Vec
<
Constant
>
),
//Pointer(Address),
NullRef
,
}
impl
fmt
::
Display
for
Constant
{
...
...
@@ -756,6 +759,7 @@ impl fmt::Display for Constant {
}
write!
(
f
,
"]"
)
}
&
Constant
::
NullRef
=>
write!
(
f
,
"NullRef"
),
}
}
}
...
...
src/ast/src/ir_semantics.rs
View file @
c3ba71ac
...
...
@@ -5,6 +5,7 @@ pub fn is_terminal_inst(inst: &Instruction_) -> bool {
match
inst
{
&
BinOp
(
_
,
_
,
_
)
|
&
CmpOp
(
_
,
_
,
_
)
|
&
ConvOp
{
..
}
|
&
ExprCall
{
..
}
|
&
Load
{
..
}
|
&
Store
{
..
}
...
...
@@ -49,6 +50,7 @@ pub fn has_side_effect(inst: &Instruction_) -> bool {
match
inst
{
&
BinOp
(
_
,
_
,
_
)
=>
false
,
&
CmpOp
(
_
,
_
,
_
)
=>
false
,
&
ConvOp
{
..
}
=>
false
,
&
ExprCall
{
..
}
=>
true
,
&
Load
{
..
}
=>
true
,
&
Store
{
..
}
=>
true
,
...
...
src/ast/src/op.rs
View file @
c3ba71ac
...
...
@@ -35,6 +35,7 @@ pub enum OpCode {
// expression
Binary
(
BinOp
),
Comparison
(
CmpOp
),
Conversion
(
ConvOp
),
AtomicRMW
(
AtomicRMWOp
),
ExprCall
,
...
...
@@ -172,6 +173,22 @@ pub enum CmpOp {
FUNO
}
#[derive(Copy,
Clone,
Debug,
PartialEq,
RustcEncodable,
RustcDecodable)]
pub
enum
ConvOp
{
TRUNC
,
ZEXT
,
SEXT
,
FPTRUNC
,
FPEXT
,
FPTOUI
,
FPTOSI
,
UITOFP
,
SITOFP
,
BITCAST
,
REFCAST
,
PTRCAST
}
#[derive(Copy,
Clone,
Debug,
PartialEq,
RustcEncodable,
RustcDecodable)]
pub
enum
AtomicRMWOp
{
XCHG
,
...
...
@@ -207,6 +224,7 @@ pub fn pick_op_code_for_inst(inst: &Instruction) -> OpCode {
match
inst
.v
{
Instruction_
::
BinOp
(
op
,
_
,
_
)
=>
OpCode
::
Binary
(
op
),
Instruction_
::
CmpOp
(
op
,
_
,
_
)
=>
OpCode
::
Comparison
(
op
),
Instruction_
::
ConvOp
{
operation
,
..
}
=>
OpCode
::
Conversion
(
operation
),
Instruction_
::
AtomicRMW
{
op
,
..
}
=>
OpCode
::
AtomicRMW
(
op
),
Instruction_
::
ExprCall
{
..
}
=>
OpCode
::
ExprCall
,
Instruction_
::
Load
{
..
}
=>
OpCode
::
Load
,
...
...
src/ast/src/types.rs
View file @
c3ba71ac
...
...
@@ -12,6 +12,14 @@ lazy_static! {
pub
static
ref
ADDRESS_TYPE
:
P
<
MuType
>
=
P
(
MuType
::
new
(
new_internal_id
(),
MuType_
::
int
(
POINTER_SIZE
*
8
))
);
pub
static
ref
UINT8_TYPE
:
P
<
MuType
>
=
P
(
MuType
::
new
(
new_internal_id
(),
MuType_
::
int
(
8
))
);
pub
static
ref
UINT16_TYPE
:
P
<
MuType
>
=
P
(
MuType
::
new
(
new_internal_id
(),
MuType_
::
int
(
16
))
);
pub
static
ref
UINT32_TYPE
:
P
<
MuType
>
=
P
(
MuType
::
new
(
new_internal_id
(),
MuType_
::
int
(
32
))
...
...
@@ -27,6 +35,8 @@ lazy_static! {
pub
static
ref
INTERNAL_TYPES
:
Vec
<
P
<
MuType
>>
=
vec!
[
ADDRESS_TYPE
.clone
(),
UINT8_TYPE
.clone
(),
UINT16_TYPE
.clone
(),
UINT32_TYPE
.clone
(),
UINT64_TYPE
.clone
(),
DOUBLE_TYPE
.clone
()
...
...
src/compiler/backend/arch/x86_64/asm_backend.rs
View file @
c3ba71ac
This diff is collapsed.
Click to expand it.
src/compiler/backend/arch/x86_64/codegen.rs
View file @
c3ba71ac
This diff is collapsed.
Click to expand it.
src/compiler/backend/arch/x86_64/inst_sel.rs
View file @
c3ba71ac
This diff is collapsed.
Click to expand it.
src/compiler/backend/arch/x86_64/mod.rs
View file @
c3ba71ac
...
...
@@ -62,14 +62,14 @@ lazy_static! {
pub
static
ref
R13
:
P
<
Value
>
=
GPR!
(
13
,
"r13"
);
pub
static
ref
R14
:
P
<
Value
>
=
GPR!
(
14
,
"r14"
);
pub
static
ref
R15
:
P
<
Value
>
=
GPR!
(
15
,
"r15"
);
pub
static
ref
RIP
:
P
<
Value
>
=
GPR!
(
32
,
"rip"
);
pub
static
ref
RETURN_GPRs
:
[
P
<
Value
>
;
2
]
=
[
RAX
.clone
(),
RDX
.clone
(),
];
pub
static
ref
ARGUMENT_GPRs
:
[
P
<
Value
>
;
6
]
=
[
RDI
.clone
(),
RSI
.clone
(),
...
...
@@ -78,7 +78,7 @@ lazy_static! {
R8
.clone
(),
R9
.clone
()
];
pub
static
ref
CALLEE_SAVED_GPRs
:
[
P
<
Value
>
;
6
]
=
[
RBX
.clone
(),
RBP
.clone
(),
...
...
@@ -99,7 +99,7 @@ lazy_static! {
R10
.clone
(),
R11
.clone
()
];
pub
static
ref
ALL_GPRs
:
[
P
<
Value
>
;
15
]
=
[
RAX
.clone
(),
RCX
.clone
(),
...
...
@@ -136,13 +136,13 @@ lazy_static!{
pub
static
ref
XMM12
:
P
<
Value
>
=
FPR!
(
28
,
"xmm12"
);
pub
static
ref
XMM13
:
P
<
Value
>
=
FPR!
(
29
,
"xmm13"
);
pub
static
ref
XMM14
:
P
<
Value
>
=
FPR!
(
30
,
"xmm14"
);
pub
static
ref
XMM15
:
P
<
Value
>
=
FPR!
(
31
,
"xmm15"
);
pub
static
ref
XMM15
:
P
<
Value
>
=
FPR!
(
31
,
"xmm15"
);
pub
static
ref
RETURN_FPRs
:
[
P
<
Value
>
;
2
]
=
[
XMM0
.clone
(),
XMM1
.clone
()
];
pub
static
ref
ARGUMENT_FPRs
:
[
P
<
Value
>
;
8
]
=
[
XMM0
.clone
(),
XMM1
.clone
(),
...
...
@@ -153,7 +153,7 @@ lazy_static!{
XMM6
.clone
(),
XMM7
.clone
()
];
pub
static
ref
CALLEE_SAVED_FPRs
:
[
P
<
Value
>
;
0
]
=
[];
pub
static
ref
CALLER_SAVED_FPRs
:
[
P
<
Value
>
;
16
]
=
[
...
...
@@ -174,7 +174,7 @@ lazy_static!{
XMM14
.clone
(),
XMM15
.clone
(),
];
pub
static
ref
ALL_FPRs
:
[
P
<
Value
>
;
16
]
=
[
XMM0
.clone
(),
XMM1
.clone
(),
...
...
@@ -234,10 +234,10 @@ lazy_static! {
map
.insert
(
XMM14
.id
(),
XMM14
.clone
());
map
.insert
(
XMM15
.id
(),
XMM15
.clone
());
map
.insert
(
RIP
.id
(),
RIP
.clone
());
map
};
// put caller saved regs first (they imposes no overhead if there is no call instruction)
pub
static
ref
ALL_USABLE_MACHINE_REGs
:
Vec
<
P
<
Value
>>
=
vec!
[
RAX
.clone
(),
...
...
@@ -279,7 +279,7 @@ pub fn init_machine_regs_for_func (func_context: &mut FunctionContext) {
for
reg
in
ALL_MACHINE_REGs
.values
()
{
let
reg_id
=
reg
.extract_ssa_id
()
.unwrap
();
let
entry
=
SSAVarEntry
::
new
(
reg
.clone
());
func_context
.values
.insert
(
reg_id
,
entry
);
}
}
...
...
@@ -320,8 +320,8 @@ pub fn is_callee_saved(reg_id: MuID) -> bool {
return
true
;
}
}
false
false
}
pub
fn
is_valid_x86_imm
(
op
:
&
P
<
Value
>
)
->
bool
{
...
...
@@ -332,4 +332,4 @@ pub fn is_valid_x86_imm(op: &P<Value>) -> bool {
},
_
=>
false
}
}
}
\ No newline at end of file
src/compiler/backend/mod.rs
View file @
c3ba71ac
...
...
@@ -171,3 +171,30 @@ pub struct BackendTypeInfo {
#[derive(Clone,
Copy,
Debug,
PartialEq,
Eq,
Hash,
RustcEncodable,
RustcDecodable)]
pub
enum
RegGroup
{
GPR
,
FPR
}
impl
RegGroup
{
pub
fn
get
(
ty
:
&
P
<
MuType
>
)
->
RegGroup
{
match
ty
.v
{
// for now, only use 64bits registers
MuType_
::
Int
(
len
)
if
len
==
8
=>
RegGroup
::
GPR
,
MuType_
::
Int
(
len
)
if
len
==
16
=>
RegGroup
::
GPR
,
MuType_
::
Int
(
len
)
if
len
==
32
=>
RegGroup
::
GPR
,
MuType_
::
Int
(
len
)
if
len
==
64
=>
RegGroup
::
GPR
,
MuType_
::
Ref
(
_
)
|
MuType_
::
IRef
(
_
)
|
MuType_
::
WeakRef
(
_
)
|
MuType_
::
UPtr
(
_
)
|
MuType_
::
ThreadRef
|
MuType_
::
StackRef
|
MuType_
::
Tagref64
|
MuType_
::
FuncRef
(
_
)
|
MuType_
::
UFuncPtr
(
_
)
=>
RegGroup
::
GPR
,
MuType_
::
Float
=>
RegGroup
::
FPR
,
MuType_
::
Double
=>
RegGroup
::
FPR
,
_
=>
unimplemented!
()
}
}
}
\ No newline at end of file
src/compiler/backend/reg_alloc/graph_coloring/liveness.rs
View file @
c3ba71ac
...
...
@@ -54,18 +54,7 @@ impl InterferenceGraph {
self
.nodes
.insert
(
reg_id
,
node
.clone
());
// add node property
let
group
=
{
let
ref
ty
=
entry
.ty
();
if
types
::
is_scalar
(
ty
)
{
if
types
::
is_fp
(
ty
)
{
backend
::
RegGroup
::
FPR
}
else
{
backend
::
RegGroup
::
GPR
}
}
else
{
unimplemented!
()
}
};
let
group
=
backend
::
RegGroup
::
get
(
entry
.ty
());
let
property
=
NodeProperty
{
color
:
None
,
group
:
group
,
...
...
src/testutil/aot.rs
View file @
c3ba71ac
...
...
@@ -138,5 +138,28 @@ pub fn link_dylib (funcs: Vec<MuName>, out: &str) -> PathBuf {
let
mut
out_path
=
PathBuf
::
from
(
backend
::
AOT_EMIT_DIR
);
out_path
.push
(
out
);
link_dylib_internal
(
files
,
out_path
)
}
pub
fn
link_dylib_with_extra_srcs
(
funcs
:
Vec
<
MuName
>
,
srcs
:
Vec
<
String
>
,
out
:
&
str
)
->
PathBuf
{
let
files
=
{
let
mut
ret
=
vec!
[];
for
func
in
funcs
{
ret
.push
(
get_path_for_mu_func
(
func
));
}
for
src
in
srcs
{
ret
.push
(
PathBuf
::
from
(
src
));
}
ret
.push
(
get_path_for_mu_context
());
ret
};
let
mut
out_path
=
PathBuf
::
from
(
backend
::
AOT_EMIT_DIR
);
out_path
.push
(
out
);
link_dylib_internal
(
files
,
out_path
)
}
\ No newline at end of file
src/testutil/mod.rs
View file @
c3ba71ac
...
...
@@ -24,13 +24,18 @@ pub fn get_test_clang_path() -> String {
pub
fn
exec
(
mut
cmd
:
Command
)
->
Output
{
println!
(
"executing: {:?}"
,
cmd
);
let
output
=
cmd
.output
()
.expect
(
"failed to execute"
);
let
output
=
match
cmd
.output
()
{
Ok
(
res
)
=>
res
,
Err
(
e
)
=>
panic!
(
"failed to execute: {}"
,
e
)
};
println!
(
"---out---"
);
println!
(
"{}"
,
String
::
from_utf8_lossy
(
&
output
.stdout
));
println!
(
"---err---"
);
println!
(
"{}"
,
String
::
from_utf8_lossy
(
&
output
.stderr
));
assert
!
(
output
.status
.success
());
output
}
...
...
src/vm/api/api_bridge.rs
View file @
c3ba71ac
...
...
@@ -243,11 +243,13 @@ extern fn _forwarder__MuVM__set_trap_handler(mvm: *mut CMuVM, trap_handler: CMuT
};
}
extern
fn
_
forwarder__MuVM__compile_to_sharedlib
(
mvm
:
*
mut
CMuVM
,
lib_name
:
CMuCString
)
{
extern
fn
_
forwarder__MuVM__compile_to_sharedlib
(
mvm
:
*
mut
CMuVM
,
lib_name
:
CMuCString
,
extra_srcs
:
*
const
CMuCString
,
n
:
usize
)
{
let
mut
_
arg_mvm
=
from_MuVM_ptr
(
mvm
);
let
mut
_
arg_lib_name
=
from_MuCString
(
lib_name
);
let
_
arg_extra_srcs
=
from_MuCString_array
(
extra_srcs
,
n
);
unsafe
{
(
*
_
arg_mvm
)
.compile_to_sharedlib
(
&
_
arg_lib_name
)
(
*
_
arg_mvm
)
.compile_to_sharedlib
(
&
_
arg_lib_name
,
_
arg_extra_srcs
)
};
}
...
...
src/vm/api/api_c.rs
View file @
c3ba71ac
...
...
@@ -110,7 +110,7 @@ pub struct CMuVM {
pub
name_of
:
extern
fn
(
*
mut
CMuVM
,
CMuID
)
->
CMuName
,
pub
set_trap_handler
:
extern
fn
(
*
mut
CMuVM
,
CMuTrapHandler
,
CMuCPtr
),
// this function is only used in testing jit
pub
compile_to_sharedlib
:
extern
fn
(
*
mut
CMuVM
,
CMuCString
),
pub
compile_to_sharedlib
:
extern
fn
(
*
mut
CMuVM
,
CMuCString
,
*
const
CMuCString
,
CMuArraySize
),
}
#[repr(C)]
...
...
src/vm/api/api_impl/irnodes.rs
View file @
c3ba71ac
...
...
@@ -42,7 +42,10 @@ pub enum NodeType {
TypeStruct
{
id
:
MuID
,
fieldtys
:
Vec
<
MuTypeNode
>
},
TypeHybrid
{
id
:
MuID
,
fixedtys
:
Vec
<
MuTypeNode
>
,
varty
:
MuTypeNode
},
TypeArray
{
id
:
MuID
,
elemty
:
MuTypeNode
,
len
:
usize
},
TypeVector
{
id
:
MuID
,
elemty
:
MuTypeNode
,
lem
:
usize
},
TypeVector
{
id
:
MuID
,
elemty
:
MuTypeNode
,
len
:
usize
},
TypeVoid
{
id
:
MuID
},
TypeTagRef64
{
id
:
MuID
},
TypeRef
{
id
:
MuID
,
ty
:
MuTypeNode
},
TypeIRef
{
id
:
MuID
,
ty
:
MuTypeNode
},
...
...
src/vm/api/api_impl/muirbuilder.rs
View file @
c3ba71ac
This diff is collapsed.
Click to expand it.
src/vm/api/api_impl/muvm.rs
View file @
c3ba71ac
...
...
@@ -70,7 +70,7 @@ impl MuVM {
panic!
(
"Not implemented"
)
}
pub
fn
compile_to_sharedlib
(
&
self
,
lib_name
:
&
str
)
{
pub
fn
compile_to_sharedlib
(
&
self
,
lib_name
:
&
str
,
extra_srcs
:
Vec
<
String
>
)
{
extern
crate
libloading
as
ll
;
use
compiler
::
*
;
...
...
@@ -88,7 +88,7 @@ impl MuVM {
func_names
.push
(
func
.name
()
.unwrap
());
}
backend
::
emit_context
(
&
self
.vm
);
aot
::
link_dylib
(
func_name
s
,
lib_name
);
aot
::
link_dylib
_with_extra_srcs
(
func_names
,
extra_src
s
,
lib_name
);
}
}
...
...
src/vm/api/muapi.h
View file @
c3ba71ac
...
...
@@ -271,7 +271,7 @@ struct MuVM {
// Set handlers
void
(
*
set_trap_handler
)(
MuVM
*
mvm
,
MuTrapHandler
trap_handler
,
MuCPtr
userdata
);
void
(
*
compile_to_sharedlib
)(
MuVM
*
mvm
,
MuCString
lib_name
);
void
(
*
compile_to_sharedlib
)(
MuVM
*
mvm
,
MuCString
lib_name
,
MuCString
*
extra_srcs
,
MuArraySize
n_extra_srcs
);
/// MUAPIPARSER extra_srcs:array:n_extra_srcs
};
// A local context. It can only be used by one thread at a time. It holds many
...
...
src/vm/vm.rs
View file @
c3ba71ac
...
...
@@ -478,6 +478,15 @@ impl <'a> VM {
funcs
.insert
(
func
.id
(),
RwLock
::
new
(
func
));
}
/// The IR builder needs to look-up the function signature from the existing function ID.
pub
fn
get_func_sig_for_func
(
&
self
,
id
:
MuID
)
->
P
<
MuFuncSig
>
{
let
funcs_lock
=
self
.funcs
.read
()
.unwrap
();
match
funcs_lock
.get
(
&
id
)
{
Some
(
func
)
=>
func
.read
()
.unwrap
()
.sig
.clone
(),
None
=>
panic!
(
"cannot find Mu function #{}"
,
id
)
}
}
pub
fn
define_func_version
(
&
self
,
func_ver
:
MuFunctionVersion
)
{
info!
(
"define function version {}"
,
func_ver
);
// record this version
...
...
@@ -501,6 +510,72 @@ impl <'a> VM {
// redefinition happens here
// do stuff
}
/// Add a new bundle into VM.
///
/// This function will drain the contents of all arguments.
///
/// Ideally, this function should happen atomically. e.g. The client should not see a new type
/// added without also seeing a new function added.
pub
fn
declare_many
(
&
self
,
new_id_name_map
:
&
mut
HashMap
<
MuID
,
MuName
>
,
new_types
:
&
mut
HashMap
<
MuID
,
P
<
MuType
>>
,
new_func_sigs
:
&
mut
HashMap
<
MuID
,
P
<
MuFuncSig
>>
,
new_constants
:
&
mut
HashMap
<
MuID
,
P
<
Value
>>
,
new_globals
:
&
mut
HashMap
<
MuID
,
P
<
Value
>>
,
new_funcs
:
&
mut
HashMap
<
MuID
,
Box
<
MuFunction
>>
,
new_func_vers
:
&
mut
HashMap
<
MuID
,
Box
<
MuFunctionVersion
>>
)
{
// Make sure other components, if ever acquiring multiple locks at the same time, acquire
// them in this order, to prevent deadlock.
let
mut
id_name_map
=
self
.id_name_map
.write
()
.unwrap
();
let
mut
name_id_map
=
self
.name_id_map
.write
()
.unwrap
();
let
mut
types
=
self
.types
.write
()
.unwrap
();
let
mut
constants
=
self
.constants
.write
()
.unwrap
();
let
mut
globals
=
self
.globals
.write
()
.unwrap
();
let
mut
func_sigs
=
self
.func_sigs
.write
()
.unwrap
();
let
mut
funcs
=
self
.funcs
.write
()
.unwrap
();
let
mut
func_vers
=
self
.func_vers
.write
()
.unwrap
();
for
(
id
,
name
)
in
new_id_name_map
.drain
()
{
id_name_map
.insert
(
id
,
name
.clone
());
name_id_map
.insert
(
name
,
id
);
}
for
(
id
,
obj
)
in
new_types
.drain
()
{
types
.insert
(
id
,
obj
);
}
for
(
id
,
obj
)
in
new_constants
.drain
()
{
constants
.insert
(
id
,
obj
);
}
for
(
id
,
obj
)
in
new_globals
.drain
()
{
globals
.insert
(
id
,
obj
);
}
for
(
id
,
obj
)
in
new_func_sigs
.drain
()
{
func_sigs
.insert
(
id
,
obj
);
}
for
(
id
,
obj
)
in
new_funcs
.drain
()
{
funcs
.insert
(
id
,
RwLock
::
new
(
*
obj
));
}
for
(
id
,
obj
)
in
new_func_vers
.drain
()
{
let
func_id
=
obj
.func_id
;
func_vers
.insert
(
id
,
RwLock
::
new
(
*
obj
));
{
trace!
(
"Adding funcver {} as a version of {}..."
,
id
,
func_id
);
let
func
=
funcs
.get_mut
(
&
func_id
)
.unwrap
();
func
.write
()
.unwrap
()
.new_version
(
id
);
trace!
(
"Added funcver {} as a version of {} {:?}."
,
id
,
func_id
,
func
);
}
}
// Locks released here
}
pub
fn
add_compiled_func
(
&
self
,
func
:
CompiledFunction
)
{
debug_assert!
(
self
.funcs
.read
()
.unwrap
()
.contains_key
(
&
func
.func_id
));
...
...
tests/test_compiler/test_binop.rs
View file @
c3ba71ac
...
...
@@ -173,5 +173,175 @@ fn sdiv() -> VM {
vm
.define_func_version
(
func_ver
);
vm
}
#[test]
fn
test_shl
()
{
let
lib
=
testutil
::
compile_fnc
(
"shl"
,
&
shl
);
unsafe
{
let
shl
:
libloading
::
Symbol
<
unsafe
extern
fn
(
u64
,
u8
)
->
u64
>
=
lib
.get
(
b
"shl"
)
.unwrap
();
let
shl_1_2
=
shl
(
1
,
2
);
println!
(
"shl(1, 2) = {}"
,
shl_1_2
);
assert
!
(
shl_1_2
==
4
);
let
shl_2_2
=
shl
(
2
,
2
);
println!
(
"shl(2, 2) = {}"
,
shl_2_2
);
assert
!
(
shl_2_2
==
8
);
}
}
fn
shl
()
->
VM
{
let
vm
=
VM
::
new
();
// .typedef @int64 = int<64>
let
type_def_int64
=
vm
.declare_type
(
vm
.next_id
(),
MuType_
::
int
(
64
));
vm
.set_name
(
type_def_int64
.as_entity
(),
Mu
(
"int64"
));
// .typedef @int8 = int<8>
let
type_def_int8
=
vm
.declare_type
(
vm
.next_id
(),
MuType_
::
int
(
8
));
vm
.set_name
(
type_def_int8
.as_entity
(),
Mu
(
"int8"
));
// .funcsig @shl_sig = (@int64 @int8) -> (@int64)
let
shl_sig
=
vm
.declare_func_sig
(
vm
.next_id
(),
vec!
[
type_def_int64
.clone
()],
vec!
[
type_def_int64
.clone
(),
type_def_int8
.clone
()]);
vm
.set_name
(
shl_sig
.as_entity
(),
Mu
(
"shl_sig"
));
// .funcdecl @shl <@shl_sig>
let
func_id
=
vm
.next_id
();
let
func
=
MuFunction
::
new
(
func_id
,
shl_sig
.clone
());
vm
.set_name
(
func
.as_entity
(),
Mu
(
"shl"
));
vm
.declare_func
(
func
);
// .funcdef @shl VERSION @shl_v1 <@shl_sig>
let
mut
func_ver
=
MuFunctionVersion
::
new
(
vm
.next_id
(),
func_id
,
shl_sig
.clone
());
vm
.set_name
(
func_ver
.as_entity
(),
Mu
(
"shl_v1"
));
// %entry(<@int64> %a, <@int8> %b):
let
mut
blk_entry
=
Block
::
new
(
vm
.next_id
());
vm
.set_name
(
blk_entry
.as_entity
(),
Mu
(
"entry"
));
let
blk_entry_a
=
func_ver
.new_ssa
(
vm
.next_id
(),
type_def_int64
.clone
());
vm
.set_name
(
blk_entry_a
.as_entity
(),
Mu
(
"blk_entry_a"
));
let
blk_entry_b
=
func_ver
.new_ssa
(
vm
.next_id
(),
type_def_int8
.clone
());
vm
.set_name
(
blk_entry_b
.as_entity
(),
Mu
(
"blk_entry_b"
));
// %r = SHL %a %b
let
blk_entry_r
=
func_ver
.new_ssa
(
vm
.next_id
(),
type_def_int64
.clone
());
vm
.set_name
(
blk_entry_r
.as_entity
(),
Mu
(
"blk_entry_r"
));
let
blk_entry_add
=
func_ver
.new_inst
(
Instruction
{
hdr
:
MuEntityHeader
::
unnamed
(
vm
.next_id
()),
value
:
Some
(
vec!
[
blk_entry_r
.clone_value
()]),
ops
:
RwLock
::
new
(
vec!
[
blk_entry_a
.clone
(),
blk_entry_b
.clone
()]),
v
:
Instruction_
::
BinOp
(
BinOp
::
Shl
,
0
,
1
)
});
// RET %r
let
blk_entry_term
=
func_ver
.new_inst
(
Instruction
{
hdr
:
MuEntityHeader
::
unnamed
(
vm
.next_id
()),
value
:
None
,
ops
:
RwLock
::
new
(
vec!
[
blk_entry_r
.clone
()]),
v
:
Instruction_
::
Return
(
vec!
[
0
])
});
blk_entry
.content
=
Some
(
BlockContent
{
args
:
vec!
[
blk_entry_a
.clone_value
(),
blk_entry_b
.clone_value
()],
exn_arg
:
None
,
body
:
vec!
[
blk_entry_add
,
blk_entry_term
],
keepalives
:
None
});
func_ver
.define
(
FunctionContent
{
entry
:
blk_entry
.id
(),
blocks
:
hashmap!
{
blk_entry
.id
()
=>
blk_entry
}
});
vm
.define_func_version
(
func_ver
);
vm
}
#[test]
fn
test_lshr
()
{
let
lib
=
testutil
::
compile_fnc
(
"lshr"
,
&
lshr
);
unsafe
{
let
lshr
:
libloading
::
Symbol
<
unsafe
extern
fn
(
u64
,
u8
)
->
u64
>
=
lib
.get
(
b
"lshr"
)
.unwrap
();
let
lshr_8_3
=
lshr
(
8
,
3
);
println!
(
"lshr(8, 3) = {}"
,
lshr_8_3
);
assert
!
(
lshr_8_3
==
1
);
}
}
fn
lshr
()
->
VM
{
let
vm
=
VM
::
new
();
// .typedef @int64 = int<64>
let
type_def_int64
=
vm
.declare_type
(
vm
.next_id
(),
MuType_
::
int
(
64
));
vm
.set_name
(
type_def_int64
.as_entity
(),
Mu
(
"int64"
));
// .typedef @int8 = int<8>
let
type_def_int8
=
vm
.declare_type
(
vm
.next_id
(),
MuType_
::
int
(
8
));
vm
.set_name
(
type_def_int8
.as_entity
(),
Mu
(
"int8"
));
// .funcsig @lshr_sig = (@int64 @int8) -> (@int64)
let
lshr_sig
=
vm
.declare_func_sig
(
vm
.next_id
(),
vec!
[
type_def_int64
.clone
()],
vec!
[
type_def_int64
.clone
(),
type_def_int8
.clone
()]);
vm
.set_name
(
lshr_sig
.as_entity
(),
Mu
(
"lshr_sig"
));