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
76504d0b
Commit
76504d0b
authored
Jul 27, 2016
by
qinsoon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[wip] working on api
parent
84e5d475
Changes
32
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
723 additions
and
218 deletions
+723
-218
src/ast/inst.rs
src/ast/inst.rs
+1
-1
src/ast/ir.rs
src/ast/ir.rs
+28
-28
src/ast/types.rs
src/ast/types.rs
+5
-5
src/compiler/backend/arch/arm/inst_sel.rs
src/compiler/backend/arch/arm/inst_sel.rs
+2
-2
src/compiler/backend/arch/x86_64/asm_backend.rs
src/compiler/backend/arch/x86_64/asm_backend.rs
+26
-26
src/compiler/backend/arch/x86_64/codegen.rs
src/compiler/backend/arch/x86_64/codegen.rs
+6
-6
src/compiler/backend/arch/x86_64/inst_sel.rs
src/compiler/backend/arch/x86_64/inst_sel.rs
+14
-14
src/compiler/backend/code_emission.rs
src/compiler/backend/code_emission.rs
+3
-3
src/compiler/backend/mod.rs
src/compiler/backend/mod.rs
+4
-4
src/compiler/backend/peephole_opt.rs
src/compiler/backend/peephole_opt.rs
+3
-3
src/compiler/backend/reg_alloc/mod.rs
src/compiler/backend/reg_alloc/mod.rs
+5
-5
src/compiler/mod.rs
src/compiler/mod.rs
+4
-4
src/compiler/passes/control_flow.rs
src/compiler/passes/control_flow.rs
+8
-8
src/compiler/passes/def_use.rs
src/compiler/passes/def_use.rs
+4
-4
src/compiler/passes/mod.rs
src/compiler/passes/mod.rs
+16
-16
src/compiler/passes/trace_gen.rs
src/compiler/passes/trace_gen.rs
+6
-6
src/compiler/passes/tree_gen.rs
src/compiler/passes/tree_gen.rs
+5
-5
src/lib.rs
src/lib.rs
+1
-1
src/vm/api.rs
src/vm/api.rs
+420
-0
src/vm/bundle.rs
src/vm/bundle.rs
+42
-0
src/vm/context.rs
src/vm/context.rs
+33
-19
src/vm/machine_code.rs
src/vm/machine_code.rs
+5
-5
src/vm/mod.rs
src/vm/mod.rs
+4
-2
src/vm/vm_options.rs
src/vm/vm_options.rs
+1
-1
tests/test_compiler/mod.rs
tests/test_compiler/mod.rs
+1
-1
tests/test_compiler/test_global.rs
tests/test_compiler/test_global.rs
+5
-5
tests/test_compiler/test_instsel.rs
tests/test_compiler/test_instsel.rs
+4
-4
tests/test_compiler/test_pre_instsel.rs
tests/test_compiler/test_pre_instsel.rs
+24
-24
tests/test_compiler/test_regalloc.rs
tests/test_compiler/test_regalloc.rs
+9
-9
tests/test_ir/mod.rs
tests/test_ir/mod.rs
+1
-0
tests/test_ir/test_builder_api.rs
tests/test_ir/test_builder_api.rs
+26
-0
tests/test_ir/test_ir.rs
tests/test_ir/test_ir.rs
+7
-7
No files found.
src/ast/inst.rs
View file @
76504d0b
...
...
@@ -346,7 +346,7 @@ impl ResumptionData {
#[derive(Clone,
Debug)]
pub
struct
Destination
{
pub
target
:
Mu
Tag
,
pub
target
:
Mu
Name
,
pub
args
:
Vec
<
DestArg
>
}
...
...
src/ast/ir.rs
View file @
76504d0b
...
...
@@ -12,21 +12,21 @@ use std::cell::Cell;
pub
type
WPID
=
usize
;
pub
type
MuID
=
usize
;
pub
type
Mu
Tag
=
&
'static
str
;
pub
type
Mu
Name
=
&
'static
str
;
pub
type
Address
=
usize
;
// TODO: replace this with Address(usize)
pub
type
OpIndex
=
usize
;
#[derive(Debug)]
pub
struct
MuFunction
{
pub
fn_name
:
Mu
Tag
,
pub
fn_name
:
Mu
Name
,
pub
sig
:
P
<
MuFuncSig
>
,
pub
cur_ver
:
Option
<
Mu
Tag
>
,
pub
all_vers
:
Vec
<
Mu
Tag
>
pub
cur_ver
:
Option
<
Mu
Name
>
,
pub
all_vers
:
Vec
<
Mu
Name
>
}
impl
MuFunction
{
pub
fn
new
(
fn_name
:
Mu
Tag
,
sig
:
P
<
MuFuncSig
>
)
->
MuFunction
{
pub
fn
new
(
fn_name
:
Mu
Name
,
sig
:
P
<
MuFuncSig
>
)
->
MuFunction
{
MuFunction
{
fn_name
:
fn_name
,
sig
:
sig
,
...
...
@@ -38,20 +38,20 @@ impl MuFunction {
#[derive(Debug)]
pub
struct
MuFunctionVersion
{
pub
fn_name
:
Mu
Tag
,
pub
version
:
Mu
Tag
,
pub
fn_name
:
Mu
Name
,
pub
version
:
Mu
Name
,
pub
sig
:
P
<
MuFuncSig
>
,
pub
content
:
Option
<
FunctionContent
>
,
pub
context
:
FunctionContext
,
pub
block_trace
:
Option
<
Vec
<
Mu
Tag
>>
// only available after Trace Generation Pass
pub
block_trace
:
Option
<
Vec
<
Mu
Name
>>
// only available after Trace Generation Pass
}
pub
const
RESERVED_NODE_IDS_FOR_MACHINE
:
usize
=
100
;
impl
MuFunctionVersion
{
pub
fn
new
(
fn_name
:
Mu
Tag
,
ver
:
MuTag
,
sig
:
P
<
MuFuncSig
>
)
->
MuFunctionVersion
{
pub
fn
new
(
fn_name
:
Mu
Name
,
ver
:
MuName
,
sig
:
P
<
MuFuncSig
>
)
->
MuFunctionVersion
{
MuFunctionVersion
{
fn_name
:
fn_name
,
version
:
ver
,
...
...
@@ -65,7 +65,7 @@ impl MuFunctionVersion {
self
.content
=
Some
(
content
)
}
pub
fn
new_ssa
(
&
mut
self
,
id
:
MuID
,
tag
:
Mu
Tag
,
ty
:
P
<
MuType
>
)
->
P
<
TreeNode
>
{
pub
fn
new_ssa
(
&
mut
self
,
id
:
MuID
,
tag
:
Mu
Name
,
ty
:
P
<
MuType
>
)
->
P
<
TreeNode
>
{
self
.context.value_tags
.insert
(
tag
,
id
);
self
.context.values
.insert
(
id
,
SSAVarEntry
{
id
:
id
,
tag
:
tag
,
ty
:
ty
.clone
(),
use_count
:
Cell
::
new
(
0
),
expr
:
None
});
...
...
@@ -107,8 +107,8 @@ impl MuFunctionVersion {
#[derive(Debug)]
pub
struct
FunctionContent
{
pub
entry
:
Mu
Tag
,
pub
blocks
:
HashMap
<
Mu
Tag
,
Block
>
pub
entry
:
Mu
Name
,
pub
blocks
:
HashMap
<
Mu
Name
,
Block
>
}
impl
FunctionContent
{
...
...
@@ -121,7 +121,7 @@ impl FunctionContent {
self
.get_block_mut
(
entry
)
}
pub
fn
get_block
(
&
self
,
tag
:
Mu
Tag
)
->
&
Block
{
pub
fn
get_block
(
&
self
,
tag
:
Mu
Name
)
->
&
Block
{
let
ret
=
self
.blocks
.get
(
tag
);
match
ret
{
Some
(
b
)
=>
b
,
...
...
@@ -129,7 +129,7 @@ impl FunctionContent {
}
}
pub
fn
get_block_mut
(
&
mut
self
,
tag
:
Mu
Tag
)
->
&
mut
Block
{
pub
fn
get_block_mut
(
&
mut
self
,
tag
:
Mu
Name
)
->
&
mut
Block
{
let
ret
=
self
.blocks
.get_mut
(
tag
);
match
ret
{
Some
(
b
)
=>
b
,
...
...
@@ -140,7 +140,7 @@ impl FunctionContent {
#[derive(Debug)]
pub
struct
FunctionContext
{
pub
value_tags
:
HashMap
<
Mu
Tag
,
MuID
>
,
pub
value_tags
:
HashMap
<
Mu
Name
,
MuID
>
,
pub
values
:
HashMap
<
MuID
,
SSAVarEntry
>
}
...
...
@@ -152,14 +152,14 @@ impl FunctionContext {
}
}
pub
fn
get_value_by_tag
(
&
self
,
tag
:
Mu
Tag
)
->
Option
<&
SSAVarEntry
>
{
pub
fn
get_value_by_tag
(
&
self
,
tag
:
Mu
Name
)
->
Option
<&
SSAVarEntry
>
{
match
self
.value_tags
.get
(
tag
)
{
Some
(
id
)
=>
self
.get_value
(
*
id
),
None
=>
None
}
}
pub
fn
get_value_mut_by_tag
(
&
mut
self
,
tag
:
Mu
Tag
)
->
Option
<&
mut
SSAVarEntry
>
{
pub
fn
get_value_mut_by_tag
(
&
mut
self
,
tag
:
Mu
Name
)
->
Option
<&
mut
SSAVarEntry
>
{
let
id
:
MuID
=
match
self
.value_tags
.get
(
tag
)
{
Some
(
id
)
=>
*
id
,
None
=>
return
None
...
...
@@ -179,25 +179,25 @@ impl FunctionContext {
#[derive(Debug)]
pub
struct
Block
{
pub
label
:
Mu
Tag
,
pub
label
:
Mu
Name
,
pub
content
:
Option
<
BlockContent
>
,
pub
control_flow
:
ControlFlow
}
impl
Block
{
pub
fn
new
(
label
:
Mu
Tag
)
->
Block
{
pub
fn
new
(
label
:
Mu
Name
)
->
Block
{
Block
{
label
:
label
,
content
:
None
,
control_flow
:
ControlFlow
::
default
()}
}
}
#[derive(Debug)]
pub
struct
ControlFlow
{
pub
preds
:
Vec
<
Mu
Tag
>
,
pub
preds
:
Vec
<
Mu
Name
>
,
pub
succs
:
Vec
<
BlockEdge
>
}
impl
ControlFlow
{
pub
fn
get_hottest_succ
(
&
self
)
->
Option
<
Mu
Tag
>
{
pub
fn
get_hottest_succ
(
&
self
)
->
Option
<
Mu
Name
>
{
if
self
.succs
.len
()
==
0
{
None
}
else
{
...
...
@@ -231,7 +231,7 @@ impl default::Default for ControlFlow {
#[derive(Copy,
Clone,
Debug)]
pub
struct
BlockEdge
{
pub
target
:
Mu
Tag
,
pub
target
:
Mu
Name
,
pub
kind
:
EdgeKind
,
pub
is_exception
:
bool
,
pub
probability
:
f32
...
...
@@ -414,7 +414,7 @@ pub enum TreeNode_ {
/// always use with P<Value>
#[derive(Debug,
Clone,
PartialEq)]
pub
struct
Value
{
pub
tag
:
Mu
Tag
,
pub
tag
:
Mu
Name
,
pub
ty
:
P
<
MuType
>
,
pub
v
:
Value_
}
...
...
@@ -497,7 +497,7 @@ pub enum Value_ {
#[derive(Debug,
Clone)]
pub
struct
SSAVarEntry
{
pub
id
:
MuID
,
pub
tag
:
Mu
Tag
,
pub
tag
:
Mu
Name
,
pub
ty
:
P
<
MuType
>
,
// how many times this entry is used
...
...
@@ -526,8 +526,8 @@ pub enum Constant {
Float
(
f32
),
Double
(
f64
),
IRef
(
Address
),
FuncRef
(
Mu
Tag
),
UFuncRef
(
Mu
Tag
),
FuncRef
(
Mu
Name
),
UFuncRef
(
Mu
Name
),
Vector
(
Vec
<
Constant
>
),
}
...
...
@@ -564,7 +564,7 @@ pub enum MemoryLocation {
},
Symbolic
{
base
:
Option
<
P
<
Value
>>
,
label
:
Mu
Tag
label
:
Mu
Name
}
}
...
...
@@ -587,7 +587,7 @@ impl fmt::Display for MemoryLocation {
#[derive(Debug,
Clone,
PartialEq)]
pub
struct
GlobalCell
{
pub
tag
:
Mu
Tag
,
pub
tag
:
Mu
Name
,
pub
ty
:
P
<
MuType
>
}
...
...
src/ast/types.rs
View file @
76504d0b
...
...
@@ -28,7 +28,7 @@ pub enum MuType_ {
UPtr
(
P
<
MuType
>
),
/// struct<T1 T2 ...>
Struct
(
Mu
Tag
),
Struct
(
Mu
Name
),
/// array<T length>
Array
(
P
<
MuType
>
,
usize
),
...
...
@@ -82,8 +82,8 @@ impl fmt::Display for MuType_ {
}
lazy_static!
{
/// storing a map from Mu
Tag
to StructType_
pub
static
ref
STRUCT_TAG_MAP
:
RwLock
<
HashMap
<
Mu
Tag
,
StructType_
>>
=
RwLock
::
new
(
HashMap
::
new
());
/// storing a map from Mu
Name
to StructType_
pub
static
ref
STRUCT_TAG_MAP
:
RwLock
<
HashMap
<
Mu
Name
,
StructType_
>>
=
RwLock
::
new
(
HashMap
::
new
());
}
#[derive(Clone,
PartialEq,
Eq,
Debug)]
...
...
@@ -141,13 +141,13 @@ impl MuType_ {
pub
fn
uptr
(
referent
:
P
<
MuType_
>
)
->
MuType_
{
MuType_
::
UPtr
(
referent
)
}
pub
fn
mustruct_empty
(
tag
:
Mu
Tag
)
->
MuType_
{
pub
fn
mustruct_empty
(
tag
:
Mu
Name
)
->
MuType_
{
let
struct_ty_
=
StructType_
{
tys
:
vec!
[]};
STRUCT_TAG_MAP
.write
()
.unwrap
()
.insert
(
tag
,
struct_ty_
);
MuType_
::
Struct
(
tag
)
}
pub
fn
mustruct
(
tag
:
Mu
Tag
,
list
:
Vec
<
P
<
MuType_
>>
)
->
MuType_
{
pub
fn
mustruct
(
tag
:
Mu
Name
,
list
:
Vec
<
P
<
MuType_
>>
)
->
MuType_
{
let
struct_ty_
=
StructType_
{
tys
:
list
};
// if there is an attempt to use a same tag for different struct,
...
...
src/compiler/backend/arch/arm/inst_sel.rs
View file @
76504d0b
use
ast
::
ir
::
*
;
use
ast
::
inst
::
Instruction_
::
*
;
use
vm
::
context
::
VM
Context
;
use
vm
::
context
::
VM
;
use
compiler
::
CompilerPass
;
...
...
@@ -20,7 +20,7 @@ impl CompilerPass for InstructionSelection {
}
#[allow(unused_variables)]
fn
start_function
(
&
mut
self
,
vm
_context
:
&
VMContext
,
func
:
&
mut
MuFunctionVersion
)
{
fn
start_function
(
&
mut
self
,
vm
:
&
VM
,
func
:
&
mut
MuFunctionVersion
)
{
println!
(
"{}"
,
self
.name
());
}
}
src/compiler/backend/arch/x86_64/asm_backend.rs
View file @
76504d0b
...
...
@@ -5,7 +5,7 @@ use utils::ByteSize;
use
compiler
::
backend
::
x86_64
;
use
compiler
::
backend
::
x86_64
::
CodeGenerator
;
use
vm
::
MachineCode
;
use
vm
::
VM
Context
;
use
vm
::
VM
;
use
utils
::
string_utils
;
...
...
@@ -20,7 +20,7 @@ use std::slice::Iter;
use
std
::
ops
;
struct
ASMCode
{
name
:
Mu
Tag
,
name
:
Mu
Name
,
code
:
Vec
<
ASM
>
,
reg_defines
:
HashMap
<
MuID
,
Vec
<
ASMLocation
>>
,
reg_uses
:
HashMap
<
MuID
,
Vec
<
ASMLocation
>>
,
...
...
@@ -30,17 +30,17 @@ struct ASMCode {
preds
:
Vec
<
Vec
<
usize
>>
,
succs
:
Vec
<
Vec
<
usize
>>
,
idx_to_blk
:
HashMap
<
usize
,
Mu
Tag
>
,
blk_to_idx
:
HashMap
<
Mu
Tag
,
usize
>
,
cond_branches
:
HashMap
<
usize
,
Mu
Tag
>
,
branches
:
HashMap
<
usize
,
Mu
Tag
>
,
idx_to_blk
:
HashMap
<
usize
,
Mu
Name
>
,
blk_to_idx
:
HashMap
<
Mu
Name
,
usize
>
,
cond_branches
:
HashMap
<
usize
,
Mu
Name
>
,
branches
:
HashMap
<
usize
,
Mu
Name
>
,
blocks
:
Vec
<
Mu
Tag
>
,
block_start
:
HashMap
<
Mu
Tag
,
usize
>
,
block_range
:
HashMap
<
Mu
Tag
,
ops
::
Range
<
usize
>>
,
blocks
:
Vec
<
Mu
Name
>
,
block_start
:
HashMap
<
Mu
Name
,
usize
>
,
block_range
:
HashMap
<
Mu
Name
,
ops
::
Range
<
usize
>>
,
block_livein
:
HashMap
<
Mu
Tag
,
Vec
<
MuID
>>
,
block_liveout
:
HashMap
<
Mu
Tag
,
Vec
<
MuID
>>
block_livein
:
HashMap
<
Mu
Name
,
Vec
<
MuID
>>
,
block_liveout
:
HashMap
<
Mu
Name
,
Vec
<
MuID
>>
}
impl
MachineCode
for
ASMCode
{
...
...
@@ -77,7 +77,7 @@ impl MachineCode for ASMCode {
}
fn
replace_reg
(
&
mut
self
,
from
:
MuID
,
to
:
MuID
)
{
let
to_reg_tag
:
Mu
Tag
=
backend
::
all_regs
()[
to
]
.tag
;
let
to_reg_tag
:
Mu
Name
=
backend
::
all_regs
()[
to
]
.tag
;
let
to_reg_string
=
"%"
.to_string
()
+
to_reg_tag
;
match
self
.reg_defines
.get
(
&
from
)
{
...
...
@@ -140,19 +140,19 @@ impl MachineCode for ASMCode {
self
.preds
[
i
],
self
.succs
[
i
]);
}
fn
get_ir_block_livein
(
&
self
,
block
:
Mu
Tag
)
->
Option
<&
Vec
<
MuID
>>
{
fn
get_ir_block_livein
(
&
self
,
block
:
Mu
Name
)
->
Option
<&
Vec
<
MuID
>>
{
self
.block_livein
.get
(
&
block
)
}
fn
get_ir_block_liveout
(
&
self
,
block
:
Mu
Tag
)
->
Option
<&
Vec
<
MuID
>>
{
fn
get_ir_block_liveout
(
&
self
,
block
:
Mu
Name
)
->
Option
<&
Vec
<
MuID
>>
{
self
.block_liveout
.get
(
&
block
)
}
fn
get_all_blocks
(
&
self
)
->
&
Vec
<
Mu
Tag
>
{
fn
get_all_blocks
(
&
self
)
->
&
Vec
<
Mu
Name
>
{
&
self
.blocks
}
fn
get_block_range
(
&
self
,
block
:
Mu
Tag
)
->
Option
<
ops
::
Range
<
usize
>>
{
fn
get_block_range
(
&
self
,
block
:
Mu
Name
)
->
Option
<
ops
::
Range
<
usize
>>
{
match
self
.block_range
.get
(
&
block
)
{
Some
(
r
)
=>
Some
(
r
.clone
()),
None
=>
None
...
...
@@ -505,7 +505,7 @@ impl ASMCodeGen {
}
}
fn
asm_block_label
(
&
self
,
label
:
Mu
Tag
)
->
String
{
fn
asm_block_label
(
&
self
,
label
:
Mu
Name
)
->
String
{
symbol
(
&
format!
(
"{}_{}"
,
self
.cur
()
.name
,
label
))
}
...
...
@@ -575,7 +575,7 @@ impl ASMCodeGen {
}
impl
CodeGenerator
for
ASMCodeGen
{
fn
start_code
(
&
mut
self
,
func_name
:
Mu
Tag
)
{
fn
start_code
(
&
mut
self
,
func_name
:
Mu
Name
)
{
self
.cur
=
Some
(
Box
::
new
(
ASMCode
{
name
:
func_name
,
code
:
vec!
[],
...
...
@@ -629,7 +629,7 @@ impl CodeGenerator for ASMCodeGen {
println!
(
""
);
}
fn
start_block
(
&
mut
self
,
block_name
:
Mu
Tag
)
{
fn
start_block
(
&
mut
self
,
block_name
:
Mu
Name
)
{
let
label
=
format!
(
"{}:"
,
self
.asm_block_label
(
block_name
));
self
.add_asm_block_label
(
label
,
block_name
);
self
.cur_mut
()
.blocks
.push
(
block_name
);
...
...
@@ -638,14 +638,14 @@ impl CodeGenerator for ASMCodeGen {
self
.cur_mut
()
.block_start
.insert
(
block_name
,
start
);
}
fn
end_block
(
&
mut
self
,
block_name
:
Mu
Tag
)
{
fn
end_block
(
&
mut
self
,
block_name
:
Mu
Name
)
{
let
start
:
usize
=
*
self
.cur
()
.block_start
.get
(
&
block_name
)
.unwrap
();
let
end
:
usize
=
self
.line
();
self
.cur_mut
()
.block_range
.insert
(
block_name
,
(
start
..
end
));
}
fn
set_block_livein
(
&
mut
self
,
block_name
:
Mu
Tag
,
live_in
:
&
Vec
<
P
<
Value
>>
)
{
fn
set_block_livein
(
&
mut
self
,
block_name
:
Mu
Name
,
live_in
:
&
Vec
<
P
<
Value
>>
)
{
let
cur
=
self
.cur_mut
();
let
mut
res
=
{
...
...
@@ -663,7 +663,7 @@ impl CodeGenerator for ASMCodeGen {
}
}
fn
set_block_liveout
(
&
mut
self
,
block_name
:
Mu
Tag
,
live_out
:
&
Vec
<
P
<
Value
>>
)
{
fn
set_block_liveout
(
&
mut
self
,
block_name
:
Mu
Name
,
live_out
:
&
Vec
<
P
<
Value
>>
)
{
let
cur
=
self
.cur_mut
();
let
mut
res
=
{
...
...
@@ -998,7 +998,7 @@ impl CodeGenerator for ASMCodeGen {
self
.add_asm_branch2
(
asm
,
dest
.target
);
}
fn
emit_call_near_rel32
(
&
mut
self
,
func
:
Mu
Tag
)
{
fn
emit_call_near_rel32
(
&
mut
self
,
func
:
Mu
Name
)
{
trace!
(
"emit: call {}"
,
func
);
let
asm
=
format!
(
"call {}"
,
symbol
(
func
));
...
...
@@ -1071,7 +1071,7 @@ fn create_emit_directory() {
}
}
pub
fn
emit_code
(
func
:
&
mut
MuFunctionVersion
,
vm
:
&
VM
Context
)
{
pub
fn
emit_code
(
func
:
&
mut
MuFunctionVersion
,
vm
:
&
VM
)
{
use
std
::
io
::
prelude
::
*
;
use
std
::
fs
::
File
;
use
std
::
path
;
...
...
@@ -1099,7 +1099,7 @@ pub fn emit_code(func: &mut MuFunctionVersion, vm: &VMContext) {
}
const
CONTEXT_FILE
:
&
'static
str
=
"context.s"
;
pub
fn
emit_context
(
vm
:
&
VM
Context
)
{
pub
fn
emit_context
(
vm
:
&
VM
)
{
use
std
::
path
;
use
std
::
fs
::
File
;
use
std
::
io
::
prelude
::
*
;
...
...
@@ -1150,4 +1150,4 @@ fn symbol(name: &str) -> String {
#[cfg(target_os
=
"macos"
)]
fn
symbol
(
name
:
&
str
)
->
String
{
format!
(
"_{}"
,
name
)
}
\ No newline at end of file
}
src/compiler/backend/arch/x86_64/codegen.rs
View file @
76504d0b
...
...
@@ -5,15 +5,15 @@ use ast::inst::*;
use
vm
::
MachineCode
;
pub
trait
CodeGenerator
{
fn
start_code
(
&
mut
self
,
func_name
:
Mu
Tag
);
fn
start_code
(
&
mut
self
,
func_name
:
Mu
Name
);
fn
finish_code
(
&
mut
self
)
->
Box
<
MachineCode
>
;
fn
print_cur_code
(
&
self
);
fn
start_block
(
&
mut
self
,
block_name
:
Mu
Tag
);
fn
set_block_livein
(
&
mut
self
,
block_name
:
Mu
Tag
,
live_in
:
&
Vec
<
P
<
Value
>>
);
fn
set_block_liveout
(
&
mut
self
,
block_name
:
Mu
Tag
,
live_out
:
&
Vec
<
P
<
Value
>>
);
fn
end_block
(
&
mut
self
,
block_name
:
Mu
Tag
);
fn
start_block
(
&
mut
self
,
block_name
:
Mu
Name
);
fn
set_block_livein
(
&
mut
self
,
block_name
:
Mu
Name
,
live_in
:
&
Vec
<
P
<
Value
>>
);
fn
set_block_liveout
(
&
mut
self
,
block_name
:
Mu
Name
,
live_out
:
&
Vec
<
P
<
Value
>>
);
fn
end_block
(
&
mut
self
,
block_name
:
Mu
Name
);
fn
emit_cmp_r64_r64
(
&
mut
self
,
op1
:
&
P
<
Value
>
,
op2
:
&
P
<
Value
>
);
fn
emit_cmp_r64_imm32
(
&
mut
self
,
op1
:
&
P
<
Value
>
,
op2
:
u32
);
...
...
@@ -48,7 +48,7 @@ pub trait CodeGenerator {
fn
emit_jl
(
&
mut
self
,
dest
:
&
Destination
);
fn
emit_jle
(
&
mut
self
,
dest
:
&
Destination
);
fn
emit_call_near_rel32
(
&
mut
self
,
func
:
Mu
Tag
);
fn
emit_call_near_rel32
(
&
mut
self
,
func
:
Mu
Name
);
fn
emit_call_near_r64
(
&
mut
self
,
func
:
&
P
<
Value
>
);
fn
emit_call_near_mem64
(
&
mut
self
,
func
:
&
P
<
Value
>
);
...
...
src/compiler/backend/arch/x86_64/inst_sel.rs
View file @
76504d0b
...
...
@@ -8,7 +8,7 @@ use ast::inst::MemoryOrder;
use
ast
::
op
;
use
ast
::
types
;
use
ast
::
types
::
MuType_
;
use
vm
::
VM
Context
;
use
vm
::
VM
;
use
vm
::
CompiledFunction
;
use
compiler
::
CompilerPass
;
...
...
@@ -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
Context
)
{
fn
instruction_select
(
&
mut
self
,
node
:
&
'a
P
<
TreeNode
>
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
)
{
trace!
(
"instsel on node {}"
,
node
);
match
node
.v
{
...
...
@@ -412,7 +412,7 @@ impl <'a> InstructionSelection {
}
#[allow(unused_variables)]
fn
process_dest
(
&
mut
self
,
ops
:
&
Vec
<
P
<
TreeNode
>>
,
dest
:
&
Destination
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
Context
)
{
fn
process_dest
(
&
mut
self
,
ops
:
&
Vec
<
P
<
TreeNode
>>
,
dest
:
&
Destination
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
)
{
for
i
in
0
..
dest
.args
.len
()
{
let
ref
dest_arg
=
dest
.args
[
i
];
match
dest_arg
{
...
...
@@ -489,7 +489,7 @@ impl <'a> InstructionSelection {
self
.backend
.end_block
(
block_name
);
}
fn
emit_common_epilogue
(
&
mut
self
,
ret_inst
:
&
Instruction
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
Context
)
{
fn
emit_common_epilogue
(
&
mut
self
,
ret_inst
:
&
Instruction
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
)
{
// epilogue is not a block (its a few instruction inserted before return)
// FIXME: this may change in the future
...
...
@@ -543,7 +543,7 @@ impl <'a> InstructionSelection {
}
}
fn
emit_cmp_res
(
&
mut
self
,
cond
:
&
P
<
TreeNode
>
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
Context
)
->
op
::
CmpOp
{
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
();
...
...
@@ -607,7 +607,7 @@ impl <'a> InstructionSelection {
}
}
fn
emit_ireg
(
&
mut
self
,
op
:
&
P
<
TreeNode
>
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
Context
)
->
P
<
Value
>
{
fn
emit_ireg
(
&
mut
self
,
op
:
&
P
<
TreeNode
>
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
)
->
P
<
Value
>
{
match
op
.v
{
TreeNode_
::
Instruction
(
_
)
=>
{
self
.instruction_select
(
op
,
cur_func
,
vm
);
...
...
@@ -653,7 +653,7 @@ impl <'a> InstructionSelection {
}
}
fn
emit_get_mem
(
&
mut
self
,
op
:
&
P
<
TreeNode
>
,
vm
:
&
VM
Context
)
->
P
<
Value
>
{
fn
emit_get_mem
(
&
mut
self
,
op
:
&
P
<
TreeNode
>
,
vm
:
&
VM
)
->
P
<
Value
>
{
match
op
.v
{
TreeNode_
::
Value
(
ref
pv
)
=>
{
match
pv
.v
{
...
...
@@ -704,7 +704,7 @@ impl <'a> InstructionSelection {
}
}
fn
emit_get_funcref_const
(
&
mut
self
,
op
:
&
P
<
TreeNode
>
)
->
Mu
Tag
{
fn
emit_get_funcref_const
(
&
mut
self
,
op
:
&
P
<
TreeNode
>
)
->
Mu
Name
{
match
op
.v
{
TreeNode_
::
Value
(
ref
pv
)
=>
{
match
pv
.v
{
...
...
@@ -749,7 +749,7 @@ impl <'a> InstructionSelection {
}
}
fn
emit_general_move
(
&
mut
self
,
src
:
&
P
<
TreeNode
>
,
dest
:
&
P
<
Value
>
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
Context
)
{
fn
emit_general_move
(
&
mut
self
,
src
:
&
P
<
TreeNode
>
,
dest
:
&
P
<
Value
>
,
cur_func
:
&
MuFunctionVersion
,
vm
:
&
VM
)
{
let
ref
dst_ty
=
dest
.ty
;
if
!
types
::
is_fp
(
dst_ty
)
&&
types
::
is_scalar
(
dst_ty
)
{
...
...
@@ -776,7 +776,7 @@ impl CompilerPass for InstructionSelection {
}
#[allow(unused_variables)]
fn
start_function
(
&
mut
self
,
vm
_context
:
&
VMContext
,
func
:
&
mut
MuFunctionVersion
)
{
fn
start_function
(
&
mut
self
,
vm
:
&
VM
,
func
:
&
mut
MuFunctionVersion
)
{
debug!
(
"{}"
,
self
.name
());
self
.backend
.start_code
(
func
.fn_name
);
...
...
@@ -788,7 +788,7 @@ impl CompilerPass for InstructionSelection {
}
#[allow(unused_variables)]
fn
visit_function
(
&
mut
self
,
vm
_context
:
&
VMContext
,
func
:
&
mut
MuFunctionVersion
)
{
fn
visit_function
(
&
mut
self
,
vm
:
&
VM
,
func
:
&
mut
MuFunctionVersion
)
{
for
block_label
in
func
.block_trace
.as_ref
()
.unwrap
()
{
let
block
=
func
.content
.as_ref
()
.unwrap
()
.get_block
(
block_label
);
...
...
@@ -804,7 +804,7 @@ impl CompilerPass for InstructionSelection {
self
.backend
.set_block_liveout
(
block
.label
,
&
live_out
);
for
inst
in
block_content
.body
.iter
()
{
self
.instruction_select
(
inst
,
func
,
vm
_context
);
self
.instruction_select
(
inst
,
func
,
vm
);
}
self
.backend
.end_block
(
block
.label
);
...
...
@@ -812,7 +812,7 @@ impl CompilerPass for InstructionSelection {
}
#[allow(unused_variables)]
fn
finish_function
(
&
mut
self
,
vm
_context
:
&
VMContext
,
func
:
&
mut
MuFunctionVersion
)
{
fn
finish_function
(
&
mut
self
,
vm
:
&
VM
,
func
:
&
mut
MuFunctionVersion
)
{
self
.backend
.print_cur_code
();
let
mc
=
self
.backend
.finish_code
();
...
...
@@ -822,6 +822,6 @@ impl CompilerPass for InstructionSelection {
mc
:
mc
};
vm
_context
.add_compiled_func
(
compiled_func
);
vm
.add_compiled_func
(
compiled_func
);
}
}
src/compiler/backend/code_emission.rs
View file @
76504d0b
...
...
@@ -2,7 +2,7 @@
use
compiler
::
CompilerPass
;
use
ast
::
ir
::
*
;
use
vm
::
VM
Context
;
use
vm
::
VM
;
use
compiler
::
backend
::
emit_code
;
pub
struct
CodeEmission
{
...
...
@@ -22,7 +22,7 @@ impl CompilerPass for CodeEmission {
self
.name
}
fn
visit_function
(
&
mut
self
,
vm
_context
:
&
VMContext
,
func
:
&
mut
MuFunctionVersion
)
{
emit_code
(
func
,
vm
_context
);
fn
visit_function
(
&
mut
self
,
vm
:
&
VM
,
func
:
&
mut
MuFunctionVersion
)
{
emit_code
(
func
,
vm
);
}
}
src/compiler/backend/mod.rs
View file @
76504d0b
...
...
@@ -39,10 +39,10 @@ mod arm;
// common data structure with target specific info
use
vm
::
VM
Context
;
use
vm
::
VM
;
use
ast
::
types
::
*
;
use
ast
::
ptr
::
*
;
pub
fn
resolve_backend_type_info
(
ty
:
&
MuType
,
vm
:
&
VM
Context
)
->
BackendTypeInfo
{
pub
fn
resolve_backend_type_info
(
ty
:
&
MuType
,
vm
:
&
VM
)
->
BackendTypeInfo
{
match
ty
{
// integral
&
MuType_
::
Int
(
size_in_bit
)
=>
{
...
...
@@ -106,7 +106,7 @@ pub fn resolve_backend_type_info (ty: &MuType, vm: &VMContext) -> BackendTypeInf
}
}
fn
layout_struct
(
tys
:
&
Vec
<
P
<
MuType_
>>
,
vm
:
&
VM
Context
)
->
BackendTypeInfo
{
fn
layout_struct
(
tys
:
&
Vec
<
P
<
MuType_
>>
,
vm
:
&
VM
)
->
BackendTypeInfo
{
let
mut
offsets
:
Vec
<
ByteSize
>
=
vec!
[];
let
mut
cur
:
ByteSize
=
0
;
let
mut
struct_align
:
ByteSize
=
0
;
...
...
@@ -151,4 +151,4 @@ pub struct BackendTypeInfo {
}
#[derive(Clone,
Copy,
Debug,
PartialEq,
Eq,
Hash)]
pub
enum
RegGroup
{
GPR
,
FPR
}
\ No newline at end of file
pub
enum
RegGroup
{
GPR
,
FPR
}
src/compiler/backend/peephole_opt.rs
View file @
76504d0b
use
compiler
::
CompilerPass
;
use
ast
::
ir
::
*
;
use
vm
::
VM
Context
;
use
vm
::
VM
;
use
vm
::
CompiledFunction
;
pub
struct
PeepholeOptimization
{
...
...
@@ -55,8 +55,8 @@ impl CompilerPass for PeepholeOptimization {
self
.name
}
fn
visit_function
(
&
mut
self
,
vm
_context
:
&
VMContext
,
func
:
&
mut
MuFunctionVersion
)
{
let
compiled_funcs
=
vm
_context
.compiled_funcs
()
.read
()
.unwrap
();
fn
visit_function
(
&
mut
self
,
vm
:
&
VM
,
func
:
&
mut
MuFunctionVersion
)
{
let
compiled_funcs
=
vm
.compiled_funcs
()
.read
()
.unwrap
();
let
mut
cf
=
compiled_funcs
.get
(
func
.fn_name
)
.unwrap
()
.borrow_mut
();
for
i
in
0
..
cf
.mc
.number_of_insts
()
{
...
...
src/compiler/backend/reg_alloc/mod.rs
View file @
76504d0b
...
...
@@ -4,7 +4,7 @@ use compiler::CompilerPass;
use
compiler
::
PassExecutionResult
;
use
compiler
;
use
ast
::
ir
::
*
;
use
vm
::
VM
Context
;
use
vm
::
VM
;
use
compiler
::
backend
::
init_machine_regs_for_func
;
...
...
@@ -23,8 +23,8 @@ impl RegisterAllocation {
#[allow(unused_variables)]
// returns true if we spill registers (which requires another instruction selection)
fn
coloring
(
&
mut
self
,
vm
_context
:
&
VMContext
,
func
:
&
mut
MuFunctionVersion
)
->
bool
{
let
compiled_funcs
=
vm
_context
.compiled_funcs
()
.read
()
.unwrap
();
fn
coloring
(
&
mut
self
,
vm
:
&
VM
,
func
:
&
mut
MuFunctionVersion
)
->
bool
{
let
compiled_funcs
=
vm
.compiled_funcs
()
.read
()
.unwrap
();
let
mut
cf
=
compiled_funcs
.get
(
func
.fn_name
)
.unwrap
()
.borrow_mut
();
cf
.mc
.trace_mc
();
...
...
@@ -72,10 +72,10 @@ impl CompilerPass for RegisterAllocation {
self
.name
}
fn
execute
(
&
mut
self
,
vm
_context
:
&
VMContext
,
func
:
&
mut
MuFunctionVersion
)
->
PassExecutionResult
{
fn
execute
(
&
mut
self
,
vm
:
&
VM
,
func
:
&
mut
MuFunctionVersion
)
->
PassExecutionResult
{
debug!
(
"---CompilerPass {} for {}---"
,
self
.name
(),
func
.fn_name
);
if
self
.coloring
(
vm
_context
,
func
)
{
if
self
.coloring
(
vm
,
func
)
{
debug!
(
"---finish---"
);
PassExecutionResult
::
ProceedToNext
...
...
src/compiler/mod.rs
View file @
76504d0b
extern
crate
hprof
;
use
ast
::
ir
::
*
;
use
vm
::
VM
Context
;
use
vm
::
VM
;
use
std
::
cell
::
RefCell
;
use
std
::
sync
::
Arc
;
...
...
@@ -22,11 +22,11 @@ pub use compiler::passes::PASS7_CODE_EMIT;
pub
struct
Compiler
{
policy
:
RefCell
<
CompilerPolicy
>
,
vm
:
Arc
<
VM
Context
>
vm
:
Arc
<
VM
>
}
impl
Compiler
{
pub
fn
new
(
policy
:
CompilerPolicy
,
vm
:
Arc
<
VM
Context
>
)
->
Compiler
{
pub
fn
new
(
policy
:
CompilerPolicy
,
vm
:
Arc
<
VM
>
)
->
Compiler
{
Compiler
{
policy
:
RefCell
::
new
(
policy
),
vm
:
vm
...
...
@@ -80,4 +80,4 @@ impl CompilerPolicy {
pub
fn
new
(
passes
:
Vec
<
Box
<
CompilerPass
>>
)
->
CompilerPolicy
{
CompilerPolicy
{
passes
:
passes
}
}
}
\ No newline at end of file
}
src/compiler/passes/control_flow.rs
View file @
76504d0b