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
c6054d60
Commit
c6054d60
authored
Jun 21, 2016
by
qinsoon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[wip] all code for reg alloc is done. Start debugging
parent
70efc1ec
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
149 additions
and
16 deletions
+149
-16
src/compiler/backend/arch/x86_64/mod.rs
src/compiler/backend/arch/x86_64/mod.rs
+8
-0
src/compiler/backend/mod.rs
src/compiler/backend/mod.rs
+2
-0
src/compiler/backend/reg_alloc/coloring.rs
src/compiler/backend/reg_alloc/coloring.rs
+93
-6
src/compiler/backend/reg_alloc/liveness.rs
src/compiler/backend/reg_alloc/liveness.rs
+30
-9
src/compiler/backend/reg_alloc/mod.rs
src/compiler/backend/reg_alloc/mod.rs
+2
-1
src/utils/mod.rs
src/utils/mod.rs
+14
-0
No files found.
src/compiler/backend/arch/x86_64/mod.rs
View file @
c6054d60
...
...
@@ -228,6 +228,14 @@ pub fn all_regs() -> &'static Vec<P<Value>> {
&
ALL_MACHINE_REGs
}
pub
fn
pick_group_for_reg
(
reg_id
:
MuID
)
->
RegGroup
{
match
reg_id
{
0
...
15
=>
RegGroup
::
GPR
,
16
...
31
=>
RegGroup
::
FPR
,
_
=>
panic!
(
"expected a machine reg ID, got {}"
,
reg_id
)
}
}
pub
fn
is_valid_x86_imm
(
op
:
&
P
<
Value
>
)
->
bool
{
use
std
::
u32
;
match
op
.v
{
...
...
src/compiler/backend/mod.rs
View file @
c6054d60
...
...
@@ -17,6 +17,8 @@ pub use compiler::backend::x86_64::number_of_regs_in_group;
pub
use
compiler
::
backend
::
x86_64
::
number_of_all_regs
;
#[cfg(target_arch
=
"x86_64"
)]
pub
use
compiler
::
backend
::
x86_64
::
all_regs
;
#[cfg(target_arch
=
"x86_64"
)]
pub
use
compiler
::
backend
::
x86_64
::
pick_group_for_reg
;
#[cfg(target_arch
=
"arm"
)]
#[path
=
"arch/arm/mod.rs"
]
...
...
src/compiler/backend/reg_alloc/coloring.rs
View file @
c6054d60
...
...
@@ -5,6 +5,7 @@ use vm::machine_code::CompiledFunction;
use
compiler
::
backend
;
use
utils
::
vec_utils
;
use
utils
::
hashset_utils
;
use
std
::
cell
::
RefCell
;
use
std
::
collections
::
HashSet
;
...
...
@@ -18,7 +19,8 @@ pub struct GraphColoring <'a> {
cur_cf
:
&
'a
CompiledFunction
,
precolored
:
HashSet
<
Node
>
,
colors
:
HashSet
<
MuID
>
,
colors
:
HashMap
<
backend
::
RegGroup
,
HashSet
<
MuID
>>
,
colored_nodes
:
Vec
<
Node
>
,
initial
:
Vec
<
Node
>
,
degree
:
HashMap
<
Node
,
usize
>
,
...
...
@@ -31,6 +33,9 @@ pub struct GraphColoring <'a> {
alias
:
HashMap
<
Node
,
Node
>
,
worklist_spill
:
Vec
<
Node
>
,
spillable
:
HashMap
<
MuID
,
bool
>
,
spilled_nodes
:
Vec
<
Node
>
,
worklist_freeze
:
HashSet
<
Node
>
,
frozen_moves
:
HashSet
<
Move
>
,
...
...
@@ -39,13 +44,19 @@ pub struct GraphColoring <'a> {
}
impl
<
'a
>
GraphColoring
<
'a
>
{
pub
fn
start
(
cf
:
&
CompiledFunction
,
ig
:
InterferenceGraph
)
{
pub
fn
start
(
cf
:
&
CompiledFunction
,
ig
:
InterferenceGraph
)
->
GraphColoring
{
let
mut
coloring
=
GraphColoring
{
ig
:
ig
,
cur_cf
:
cf
,
precolored
:
HashSet
::
new
(),
colors
:
HashSet
::
new
(),
colors
:
{
let
mut
map
=
HashMap
::
new
();
map
.insert
(
backend
::
RegGroup
::
GPR
,
HashSet
::
new
());
map
.insert
(
backend
::
RegGroup
::
FPR
,
HashSet
::
new
());
map
},
colored_nodes
:
Vec
::
new
(),
initial
:
Vec
::
new
(),
degree
:
HashMap
::
new
(),
...
...
@@ -58,6 +69,9 @@ impl <'a> GraphColoring <'a> {
alias
:
HashMap
::
new
(),
worklist_spill
:
Vec
::
new
(),
spillable
:
HashMap
::
new
(),
spilled_nodes
:
Vec
::
new
(),
worklist_freeze
:
HashSet
::
new
(),
frozen_moves
:
HashSet
::
new
(),
...
...
@@ -66,6 +80,8 @@ impl <'a> GraphColoring <'a> {
};
coloring
.init
();
coloring
}
fn
init
(
&
mut
self
)
{
...
...
@@ -76,7 +92,10 @@ impl <'a> GraphColoring <'a> {
let
node
=
self
.ig
.get_node
(
reg_id
);
self
.precolored
.insert
(
node
);
self
.colors
.insert
(
reg_id
);
{
let
group
=
backend
::
pick_group_for_reg
(
reg_id
);
self
.colors
.get_mut
(
&
group
)
.unwrap
()
.insert
(
reg_id
);
}
}
for
node
in
self
.ig
.nodes
()
{
...
...
@@ -443,10 +462,78 @@ impl <'a> GraphColoring <'a> {
}
fn
select_spill
(
&
mut
self
)
{
unimplemented!
()
let
mut
m
:
Option
<
Node
>
=
None
;
for
n
in
self
.worklist_spill
.iter
()
{
let
n
=
*
n
;
if
m
.is_none
()
{
m
=
Some
(
n
);
}
else
if
{
// m is not none
let
temp
=
self
.ig
.get_temp_of
(
m
.unwrap
());
let
spillable
=
{
match
self
.spillable
.get
(
&
temp
)
{
None
=>
{
//by default, its spillable
true
},
Some
(
b
)
=>
*
b
}};
!
spillable
}
{
m
=
Some
(
n
);
}
else
if
(
self
.ig
.get_spill_cost
(
n
)
/
(
self
.degree
(
n
)
as
f32
))
<
(
self
.ig
.get_spill_cost
(
m
.unwrap
())
/
(
self
.degree
(
m
.unwrap
())
as
f32
))
{
m
=
Some
(
n
);
}
}
// m is not none
let
m
=
m
.unwrap
();
vec_utils
::
remove_value
(
&
mut
self
.worklist_spill
,
m
);
self
.worklist_simplify
.insert
(
m
);
self
.freeze_moves
(
m
);
}
fn
assign_colors
(
&
mut
self
)
{
unimplemented!
()
while
!
self
.select_stack
.is_empty
()
{
let
n
=
self
.select_stack
.pop
()
.unwrap
();
let
mut
ok_colors
=
self
.colors
.get
(
&
self
.ig
.get_group_of
(
n
))
.unwrap
()
.clone
();
for
w
in
self
.ig
.outedges_of
(
n
)
{
let
w
=
self
.get_alias
(
w
);
match
self
.ig
.get_color_of
(
w
)
{
None
=>
{},
// do nothing
Some
(
color
)
=>
{
ok_colors
.remove
(
&
color
);}
}
}
if
ok_colors
.is_empty
()
{
self
.spilled_nodes
.push
(
n
);
}
else
{
self
.colored_nodes
.push
(
n
);
self
.ig
.color_node
(
n
,
hashset_utils
::
pop_first
(
&
mut
ok_colors
)
.unwrap
());
}
}
for
n
in
self
.coalesced_nodes
.iter
()
{
let
n
=
*
n
;
let
alias
=
self
.get_alias
(
n
);
let
alias_color
=
self
.ig
.get_color_of
(
alias
)
.unwrap
();
self
.ig
.color_node
(
n
,
alias_color
);
}
}
pub
fn
spills
(
&
self
)
->
Vec
<
MuID
>
{
let
mut
spills
=
vec!
[];
let
spill_count
=
self
.spilled_nodes
.len
();
if
spill_count
>
0
{
for
n
in
self
.spilled_nodes
.iter
()
{
spills
.push
(
self
.ig
.get_temp_of
(
*
n
));
}
}
spills
}
}
\ No newline at end of file
src/compiler/backend/reg_alloc/liveness.rs
View file @
c6054d60
...
...
@@ -14,10 +14,12 @@ use self::nalgebra::DMatrix;
#[derive(Clone,
Copy,
Debug,
PartialEq,
Eq,
Hash)]
pub
struct
Node
(
usize
);
#[derive(Clone,
Debug,
PartialEq
,
Eq,
Hash
)]
#[derive(Clone,
Debug,
PartialEq)]
pub
struct
NodeProperty
{
color
:
Option
<
MuID
>
,
group
:
backend
::
RegGroup
group
:
backend
::
RegGroup
,
temp
:
MuID
,
spill_cost
:
f32
}
#[derive(Clone,
Copy,
Debug,
PartialEq,
Eq,
Hash)]
pub
struct
Move
{
pub
from
:
Node
,
pub
to
:
Node
}
...
...
@@ -66,14 +68,21 @@ impl InterferenceGraph {
};
let
property
=
NodeProperty
{
color
:
None
,
group
:
group
group
:
group
,
temp
:
reg_id
,
spill_cost
:
0.0f32
};
self
.nodes_property
.insert
(
node
,
property
);
node
}
else
{
*
self
.nodes
.get
(
&
reg_id
)
.unwrap
()
}
}
let
node
=
*
self
.nodes
.get
(
&
reg_id
)
.unwrap
();
// increase node spill cost
let
property
=
self
.nodes_property
.get_mut
(
&
node
)
.unwrap
();
property
.spill_cost
+=
1.0f32
;
node
}
pub
fn
get_node
(
&
self
,
reg
:
MuID
)
->
Node
{
...
...
@@ -117,7 +126,7 @@ impl InterferenceGraph {
}
}
fn
color_node
(
&
mut
self
,
node
:
Node
,
color
:
MuID
)
{
pub
fn
color_node
(
&
mut
self
,
node
:
Node
,
color
:
MuID
)
{
self
.nodes_property
.get_mut
(
&
node
)
.unwrap
()
.color
=
Some
(
color
);
}
...
...
@@ -125,10 +134,22 @@ impl InterferenceGraph {
self
.nodes_property
.get
(
&
node
)
.unwrap
()
.color
.is_some
()
}
pub
fn
get_color_of
(
&
self
,
node
:
Node
)
->
Option
<
MuID
>
{
self
.nodes_property
.get
(
&
node
)
.unwrap
()
.color
}
pub
fn
get_group_of
(
&
self
,
node
:
Node
)
->
backend
::
RegGroup
{
self
.nodes_property
.get
(
&
node
)
.unwrap
()
.group
}
pub
fn
get_temp_of
(
&
self
,
node
:
Node
)
->
MuID
{
self
.nodes_property
.get
(
&
node
)
.unwrap
()
.temp
}
pub
fn
get_spill_cost
(
&
self
,
node
:
Node
)
->
f32
{
self
.nodes_property
.get
(
&
node
)
.unwrap
()
.spill_cost
}
fn
is_same_node
(
&
self
,
node1
:
Node
,
node2
:
Node
)
->
bool
{
node1
==
node2
}
...
...
src/compiler/backend/reg_alloc/mod.rs
View file @
c6054d60
...
...
@@ -39,6 +39,7 @@ impl CompilerPass for RegisterAllocation {
let
liveness
=
liveness
::
build
(
&
mut
cf
,
func
);
liveness
.print
();
coloring
::
GraphColoring
::
start
(
&
mut
cf
,
liveness
);
let
coloring
=
coloring
::
GraphColoring
::
start
(
&
mut
cf
,
liveness
);
let
spills
=
coloring
.spills
();
}
}
\ No newline at end of file
src/utils/mod.rs
View file @
c6054d60
...
...
@@ -31,4 +31,18 @@ pub mod vec_utils {
None
=>
{}
// do nothing
}
}
}
pub
mod
hashset_utils
{
use
std
::
collections
::
HashSet
;
use
std
::
hash
::
Hash
;
pub
fn
pop_first
<
T
:
Eq
+
Hash
+
Copy
>
(
set
:
&
mut
HashSet
<
T
>
)
->
Option
<
T
>
{
if
set
.is_empty
()
{
None
}
else
{
let
next
:
T
=
set
.iter
()
.next
()
.unwrap
()
.clone
();
set
.take
(
&
next
)
}
}
}
\ 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