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
e91f7785
Commit
e91f7785
authored
Jun 22, 2016
by
qinsoon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[wip] debugging. Some coloring choices are still wrong
parent
def9deb3
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
102 additions
and
34 deletions
+102
-34
src/compiler/backend/arch/x86_64/asm_backend.rs
src/compiler/backend/arch/x86_64/asm_backend.rs
+44
-24
src/compiler/backend/reg_alloc/coloring.rs
src/compiler/backend/reg_alloc/coloring.rs
+6
-8
src/compiler/backend/reg_alloc/liveness.rs
src/compiler/backend/reg_alloc/liveness.rs
+8
-0
src/compiler/backend/reg_alloc/mod.rs
src/compiler/backend/reg_alloc/mod.rs
+25
-2
src/utils/mod.rs
src/utils/mod.rs
+17
-0
src/vm/machine_code.rs
src/vm/machine_code.rs
+2
-0
No files found.
src/compiler/backend/arch/x86_64/asm_backend.rs
View file @
e91f7785
#![allow(unused_variables)]
use
compiler
::
backend
;
use
compiler
::
backend
::
x86_64
;
use
compiler
::
backend
::
x86_64
::
CodeGenerator
;
use
vm
::
machine_code
::
MachineCode
;
use
utils
::
string_utils
;
use
ast
::
ptr
::
P
;
use
ast
::
ir
::
*
;
use
ast
::
inst
::
*
;
...
...
@@ -56,6 +59,35 @@ impl MachineCode for ASMCode {
&
self
.code
[
index
]
.defines
}
fn
replace_reg
(
&
mut
self
,
from
:
MuID
,
to
:
MuID
)
{
let
to_reg_tag
:
MuTag
=
backend
::
all_regs
()[
to
]
.tag
;
let
to_reg_string
=
"%"
.to_string
()
+
to_reg_tag
;
match
self
.reg_defines
.get
(
&
from
)
{
Some
(
defines
)
=>
{
for
loc
in
defines
{
let
ref
mut
inst_to_patch
=
self
.code
[
loc
.line
];
for
i
in
0
..
loc
.len
{
string_utils
::
replace
(
&
mut
inst_to_patch
.code
,
loc
.index
,
&
to_reg_string
,
to_reg_string
.len
());
}
}
},
None
=>
{}
}
match
self
.reg_uses
.get
(
&
from
)
{
Some
(
uses
)
=>
{
for
loc
in
uses
{
let
ref
mut
inst_to_patch
=
self
.code
[
loc
.line
];
for
i
in
0
..
loc
.len
{
string_utils
::
replace
(
&
mut
inst_to_patch
.code
,
loc
.index
,
&
to_reg_string
,
to_reg_string
.len
());
}
}
},
None
=>
{}
}
}
fn
print
(
&
self
)
{
println!
(
""
);
...
...
@@ -142,7 +174,7 @@ pub struct ASMCodeGen {
cur
:
Option
<
Box
<
ASMCode
>>
}
const
REG_PLACEHOLDER_LEN
:
usize
=
3
;
const
REG_PLACEHOLDER_LEN
:
usize
=
5
;
lazy_static!
{
pub
static
ref
REG_PLACEHOLDER
:
String
=
{
let
blank_spaces
=
[
' '
as
u8
;
REG_PLACEHOLDER_LEN
];
...
...
@@ -170,18 +202,6 @@ impl ASMCodeGen {
self
.cur
()
.code
.len
()
}
fn
replace
(
s
:
&
mut
String
,
index
:
usize
,
replace
:
&
str
,
replace_len
:
usize
)
{
let
vec
=
unsafe
{
s
.as_mut_vec
()};
for
i
in
0
..
replace_len
{
if
i
<
replace
.len
()
{
vec
[
index
+
i
]
=
replace
.as_bytes
()[
i
]
as
u8
;
}
else
{
vec
[
index
+
i
]
=
' '
as
u8
;
}
}
}
fn
add_asm_block_label
(
&
mut
self
,
code
:
String
,
block_name
:
&
'static
str
)
{
let
l
=
self
.line
();
self
.cur_mut
()
.code
.push
(
ASM
::
symbolic
(
code
));
...
...
@@ -489,10 +509,10 @@ impl CodeGenerator for ASMCodeGen {
fn
emit_mov_r64_r64
(
&
mut
self
,
dest
:
&
P
<
Value
>
,
src
:
&
P
<
Value
>
)
{
trace!
(
"emit: mov {} -> {}"
,
src
,
dest
);
let
(
reg1
,
id1
,
loc1
)
=
self
.prepare_op
(
dest
,
4
+
1
);
let
(
reg2
,
id2
,
loc2
)
=
self
.prepare_op
(
src
,
4
+
1
+
reg1
.len
()
+
1
);
let
(
reg1
,
id1
,
loc1
)
=
self
.prepare_op
(
src
,
4
+
1
);
let
(
reg2
,
id2
,
loc2
)
=
self
.prepare_op
(
dest
,
4
+
1
+
reg1
.len
()
+
1
);
let
asm
=
format!
(
"movq {} {}"
,
reg
2
,
reg1
);
let
asm
=
format!
(
"movq {} {}"
,
reg
1
,
reg2
);
self
.add_asm_inst
(
asm
,
...
...
@@ -506,10 +526,10 @@ impl CodeGenerator for ASMCodeGen {
fn
emit_add_r64_r64
(
&
mut
self
,
dest
:
&
P
<
Value
>
,
src
:
&
P
<
Value
>
)
{
trace!
(
"emit: add {}, {} -> {}"
,
dest
,
src
,
dest
);
let
(
reg1
,
id1
,
loc1
)
=
self
.prepare_op
(
dest
,
4
+
1
);
let
(
reg2
,
id2
,
loc2
)
=
self
.prepare_op
(
src
,
4
+
1
+
reg1
.len
()
+
1
);
let
(
reg1
,
id1
,
loc1
)
=
self
.prepare_op
(
src
,
4
+
1
);
let
(
reg2
,
id2
,
loc2
)
=
self
.prepare_op
(
dest
,
4
+
1
+
reg1
.len
()
+
1
);
let
asm
=
format!
(
"addq {} {}"
,
reg
2
,
reg1
);
let
asm
=
format!
(
"addq {} {}"
,
reg
1
,
reg2
);
self
.add_asm_inst
(
asm
,
...
...
@@ -544,10 +564,10 @@ impl CodeGenerator for ASMCodeGen {
fn
emit_sub_r64_r64
(
&
mut
self
,
dest
:
&
P
<
Value
>
,
src
:
&
P
<
Value
>
)
{
trace!
(
"emit: sub {}, {} -> {}"
,
dest
,
src
,
dest
);
let
(
reg1
,
id1
,
loc1
)
=
self
.prepare_op
(
dest
,
4
+
1
);
let
(
reg2
,
id2
,
loc2
)
=
self
.prepare_op
(
src
,
4
+
1
+
reg1
.len
()
+
1
);
let
(
reg1
,
id1
,
loc1
)
=
self
.prepare_op
(
src
,
4
+
1
);
let
(
reg2
,
id2
,
loc2
)
=
self
.prepare_op
(
dest
,
4
+
1
+
reg1
.len
()
+
1
);
let
asm
=
format!
(
"subq {} {}"
,
reg
2
,
reg1
);
let
asm
=
format!
(
"subq {} {}"
,
reg
1
,
reg2
);
self
.add_asm_inst
(
asm
,
...
...
@@ -566,9 +586,9 @@ impl CodeGenerator for ASMCodeGen {
fn
emit_sub_r64_imm32
(
&
mut
self
,
dest
:
&
P
<
Value
>
,
src
:
u32
)
{
trace!
(
"emit: sub {}, {} -> {}"
,
dest
,
src
,
dest
);
let
(
reg1
,
id1
,
loc1
)
=
self
.prepare_op
(
dest
,
4
+
1
);
let
(
reg1
,
id1
,
loc1
)
=
self
.prepare_op
(
dest
,
4
+
1
+
1
+
src
.to_string
()
.len
()
+
1
);
let
asm
=
format!
(
"subq
{} $
{}"
,
src
,
reg1
);
let
asm
=
format!
(
"subq
${}
{}"
,
src
,
reg1
);
self
.add_asm_inst
(
asm
,
...
...
src/compiler/backend/reg_alloc/coloring.rs
View file @
e91f7785
...
...
@@ -13,13 +13,12 @@ use std::collections::HashMap;
const
COALESCING
:
bool
=
true
;
pub
struct
GraphColoring
<
'a
>
{
ig
:
InterferenceGraph
,
cur_cf
:
&
'a
CompiledFunction
,
pub
struct
GraphColoring
{
pub
ig
:
InterferenceGraph
,
precolored
:
HashSet
<
Node
>
,
colors
:
HashMap
<
backend
::
RegGroup
,
HashSet
<
MuID
>>
,
colored_nodes
:
Vec
<
Node
>
,
pub
colored_nodes
:
Vec
<
Node
>
,
initial
:
Vec
<
Node
>
,
degree
:
HashMap
<
Node
,
isize
>
,
...
...
@@ -43,11 +42,10 @@ pub struct GraphColoring <'a> {
select_stack
:
Vec
<
Node
>
}
impl
<
'a
>
GraphColoring
<
'a
>
{
pub
fn
start
(
cf
:
&
CompiledFunction
,
ig
:
InterferenceGraph
)
->
GraphColoring
{
impl
GraphColoring
{
pub
fn
start
(
ig
:
InterferenceGraph
)
->
GraphColoring
{
let
mut
coloring
=
GraphColoring
{
ig
:
ig
,
cur_cf
:
cf
,
precolored
:
HashSet
::
new
(),
colors
:
{
...
...
@@ -359,7 +357,7 @@ impl <'a> GraphColoring <'a> {
}
}
fn
get_alias
(
&
self
,
node
:
Node
)
->
Node
{
pub
fn
get_alias
(
&
self
,
node
:
Node
)
->
Node
{
if
self
.coalesced_nodes
.contains
(
&
node
)
{
self
.get_alias
(
*
self
.alias
.get
(
&
node
)
.unwrap
())
}
else
{
...
...
src/compiler/backend/reg_alloc/liveness.rs
View file @
e91f7785
...
...
@@ -92,6 +92,14 @@ impl InterferenceGraph {
}
}
pub
fn
temps
(
&
self
)
->
Vec
<
MuID
>
{
let
mut
ret
=
vec!
[];
for
reg
in
self
.nodes
.keys
()
{
ret
.push
(
*
reg
);
}
ret
}
pub
fn
nodes
(
&
self
)
->
Vec
<
Node
>
{
let
mut
ret
=
vec!
[];
for
node
in
self
.nodes
.values
()
{
...
...
src/compiler/backend/reg_alloc/mod.rs
View file @
e91f7785
...
...
@@ -28,7 +28,7 @@ impl CompilerPass for RegisterAllocation {
#[allow(unused_variables)]
fn
visit_function
(
&
mut
self
,
vm_context
:
&
VMContext
,
func
:
&
mut
MuFunction
)
{
let
mut
compiled_funcs
=
vm_context
.compiled_funcs
()
.read
()
.unwrap
();
let
compiled_funcs
=
vm_context
.compiled_funcs
()
.read
()
.unwrap
();
let
mut
cf
=
compiled_funcs
.get
(
func
.fn_name
)
.unwrap
()
.borrow_mut
();
cf
.mc
.print
();
...
...
@@ -39,7 +39,30 @@ impl CompilerPass for RegisterAllocation {
let
liveness
=
liveness
::
build
(
&
mut
cf
,
func
);
liveness
.print
();
let
coloring
=
coloring
::
GraphColoring
::
start
(
&
mut
cf
,
liveness
);
let
coloring
=
coloring
::
GraphColoring
::
start
(
liveness
);
let
spills
=
coloring
.spills
();
if
!
spills
.is_empty
()
{
unimplemented!
();
}
// replace regs
trace!
(
"Replacing Registers..."
);
for
node
in
coloring
.ig
.nodes
()
{
let
temp
=
coloring
.ig
.get_temp_of
(
node
);
// skip machine registers
if
temp
<
RESERVED_NODE_IDS_FOR_MACHINE
{
continue
;
}
else
{
let
alias
=
coloring
.get_alias
(
node
);
let
machine_reg
=
coloring
.ig
.get_color_of
(
alias
)
.unwrap
();
trace!
(
"replacing {} with {}"
,
temp
,
machine_reg
);
cf
.mc
.replace_reg
(
temp
,
machine_reg
);
}
}
cf
.mc
.print
();
}
}
\ No newline at end of file
src/utils/mod.rs
View file @
e91f7785
#![allow(dead_code)]
// This porvides some missing operations on Vec.
// They are not included in the standard libarary.
// (because they are likely inefficient?)
...
...
@@ -45,4 +47,19 @@ pub mod hashset_utils {
set
.take
(
&
next
)
}
}
}
pub
mod
string_utils
{
pub
fn
replace
(
s
:
&
mut
String
,
index
:
usize
,
replace
:
&
String
,
replace_len
:
usize
)
{
let
vec
=
unsafe
{
s
.as_mut_vec
()};
let
vec_replace
=
replace
.as_bytes
();
for
i
in
0
..
replace_len
{
if
i
<
replace
.len
()
{
vec
[
index
+
i
]
=
vec_replace
[
i
]
as
u8
;
}
else
{
vec
[
index
+
i
]
=
' '
as
u8
;
}
}
}
}
\ No newline at end of file
src/vm/machine_code.rs
View file @
e91f7785
...
...
@@ -16,4 +16,6 @@ pub trait MachineCode {
fn
get_inst_reg_uses
(
&
self
,
index
:
usize
)
->
&
Vec
<
MuID
>
;
fn
get_inst_reg_defines
(
&
self
,
index
:
usize
)
->
&
Vec
<
MuID
>
;
fn
replace_reg
(
&
mut
self
,
from
:
MuID
,
to
:
MuID
);
}
\ 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