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
d28af85a
Commit
d28af85a
authored
Aug 18, 2016
by
qinsoon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
serialization
parent
d3c8e060
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
377 additions
and
155 deletions
+377
-155
src/ast/inst.rs
src/ast/inst.rs
+57
-13
src/ast/ir.rs
src/ast/ir.rs
+22
-22
src/ast/op.rs
src/ast/op.rs
+4
-4
src/ast/ptr.rs
src/ast/ptr.rs
+25
-34
src/ast/types.rs
src/ast/types.rs
+4
-14
src/compiler/backend/arch/x86_64/inst_sel.rs
src/compiler/backend/arch/x86_64/inst_sel.rs
+12
-12
src/compiler/backend/mod.rs
src/compiler/backend/mod.rs
+2
-2
src/compiler/passes/def_use.rs
src/compiler/passes/def_use.rs
+1
-1
src/compiler/passes/tree_gen.rs
src/compiler/passes/tree_gen.rs
+1
-1
src/runtime/thread.rs
src/runtime/thread.rs
+1
-0
src/vm/vm.rs
src/vm/vm.rs
+183
-23
tests/test_api/test_vm_serialize.rs
tests/test_api/test_vm_serialize.rs
+37
-1
tests/test_compiler/test_global.rs
tests/test_compiler/test_global.rs
+1
-1
tests/test_compiler/test_instsel.rs
tests/test_compiler/test_instsel.rs
+1
-1
tests/test_compiler/test_pre_instsel.rs
tests/test_compiler/test_pre_instsel.rs
+6
-6
tests/test_compiler/test_regalloc.rs
tests/test_compiler/test_regalloc.rs
+2
-2
tests/test_ir/test_ir.rs
tests/test_ir/test_ir.rs
+17
-17
tests/test_vm/test_thread.rs
tests/test_vm/test_thread.rs
+1
-1
No files found.
src/ast/inst.rs
View file @
d28af85a
...
...
@@ -6,15 +6,59 @@ use utils::vec_utils::as_str as vector_as_str;
use
utils
::
vec_utils
;
use
std
::
fmt
;
use
std
::
cell
::
RefCell
;
use
std
::
sync
::
RwLock
;
#[derive(Debug
,
Clone
)]
#[derive(Debug)]
pub
struct
Instruction
{
pub
value
:
Option
<
Vec
<
P
<
Value
>>>
,
pub
ops
:
R
efCell
<
Vec
<
P
<
TreeNode
>>>
,
pub
ops
:
R
wLock
<
Vec
<
P
<
TreeNode
>>>
,
pub
v
:
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"
,
3
,
|
s
|
{
try!
(
s
.emit_struct_field
(
"value"
,
0
,
|
s
|
self
.value
.encode
(
s
)));
let
ops
=
&
self
.ops
.read
()
.unwrap
();
try!
(
s
.emit_struct_field
(
"ops"
,
1
,
|
s
|
ops
.encode
(
s
)));
try!
(
s
.emit_struct_field
(
"v"
,
2
,
|
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"
,
3
,
|
d
|
{
let
value
=
try!
(
d
.read_struct_field
(
"value"
,
0
,
|
d
|
Decodable
::
decode
(
d
)));
let
ops
=
try!
(
d
.read_struct_field
(
"ops"
,
1
,
|
d
|
Decodable
::
decode
(
d
)));
let
v
=
try!
(
d
.read_struct_field
(
"v"
,
2
,
|
d
|
Decodable
::
decode
(
d
)));
Ok
(
Instruction
{
value
:
value
,
ops
:
RwLock
::
new
(
ops
),
v
:
v
})
})
}
}
impl
Clone
for
Instruction
{
fn
clone
(
&
self
)
->
Self
{
Instruction
{
value
:
self
.value
.clone
(),
ops
:
RwLock
::
new
(
self
.ops
.read
()
.unwrap
()
.clone
()),
v
:
self
.v
.clone
()
}
}
}
impl
Instruction
{
fn
debug_str
(
&
self
,
ops
:
&
Vec
<
P
<
TreeNode
>>
)
->
String
{
self
.v
.debug_str
(
ops
)
...
...
@@ -23,7 +67,7 @@ impl Instruction {
impl
fmt
::
Display
for
Instruction
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
let
ops
=
&
self
.ops
.
borrow
();
let
ops
=
&
self
.ops
.
read
()
.unwrap
();
if
self
.value
.is_some
()
{
write!
(
f
,
"{} = {}"
,
vector_as_str
(
self
.value
.as_ref
()
.unwrap
()),
self
.v
.debug_str
(
ops
))
}
else
{
...
...
@@ -32,7 +76,7 @@ impl fmt::Display for Instruction {
}
}
#[derive(Debug,
Clone)]
#[derive(Debug,
Clone
,
RustcEncodable,
RustcDecodable
)]
pub
enum
Instruction_
{
// non-terminal instruction
...
...
@@ -189,7 +233,7 @@ pub enum Instruction_ {
branches
:
Vec
<
(
OpIndex
,
Destination
)
>
},
ExnInstruction
{
inner
:
P
<
Instruction
>
,
inner
:
Box
<
Instruction
>
,
resume
:
ResumptionData
}
}
...
...
@@ -297,7 +341,7 @@ impl Instruction_ {
}
}
#[derive(Copy,
Clone,
Debug)]
#[derive(Copy,
Clone,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
enum
MemoryOrder
{
NotAtomic
,
Relaxed
,
...
...
@@ -308,18 +352,18 @@ pub enum MemoryOrder {
SeqCst
}
#[derive(Copy,
Clone,
Debug)]
#[derive(Copy,
Clone,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
enum
CallConvention
{
Mu
,
Foreign
(
ForeignFFI
)
}
#[derive(Copy,
Clone,
Debug)]
#[derive(Copy,
Clone,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
enum
ForeignFFI
{
C
}
#[derive(Clone,
Debug)]
#[derive(Clone,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
CallData
{
pub
func
:
OpIndex
,
pub
args
:
Vec
<
OpIndex
>
,
...
...
@@ -332,7 +376,7 @@ impl CallData {
}
}
#[derive(Clone,
Debug)]
#[derive(Clone,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
ResumptionData
{
pub
normal_dest
:
Destination
,
pub
exn_dest
:
Destination
...
...
@@ -344,7 +388,7 @@ impl ResumptionData {
}
}
#[derive(Clone,
Debug)]
#[derive(Clone,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
Destination
{
pub
target
:
MuID
,
pub
args
:
Vec
<
DestArg
>
...
...
@@ -377,7 +421,7 @@ impl Destination {
}
}
#[derive(Clone,
Debug)]
#[derive(Clone,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
enum
DestArg
{
Normal
(
OpIndex
),
Freshbound
(
usize
)
...
...
src/ast/ir.rs
View file @
d28af85a
...
...
@@ -54,7 +54,7 @@ pub fn new_internal_id() -> MuID {
ret
}
#[derive(Debug)]
#[derive(Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
MuFunction
{
pub
hdr
:
MuEntityHeader
,
...
...
@@ -89,7 +89,7 @@ impl fmt::Display for MuFunction {
}
}
#[derive(Debug)]
#[derive(Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
MuFunctionVersion
{
pub
hdr
:
MuEntityHeader
,
...
...
@@ -153,8 +153,8 @@ impl MuFunctionVersion {
})
}
pub
fn
new_inst
(
&
mut
self
,
id
:
MuID
,
v
:
Instruction
)
->
P
<
TreeNode
>
{
P
(
TreeNode
{
pub
fn
new_inst
(
&
mut
self
,
id
:
MuID
,
v
:
Instruction
)
->
Box
<
TreeNode
>
{
Box
::
new
(
TreeNode
{
hdr
:
MuEntityHeader
::
unnamed
(
id
),
op
:
pick_op_code_for_inst
(
&
v
),
v
:
TreeNode_
::
Instruction
(
v
),
...
...
@@ -162,7 +162,7 @@ impl MuFunctionVersion {
}
}
#[derive(Debug)]
#[derive(Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
FunctionContent
{
pub
entry
:
MuID
,
pub
blocks
:
HashMap
<
MuID
,
Block
>
...
...
@@ -195,7 +195,7 @@ impl FunctionContent {
}
}
#[derive(Debug)]
#[derive(Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
FunctionContext
{
pub
value_tags
:
HashMap
<
MuName
,
MuID
>
,
pub
values
:
HashMap
<
MuID
,
SSAVarEntry
>
...
...
@@ -234,7 +234,7 @@ impl FunctionContext {
}
}
#[derive(Debug)]
#[derive(Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
Block
{
pub
hdr
:
MuEntityHeader
,
pub
content
:
Option
<
BlockContent
>
,
...
...
@@ -247,7 +247,7 @@ impl Block {
}
}
#[derive(Debug)]
#[derive(Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
ControlFlow
{
pub
preds
:
Vec
<
MuID
>
,
pub
succs
:
Vec
<
BlockEdge
>
...
...
@@ -286,7 +286,7 @@ impl default::Default for ControlFlow {
}
}
#[derive(Copy,
Clone,
Debug)]
#[derive(Copy,
Clone,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
BlockEdge
{
pub
target
:
MuID
,
pub
kind
:
EdgeKind
,
...
...
@@ -300,15 +300,15 @@ impl fmt::Display for BlockEdge {
}
}
#[derive(Copy,
Clone,
Debug)]
#[derive(Copy,
Clone,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
enum
EdgeKind
{
Forward
,
Backward
}
#[derive(Debug)]
#[derive(Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
BlockContent
{
pub
args
:
Vec
<
P
<
Value
>>
,
pub
body
:
Vec
<
P
<
TreeNode
>>
,
pub
body
:
Vec
<
Box
<
TreeNode
>>
,
pub
keepalives
:
Option
<
Vec
<
P
<
Value
>>>
}
...
...
@@ -321,7 +321,7 @@ impl BlockContent {
match
last_inst
.v
{
TreeNode_
::
Instruction
(
ref
inst
)
=>
{
let
ops
=
inst
.ops
.
borrow
();
let
ops
=
inst
.ops
.
read
()
.unwrap
();
match
inst
.v
{
Instruction_
::
Return
(
_
)
|
Instruction_
::
ThreadExit
...
...
@@ -383,7 +383,7 @@ impl BlockContent {
}
}
#[derive(Debug)]
#[derive(Debug
,
RustcEncodable,
RustcDecodable
)]
/// always use with P<TreeNode>
pub
struct
TreeNode
{
pub
hdr
:
MuEntityHeader
,
...
...
@@ -447,14 +447,14 @@ impl fmt::Display for TreeNode {
}
}
#[derive(Debug,
Clon
e)]
#[derive(Debug,
RustcEncodable,
RustcDecodabl
e)]
pub
enum
TreeNode_
{
Value
(
P
<
Value
>
),
Instruction
(
Instruction
)
}
/// always use with P<Value>
#[derive(Debug,
PartialEq)]
#[derive(Debug,
PartialEq
,
RustcEncodable,
RustcDecodable
)]
pub
struct
Value
{
pub
hdr
:
MuEntityHeader
,
pub
ty
:
P
<
MuType
>
,
...
...
@@ -528,7 +528,7 @@ impl fmt::Display for Value {
}
}
#[derive(Debug,
Clone,
PartialEq)]
#[derive(Debug,
Clone,
PartialEq
,
RustcEncodable,
RustcDecodable
)]
pub
enum
Value_
{
SSAVar
(
MuID
),
Constant
(
Constant
),
...
...
@@ -536,7 +536,7 @@ pub enum Value_ {
Memory
(
MemoryLocation
)
}
#[derive(Debug,
Clon
e)]
#[derive(Debug,
RustcEncodable,
RustcDecodabl
e)]
pub
struct
SSAVarEntry
{
pub
id
:
MuID
,
pub
name
:
Option
<
MuName
>
,
...
...
@@ -566,12 +566,12 @@ impl fmt::Display for SSAVarEntry {
}
}
#[derive(Debug,
Clone,
PartialEq)]
#[derive(Debug,
Clone,
PartialEq
,
RustcEncodable,
RustcDecodable
)]
pub
enum
Constant
{
Int
(
u64
),
Float
(
f32
),
Double
(
f64
),
IRef
(
Address
),
//
IRef(Address),
FuncRef
(
MuID
),
UFuncRef
(
MuID
),
Vector
(
Vec
<
Constant
>
),
...
...
@@ -583,7 +583,7 @@ impl fmt::Display for Constant {
&
Constant
::
Int
(
v
)
=>
write!
(
f
,
"{}"
,
v
),
&
Constant
::
Float
(
v
)
=>
write!
(
f
,
"{}"
,
v
),
&
Constant
::
Double
(
v
)
=>
write!
(
f
,
"{}"
,
v
),
&
Constant
::
IRef
(
v
)
=>
write!
(
f
,
"{}"
,
v
),
//
&Constant::IRef(v) => write!(f, "{}", v),
&
Constant
::
FuncRef
(
v
)
=>
write!
(
f
,
"{}"
,
v
),
&
Constant
::
UFuncRef
(
v
)
=>
write!
(
f
,
"{}"
,
v
),
&
Constant
::
Vector
(
ref
v
)
=>
{
...
...
@@ -600,7 +600,7 @@ impl fmt::Display for Constant {
}
}
#[derive(Debug,
Clone,
PartialEq)]
#[derive(Debug,
Clone,
PartialEq
,
RustcEncodable,
RustcDecodable
)]
pub
enum
MemoryLocation
{
Address
{
base
:
P
<
Value
>
,
...
...
src/ast/op.rs
View file @
d28af85a
...
...
@@ -2,7 +2,7 @@ use ast::ptr::P;
use
ast
::
types
::
*
;
use
ast
::
inst
::
*
;
#[derive(Copy,
Clone,
Debug,
PartialEq)]
#[derive(Copy,
Clone,
Debug,
PartialEq
,
RustcEncodable,
RustcDecodable
)]
pub
enum
OpCode
{
// SSA
RegI64
,
...
...
@@ -112,7 +112,7 @@ pub fn pick_op_code_for_value(ty: &P<MuType>) -> OpCode {
}
}
#[derive(Copy,
Clone,
Debug,
PartialEq)]
#[derive(Copy,
Clone,
Debug,
PartialEq
,
RustcEncodable,
RustcDecodable
)]
pub
enum
BinOp
{
// Int(n) BinOp Int(n) -> Int(n)
Add
,
...
...
@@ -138,7 +138,7 @@ pub enum BinOp {
FRem
}
#[derive(Copy,
Clone,
Debug,
PartialEq)]
#[derive(Copy,
Clone,
Debug,
PartialEq
,
RustcEncodable,
RustcDecodable
)]
pub
enum
CmpOp
{
// for Int comparison
EQ
,
...
...
@@ -171,7 +171,7 @@ pub enum CmpOp {
FUNO
}
#[derive(Copy,
Clone,
Debug,
PartialEq)]
#[derive(Copy,
Clone,
Debug,
PartialEq
,
RustcEncodable,
RustcDecodable
)]
pub
enum
AtomicRMWOp
{
XCHG
,
ADD
,
...
...
src/ast/ptr.rs
View file @
d28af85a
...
...
@@ -36,37 +36,28 @@
//! implementation changes (using a special thread-local heap, for example).
//! Moreover, a switch to, e.g. `P<'a, T>` would be easy and mostly automated.
//
use std::fmt::{self, Display, Debug};
//
use std::hash::{Hash, Hasher};
//
use std::ops::Deref;
//use std::ops::DerefMut
;
use
std
::
fmt
::{
self
,
Display
,
Debug
};
use
std
::
hash
::{
Hash
,
Hasher
};
use
std
::
ops
::
Deref
;
use
rustc_serialize
::{
Encodable
,
Encoder
,
Decodable
,
Decoder
}
;
use
std
::
sync
::
Arc
;
pub
type
P
<
T
>
=
Arc
<
T
>
;
use
ast
::
ir
::
MuEntity
;
///// An owned smart pointer.
//pub struct P<T> {
// ptr:
Box
<T>
pub
type
P
<
T
>
=
Arc
<
T
>
;
//pub struct P<T
: MuEntity
> {
// ptr:
Arc
<T>
//}
#[allow(non_snake_case)]
/// Construct a `P<T>` from a `T` value.
pub
fn
P
<
T
:
'static
>
(
value
:
T
)
->
P
<
T
>
{
pub
fn
P
<
T
:
MuEntity
>
(
value
:
T
)
->
P
<
T
>
{
// P {ptr: Arc::new(value)}
Arc
::
new
(
value
)
}
//impl<T: 'static> P<T> {
// /// Move out of the pointer.
// /// Intended for chaining transformations not covered by `map`.
// pub fn and_then<U, F>(self, f: F) -> U where
// F: FnOnce(T) -> U,
// {
// f(*self.ptr)
// }
//}
//
//impl<T> Deref for P<T> {
//impl<T: MuEntity> Deref for P<T> {
// type Target = T;
//
// fn deref<'a>(&'a self) -> &'a T {
...
...
@@ -74,45 +65,45 @@ pub fn P<T: 'static>(value: T) -> P<T> {
// }
//}
//
//impl<T> DerefMut for P<T> {
// fn deref_mut<'a>(&'a mut self) -> &'a mut T {
// &mut *self.ptr
// }
//}
//
//impl<T: 'static + Clone> Clone for P<T> {
//impl<T: MuEntity> Clone for P<T> {
// fn clone(&self) -> P<T> {
// P
((**self).clone())
// P
{ptr: self.ptr.clone()}
// }
//}
//
//impl<T: PartialEq> PartialEq for P<T> {
//impl<T:
MuEntity +
PartialEq> PartialEq for P<T> {
// fn eq(&self, other: &P<T>) -> bool {
// **self == **other
// }
//}
//
//impl<T: Eq> Eq for P<T> {}
//impl<T:
MuEntity +
Eq> Eq for P<T> {}
//
//impl<T: Debug> Debug for P<T> {
//impl<T:
MuEntity +
Debug> Debug for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Debug::fmt(&**self, f)
// }
//}
//impl<T: Display> Display for P<T> {
//impl<T:
MuEntity +
Display> Display for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Display::fmt(&**self, f)
// }
//}
//
//impl<T> fmt::Pointer for P<T> {
//impl<T
: MuEntity
> fmt::Pointer for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// fmt::Pointer::fmt(&self.ptr, f)
// }
//}
//
//impl<T: Hash> Hash for P<T> {
//impl<T:
MuEntity +
Hash> Hash for P<T> {
// fn hash<H: Hasher>(&self, state: &mut H) {
// (**self).hash(state);
// }
//}
//impl<T: MuEntity> Encodable for P<T> {
// fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
// s.emit_usize(self.id())
// }
//}
\ No newline at end of file
src/ast/types.rs
View file @
d28af85a
...
...
@@ -8,7 +8,7 @@ use std::sync::RwLock;
use
rustc_serialize
::{
Encodable
,
Encoder
,
Decodable
,
Decoder
};
#[derive(PartialEq,
Debug)]
#[derive(PartialEq,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
MuType
{
pub
hdr
:
MuEntityHeader
,
pub
v
:
MuType_
...
...
@@ -23,17 +23,7 @@ impl MuType {
}
}
//impl Encodable for MuType {
// fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
// //serialize 2 fields
// s.emit_struct("MuType", 2, |s| {
// // hdr
// try!(s.emit_struct_field("hdr", 0, |s| hdr.encode(s)));
// })
// }
//}
#[derive(PartialEq,
Debug)]
#[derive(PartialEq,
Debug,
RustcEncodable,
RustcDecodable)]
pub
enum
MuType_
{
/// int <length>
Int
(
usize
),
...
...
@@ -117,7 +107,7 @@ lazy_static! {
pub
static
ref
STRUCT_TAG_MAP
:
RwLock
<
HashMap
<
MuName
,
StructType_
>>
=
RwLock
::
new
(
HashMap
::
new
());
}
#[derive(PartialEq,
Debug)]
#[derive(PartialEq,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
StructType_
{
tys
:
Vec
<
P
<
MuType
>>
}
...
...
@@ -335,7 +325,7 @@ macro_rules! is_type (
)
);
#[derive(PartialEq,
Debug)]
#[derive(PartialEq,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
MuFuncSig
{
pub
hdr
:
MuEntityHeader
,
pub
ret_tys
:
Vec
<
P
<
MuType
>>
,
...
...
src/compiler/backend/arch/x86_64/inst_sel.rs
View file @
d28af85a
...
...
@@ -38,7 +38,7 @@ impl <'a> InstructionSelection {
// 3. we need to backup/restore all the callee-saved registers
// if any of these assumption breaks, we will need to re-emit the code
#[allow(unused_variables)]
fn
instruction_select
(
&
mut
self
,
node
:
&
'a
P
<
TreeNode
>
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
)
{
fn
instruction_select
(
&
mut
self
,
node
:
&
'a
TreeNode
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
)
{
trace!
(
"instsel on node {}"
,
node
);
match
node
.v
{
...
...
@@ -55,7 +55,7 @@ impl <'a> InstructionSelection {
}
};
let
ops
=
inst
.ops
.
borrow
();
let
ops
=
inst
.ops
.
read
()
.unwrap
();
self
.process_dest
(
&
ops
,
fallthrough_dest
,
cur_func
,
vm
);
self
.process_dest
(
&
ops
,
branch_dest
,
cur_func
,
vm
);
...
...
@@ -94,7 +94,7 @@ impl <'a> InstructionSelection {
},
Instruction_
::
Branch1
(
ref
dest
)
=>
{
let
ops
=
inst
.ops
.
borrow
();
let
ops
=
inst
.ops
.
read
()
.unwrap
();
self
.process_dest
(
&
ops
,
dest
,
cur_func
,
vm
);
...
...
@@ -108,7 +108,7 @@ impl <'a> InstructionSelection {
Instruction_
::
ExprCall
{
ref
data
,
is_abort
}
=>
{
trace!
(
"deal with pre-call convention"
);
let
ops
=
inst
.ops
.
borrow
();
let
ops
=
inst
.ops
.
read
()
.unwrap
();
let
rets
=
inst
.value
.as_ref
()
.unwrap
();
let
ref
func
=
ops
[
data
.func
];
let
ref
func_sig
=
match
func
.v
{
...
...
@@ -206,7 +206,7 @@ impl <'a> InstructionSelection {
},
Instruction_
::
BinOp
(
op
,
op1
,
op2
)
=>
{
let
ops
=
inst
.ops
.
borrow
();
let
ops
=
inst
.ops
.
read
()
.unwrap
();
match
op
{
op
::
BinOp
::
Add
=>
{
...
...
@@ -352,7 +352,7 @@ impl <'a> InstructionSelection {
// load on x64 generates mov inst (no matter what order is specified)
// https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
Instruction_
::
Load
{
is_ptr
,
order
,
mem_loc
}
=>
{
let
ops
=
inst
.ops
.
borrow
();
let
ops
=
inst
.ops
.
read
()
.unwrap
();
let
ref
loc_op
=
ops
[
mem_loc
];
// check order
...
...
@@ -377,7 +377,7 @@ impl <'a> InstructionSelection {
}
Instruction_
::
Store
{
is_ptr
,
order
,
mem_loc
,
value
}
=>
{
let
ops
=
inst
.ops
.
borrow
();
let
ops
=
inst
.ops
.
read
()
.unwrap
();
let
ref
loc_op
=
ops
[
mem_loc
];
let
ref
val_op
=
ops
[
value
];
...
...
@@ -504,7 +504,7 @@ impl <'a> InstructionSelection {
// FIXME: this may change in the future
// prepare return regs
let
ref
ops
=
ret_inst
.ops
.
borrow
();
let
ref
ops
=
ret_inst
.ops
.
read
()
.unwrap
();
let
ret_val_indices
=
match
ret_inst
.v
{
Instruction_
::
Return
(
ref
vals
)
=>
vals
,
_
=>
panic!
(
"expected ret inst"
)
...
...
@@ -556,7 +556,7 @@ impl <'a> InstructionSelection {
fn
emit_cmp_res
(
&
mut
self
,
cond
:
&
P
<
TreeNode
>
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
)
->
op
::
CmpOp
{
match
cond
.v
{
TreeNode_
::
Instruction
(
ref
inst
)
=>
{
let
ops
=
inst
.ops
.
borrow
();
let
ops
=
inst
.ops
.
read
()
.unwrap
();
match
inst
.v
{
Instruction_
::
CmpOp
(
op
,
op1
,
op2
)
=>
{
...
...
@@ -591,7 +591,7 @@ impl <'a> InstructionSelection {
}
}
fn
match_ireg
(
&
mut
self
,
op
:
&
P
<
TreeNode
>
)
->
bool
{
fn
match_ireg
(
&
mut
self
,
op
:
&
TreeNode
)
->
bool
{
match
op
.v
{
TreeNode_
::
Instruction
(
ref
inst
)
=>
{
if
inst
.value
.is_some
()
{
...
...
@@ -737,7 +737,7 @@ impl <'a> InstructionSelection {
unimplemented!
()
}
fn
emit_get_result
(
&
mut
self
,
node
:
&
P
<
TreeNode
>
)
->
P
<
Value
>
{
fn
emit_get_result
(
&
mut
self
,
node
:
&
TreeNode
)
->
P
<
Value
>
{
match
node
.v
{
TreeNode_
::
Instruction
(
ref
inst
)
=>
{
if
inst
.value
.is_some
()
{
...
...
@@ -817,7 +817,7 @@ impl CompilerPass for InstructionSelection {
self
.backend
.set_block_liveout
(
block_label
.clone
(),
&
live_out
);
for
inst
in
block_content
.body
.iter
()
{
self
.instruction_select
(
inst
,
func
,
vm
);
self
.instruction_select
(
&
inst
,
func
,
vm
);
}
self
.backend
.end_block
(
block_label
);
...
...
src/compiler/backend/mod.rs
View file @
d28af85a
...
...
@@ -147,12 +147,12 @@ fn layout_struct(tys: &Vec<P<MuType>>, vm: &VM) -> BackendTypeInfo {
}
}
#[derive(Clone,
Debug)]
#[derive(Clone,
Debug
,
RustcEncodable,
RustcDecodable
)]
pub
struct
BackendTypeInfo
{
size
:
ByteSize
,
alignment
:
ByteSize
,
struct_layout
:
Option
<
Vec
<
ByteSize
>>
}
#[derive(Clone,
Copy,
Debug,
PartialEq,
Eq,
Hash)]
#[derive(Clone,
Copy,
Debug,
PartialEq,
Eq,
Hash
,
RustcEncodable,
RustcDecodable
)]
pub
enum
RegGroup
{
GPR
,
FPR
}
src/compiler/passes/def_use.rs
View file @
d28af85a
...
...
@@ -54,7 +54,7 @@ impl CompilerPass for DefUse {
// if an SSA appears in operands of instrs, its use count increases
match
node
.v
{
TreeNode_
::
Instruction
(
ref
inst
)
=>
{
for
op
in
inst
.ops
.
borrow
()
.iter
()
{
for
op
in
inst
.ops
.
read
()
.unwrap
()
.iter
()
{
use_op
(
op
,
func_context
);
}
},
...
...
src/compiler/passes/tree_gen.rs
View file @
d28af85a
...
...
@@ -49,7 +49,7 @@ impl CompilerPass for TreeGen {
{
trace!
(
"check if we can replace any operand with inst"
);
let
mut
ops
=
inst
.ops
.
borrow_mut
();
let
mut
ops
=
inst
.ops
.
write
()
.unwrap
();
for
index
in
0
..
ops
.len
()
{
let
possible_ssa_id
=
ops
[
index
]
.extract_ssa_id
();
if
possible_ssa_id
.is_some
()
{
...
...
src/runtime/thread.rs
View file @
d28af85a
...
...
@@ -213,6 +213,7 @@ impl MuThread {
}
}
#[derive(Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
MuPrimordialThread
{
pub
func_id
:
MuID
,
pub
args
:
Vec
<
Constant
>
...
...
src/vm/vm.rs
View file @
d28af85a
This diff is collapsed.
Click to expand it.
tests/test_api/test_vm_serialize.rs
View file @
d28af85a
extern
crate
rustc_serialize
;
use
test_ir
::
test_ir
::
factorial
;
use
mu
::
ast
::
ir
::
*
;
use
mu
::
vm
::
*
;
use
std
::
sync
::
Arc
;
...
...
@@ -16,4 +15,41 @@ fn test_vm_serialize_factorial() {
let
serialized
=
json
::
encode
(
&
vm
)
.unwrap
();
println!
(
"{}"
,
serialized
);
let
reconstruct_vm
:
VM
=
json
::
decode
(
&
serialized
)
.unwrap
();
let
serialized_again
=
json
::
encode
(
&
reconstruct_vm
)
.unwrap
();
println!
(
"{}"
,
serialized_again
);
// check_string_eq_char_by_char(serialized, serialized_again);
}
#[allow(dead_code)]
fn
check_string_eq_char_by_char
(
str1
:
String
,
str2
:
String
)
{
use
std
::
cmp
;
let
min_len
=
cmp
::
min
(
str1
.len
(),
str2
.len
());
println!
(
"str1_len = {}, str2_len = {}"
,
str1
.len
(),
str2
.len
());
let
b1
=
str1
.into_bytes
();
let
b2
=
str2
.into_bytes
();
for
i
in
0
..
min_len
{
if
b1
[
i
]
!=
b2
[
i
]
{
println!
(
"different here ({}):"
,
i
);
print!
(
"str1: .."
);
for
j
in
0
..
20
{
print!
(
"{}"
,
b1
[
i
+
j
]
as
char
);
}
println!
(
".."
);
print!
(
"str2: .."
);
for
j
in
0
..
20
{
print!
(
"{}"
,
b2
[
i
+
j
]
as
char
);
}
println!
(
".."
);
panic!
(
"found difference in two strings"
);
}
}
}
\ No newline at end of file
tests/test_compiler/test_global.rs
View file @
d28af85a
...
...
@@ -29,7 +29,7 @@ fn test_global_access() {
let
funcs
=
vm
.funcs
()
.read
()
.unwrap
();
let
func
=
funcs
.get
(
&
func_id
)
.unwrap
()
.read
()
.unwrap
();
let
func_vers
=
vm
.func_vers
()
.read
()
.unwrap
();
let
mut
func_ver
=
func_vers
.get
(
&
(
func
.id
(),
func
.cur_ver
.unwrap
()
))
.unwrap
()
.write
()
.unwrap
();
let
mut
func_ver
=
func_vers
.get
(
&
func
.cur_ver
.unwrap
(
))
.unwrap
()
.write
()
.unwrap
();
compiler
.compile
(
&
mut
func_ver
);
backend
::
emit_context
(
&
vm
);
...
...
tests/test_compiler/test_instsel.rs
View file @
d28af85a
...
...
@@ -26,7 +26,7 @@ fn test_instsel_fac() {
let
funcs
=
vm
.funcs
()
.read
()
.unwrap
();
let
func
=
funcs
.get
(
&
func_id
)
.unwrap
()
.read
()
.unwrap
();
let
func_vers
=
vm
.func_vers
()
.read
()
.unwrap
();
let
mut
func_ver
=
func_vers
.get
(
&
(
func
.id
(),
func
.cur_ver
.unwrap
()
))
.unwrap
()
.write
()
.unwrap
();
let
mut
func_ver
=
func_vers
.get
(
&
func
.cur_ver
.unwrap
(
))
.unwrap
()
.write
()
.unwrap
();
compiler
.compile
(
&
mut
func_ver
);
}
tests/test_compiler/test_pre_instsel.rs
View file @
d28af85a
...
...
@@ -23,7 +23,7 @@ fn test_use_count() {
let
funcs
=
vm
.funcs
()
.read
()
.unwrap
();
let
func
=
funcs
.get
(
&
func_id
)
.unwrap
()
.read
()
.unwrap
();
let
func_vers
=
vm
.func_vers
()
.read
()
.unwrap
();
let
mut
func_ver
=
func_vers
.get
(
&
(
func
.id
(),
func
.cur_ver
.unwrap
()
))
.unwrap
()
.write
()
.unwrap
();