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
66cd7772
Commit
66cd7772
authored
Nov 30, 2016
by
qinsoon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[wip] inlining
parent
bd087834
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
475 additions
and
3 deletions
+475
-3
src/ast/src/ir.rs
src/ast/src/ir.rs
+96
-0
src/compiler/mod.rs
src/compiler/mod.rs
+1
-0
src/compiler/passes/inlining.rs
src/compiler/passes/inlining.rs
+234
-2
src/testutil/mod.rs
src/testutil/mod.rs
+22
-0
src/vm/vm.rs
src/vm/vm.rs
+11
-0
tests/ir_macros.rs
tests/ir_macros.rs
+24
-0
tests/test_compiler/mod.rs
tests/test_compiler/mod.rs
+2
-1
tests/test_compiler/test_inline.rs
tests/test_compiler/test_inline.rs
+85
-0
No files found.
src/ast/src/ir.rs
View file @
66cd7772
...
...
@@ -188,6 +188,78 @@ impl MuFunctionVersion {
v
:
TreeNode_
::
Instruction
(
v
),
})
}
/// get Map(CallSiteID -> FuncID) that are called by this function
pub
fn
get_static_call_edges
(
&
self
)
->
HashMap
<
MuID
,
MuID
>
{
let
mut
ret
=
HashMap
::
new
();
let
f_content
=
self
.content
.as_ref
()
.unwrap
();
for
(
blk_id
,
block
)
in
f_content
.blocks
.iter
()
{
let
block_content
=
block
.content
.as_ref
()
.unwrap
();
for
inst
in
block_content
.body
.iter
()
{
match
inst
.v
{
TreeNode_
::
Instruction
(
ref
inst
)
=>
{
let
ops
=
inst
.ops
.read
()
.unwrap
();
match
inst
.v
{
Instruction_
::
ExprCall
{
ref
data
,
..
}
|
Instruction_
::
ExprCCall
{
ref
data
,
..
}
|
Instruction_
::
Call
{
ref
data
,
..
}
|
Instruction_
::
CCall
{
ref
data
,
..
}
=>
{
let
ref
callee
=
ops
[
data
.func
];
match
callee
.v
{
TreeNode_
::
Instruction
(
_
)
=>
{},
TreeNode_
::
Value
(
ref
pv
)
=>
match
pv
.v
{
Value_
::
Constant
(
Constant
::
FuncRef
(
id
))
=>
{
ret
.insert
(
inst
.id
(),
id
);},
_
=>
{}
}
}
},
_
=>
{
// do nothing
}
}
},
_
=>
{
unreachable!
()
}
}
}
}
ret
}
pub
fn
has_throw
(
&
self
)
->
bool
{
let
f_content
=
self
.content
.as_ref
()
.unwrap
();
for
(
blk_id
,
block
)
in
f_content
.blocks
.iter
()
{
let
block_content
=
block
.content
.as_ref
()
.unwrap
();
for
inst
in
block_content
.body
.iter
()
{
match
inst
.v
{
TreeNode_
::
Instruction
(
ref
inst
)
=>
{
let
ops
=
inst
.ops
.read
()
.unwrap
();
match
inst
.v
{
Instruction_
::
Throw
(
_
)
=>
{
return
true
;}
_
=>
{
// do nothing
}
}
},
_
=>
{
unreachable!
()
}
}
}
}
false
}
}
#[derive(RustcEncodable,
RustcDecodable,
Clone)]
...
...
@@ -310,6 +382,16 @@ impl Block {
pub
fn
is_exception_block
(
&
self
)
->
bool
{
return
self
.content
.as_ref
()
.unwrap
()
.exn_arg
.is_some
()
}
pub
fn
number_of_irs
(
&
self
)
->
usize
{
if
self
.content
.is_none
()
{
0
}
else
{
let
content
=
self
.content
.as_ref
()
.unwrap
();
content
.body
.len
()
}
}
}
#[derive(Debug,
RustcEncodable,
RustcDecodable,
Clone)]
...
...
@@ -482,6 +564,13 @@ impl TreeNode {
})
}
pub
fn
new_boxed_inst
(
v
:
Instruction
)
->
Box
<
TreeNode
>
{
Box
::
new
(
TreeNode
{
op
:
pick_op_code_for_inst
(
&
v
),
v
:
TreeNode_
::
Instruction
(
v
),
})
}
pub
fn
extract_ssa_id
(
&
self
)
->
Option
<
MuID
>
{
match
self
.v
{
TreeNode_
::
Value
(
ref
pv
)
=>
{
...
...
@@ -514,6 +603,13 @@ impl TreeNode {
_
=>
None
}
}
pub
fn
into_inst
(
self
)
->
Option
<
Instruction
>
{
match
self
.v
{
TreeNode_
::
Instruction
(
inst
)
=>
Some
(
inst
),
_
=>
None
}
}
}
/// use +() to display a node
...
...
src/compiler/mod.rs
View file @
66cd7772
...
...
@@ -64,6 +64,7 @@ impl CompilerPolicy {
impl
Default
for
CompilerPolicy
{
fn
default
()
->
Self
{
let
mut
passes
:
Vec
<
Box
<
CompilerPass
>>
=
vec!
[];
passes
.push
(
Box
::
new
(
passes
::
Inlining
::
new
()));
// ir level passes
passes
.push
(
Box
::
new
(
passes
::
DefUse
::
new
()));
passes
.push
(
Box
::
new
(
passes
::
TreeGen
::
new
()));
...
...
src/compiler/passes/inlining.rs
View file @
66cd7772
This diff is collapsed.
Click to expand it.
src/testutil/mod.rs
View file @
66cd7772
...
...
@@ -66,3 +66,25 @@ pub fn compile_fnc<'a>(fnc_name: &'static str, build_fnc: &'a Fn() -> VM) -> ll:
let
dylib
=
aot
::
link_dylib
(
vec!
[
Mu
(
fnc_name
)],
libname
,
&
vm
);
ll
::
Library
::
new
(
dylib
.as_os_str
())
.unwrap
()
}
pub
fn
compile_fncs
<
'a
>
(
entry
:
&
'static
str
,
fnc_names
:
Vec
<&
'static
str
>
,
build_fnc
:
&
'a
Fn
()
->
VM
)
->
ll
::
Library
{
VM
::
start_logging_trace
;
let
vm
=
Arc
::
new
(
build_fnc
());
let
compiler
=
Compiler
::
new
(
CompilerPolicy
::
default
(),
vm
.clone
());
for
func
in
fnc_names
.iter
()
{
let
func_id
=
vm
.id_of
(
func
);
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
.cur_ver
.unwrap
())
.unwrap
()
.write
()
.unwrap
();
compiler
.compile
(
&
mut
func_ver
);
}
backend
::
emit_context
(
&
vm
);
let
libname
=
&
format!
(
"lib{}.dylib"
,
entry
);
let
dylib
=
aot
::
link_dylib
(
fnc_names
.iter
()
.map
(|
x
|
Mu
(
x
))
.collect
(),
libname
,
&
vm
);
ll
::
Library
::
new
(
dylib
.as_os_str
())
.unwrap
()
}
\ No newline at end of file
src/vm/vm.rs
View file @
66cd7772
...
...
@@ -736,6 +736,17 @@ impl <'a> VM {
pub
fn
func_vers
(
&
self
)
->
&
RwLock
<
HashMap
<
MuID
,
RwLock
<
MuFunctionVersion
>>>
{
&
self
.func_vers
}
pub
fn
get_cur_version_of
(
&
self
,
fid
:
MuID
)
->
Option
<
MuID
>
{
let
funcs_guard
=
self
.funcs
.read
()
.unwrap
();
match
funcs_guard
.get
(
&
fid
)
{
Some
(
rwlock_func
)
=>
{
let
func_guard
=
rwlock_func
.read
()
.unwrap
();
func_guard
.cur_ver
},
None
=>
None
}
}
pub
fn
compiled_funcs
(
&
self
)
->
&
RwLock
<
HashMap
<
MuID
,
RwLock
<
CompiledFunction
>>>
{
&
self
.compiled_funcs
...
...
tests/ir_macros.rs
View file @
66cd7772
...
...
@@ -38,6 +38,11 @@ macro_rules! typedef {
let
$name
=
$vm
.declare_type
(
$vm
.next_id
(),
MuType_
::
hybrid
(
Mu
(
stringify!
(
$name
)),
vec!
[],
$var_ty
.clone
()));
$vm
.set_name
(
$name
.as_entity
(),
Mu
(
stringify!
(
$name
)));
};
((
$vm
:
expr
)
$name
:
ident
=
mu_funcref
(
$sig
:
ident
))
=>
{
let
$name
=
$vm
.declare_type
(
$vm
.next_id
(),
MuType_
::
funcref
(
$sig
.clone
()));
$vm
.set_name
(
$name
.as_entity
(),
Mu
(
stringify!
(
$name
)));
}
}
macro_rules!
constdef
{
...
...
@@ -309,6 +314,25 @@ macro_rules! inst {
});
};
// CALL
((
$vm
:
expr
,
$fv
:
ident
)
$name
:
ident
:
$res
:
ident
=
EXPRCALL
(
$cc
:
expr
,
is_abort
:
$is_abort
:
expr
)
$func
:
ident
(
$
(
$val
:
ident
),
+
))
=>
{
let
ops
=
vec!
[
$func
,
$
(
$val
.clone
()),
*
];
let
ops_len
=
ops
.len
();
let
$name
=
$fv
.new_inst
(
Instruction
{
hdr
:
MuEntityHeader
::
unnamed
(
$vm
.next_id
()),
value
:
Some
(
vec!
[
$res
.clone_value
()]),
ops
:
RwLock
::
new
(
ops
),
v
:
Instruction_
::
ExprCall
{
data
:
CallData
{
func
:
0
,
args
:
(
1
..
ops_len
)
.collect
(),
convention
:
$cc
},
is_abort
:
$is_abort
}
});
};
// RET
((
$vm
:
expr
,
$fv
:
ident
)
$name
:
ident
:
RET
(
$
(
$val
:
ident
),
+
))
=>
{
let
$name
=
$fv
.new_inst
(
Instruction
{
...
...
tests/test_compiler/mod.rs
View file @
66cd7772
...
...
@@ -11,4 +11,5 @@ mod test_int;
mod
test_binop
;
mod
test_controlflow
;
mod
test_call
;
mod
test_mem_inst
;
\ No newline at end of file
mod
test_mem_inst
;
mod
test_inline
;
\ No newline at end of file
tests/test_compiler/test_inline.rs
0 → 100644
View file @
66cd7772
extern
crate
libloading
;
use
mu
::
ast
::
types
::
*
;
use
mu
::
ast
::
ir
::
*
;
use
mu
::
ast
::
inst
::
*
;
use
mu
::
ast
::
op
::
*
;
use
mu
::
vm
::
*
;
use
mu
::
compiler
::
*
;
use
mu
::
testutil
;
use
std
::
sync
::
Arc
;
use
std
::
sync
::
RwLock
;
use
mu
::
testutil
::
aot
;
#[test]
fn
test_inline_add
()
{
let
lib
=
testutil
::
compile_fncs
(
"add_trampoline"
,
vec!
[
"add_trampoline"
,
"add"
],
&
inline_add
);
unsafe
{
let
inline_add
:
libloading
::
Symbol
<
unsafe
extern
fn
(
u64
,
u64
)
->
u64
>
=
lib
.get
(
b
"add_trampoline"
)
.unwrap
();
let
inline_add_1_1
=
inline_add
(
1
,
1
);
println!
(
"add(1, 1) = {}"
,
inline_add_1_1
);
assert
!
(
inline_add_1_1
==
2
);
}
}
fn
inline_add
()
->
VM
{
let
vm
=
VM
::
new
();
typedef!
((
vm
)
int64
=
mu_int
(
64
));
funcsig!
((
vm
)
sig
=
(
int64
,
int64
)
->
(
int64
));
funcdecl!
((
vm
)
<
sig
>
add
);
{
// add
funcdef!
((
vm
)
<
sig
>
add
VERSION
add_v1
);
block!
((
vm
,
add_v1
)
blk_entry
);
ssa!
((
vm
,
add_v1
)
<
int64
>
x
);
ssa!
((
vm
,
add_v1
)
<
int64
>
y
);
ssa!
((
vm
,
add_v1
)
<
int64
>
res
);
inst!
((
vm
,
add_v1
)
blk_entry_add
:
res
=
BINOP
(
BinOp
::
Add
)
x
y
);
inst!
((
vm
,
add_v1
)
blk_entry_ret
:
RET
(
res
)
);
define_block!
((
vm
,
add_v1
)
blk_entry
(
x
,
y
)
{
blk_entry_add
,
blk_entry_ret
});
define_func_ver!
((
vm
)
add_v1
(
entry
:
blk_entry
)
{
blk_entry
});
}
{
// add_trampoline
typedef!
((
vm
)
funcref_to_sig
=
mu_funcref
(
sig
));
constdef!
((
vm
)
<
funcref_to_sig
>
funcref_add
=
Constant
::
FuncRef
(
add
));
funcdecl!
((
vm
)
<
sig
>
add_trampoline
);
funcdef!
((
vm
)
<
sig
>
add_trampoline
VERSION
add_trampoline_v1
);
block!
((
vm
,
add_trampoline_v1
)
tramp_blk_entry
);
ssa!
((
vm
,
add_trampoline_v1
)
<
int64
>
tramp_x
);
ssa!
((
vm
,
add_trampoline_v1
)
<
int64
>
tramp_y
);
consta!
((
vm
,
add_trampoline_v1
)
funcref_add_local
=
funcref_add
);
ssa!
((
vm
,
add_trampoline_v1
)
<
int64
>
tramp_res
);
inst!
((
vm
,
add_trampoline_v1
)
tramp_blk_call
:
tramp_res
=
EXPRCALL
(
CallConvention
::
Mu
,
is_abort
:
false
)
funcref_add_local
(
tramp_x
,
tramp_y
)
);
inst!
((
vm
,
add_trampoline_v1
)
tramp_blk_ret
:
RET
(
tramp_res
)
);
define_block!
((
vm
,
add_trampoline_v1
)
tramp_blk_entry
(
tramp_x
,
tramp_y
)
{
tramp_blk_call
,
tramp_blk_ret
});
define_func_ver!
((
vm
)
add_trampoline_v1
(
entry
:
tramp_blk_entry
)
{
tramp_blk_entry
});
}
vm
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment