Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
infosec-ecomp
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Putegnat Theo
infosec-ecomp
Commits
4e0ff71f
Commit
4e0ff71f
authored
2 years ago
by
Putegnat Theo
Browse files
Options
Downloads
Patches
Plain Diff
TP6 regalloc OK
parent
c150a11f
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/regalloc.ml
+64
-8
64 additions, 8 deletions
src/regalloc.ml
with
64 additions
and
8 deletions
src/regalloc.ml
+
64
−
8
View file @
4e0ff71f
...
...
@@ -55,7 +55,7 @@ let regalloc_on_stack_fun (f: linear_fun) : ((reg, loc) Hashtbl.t * int)=
avec le registre-clé. Cela correspond à la relation d'adjacence dans le
graphe d'interférence. *)
(* La fonction [add_
to_
interf rig x y] ajoute [y] à la liste des registres qui
(* La fonction [add_interf rig x y] ajoute [y] à la liste des registres qui
interfèrent avec [x] dans le graphe [rig].
On pourra utiliser la fonction [Hashtbl.modify_def] qui permet de modifier la
...
...
@@ -79,7 +79,22 @@ let regalloc_on_stack_fun (f: linear_fun) : ((reg, loc) Hashtbl.t * int)=
let
add_interf
(
rig
:
(
reg
,
reg
Set
.
t
)
Hashtbl
.
t
)
(
x
:
reg
)
(
y
:
reg
)
:
unit
=
(* TODO *)
()
begin
match
Hashtbl
.
find_option
rig
x
with
|
Some
xset
->
Hashtbl
.
modify_def
Set
.
empty
x
(
fun
set
->
Set
.
union
set
(
Set
.
singleton
(
y
)))
rig
;
begin
match
Hashtbl
.
find_option
rig
y
with
|
Some
yset
->
Hashtbl
.
modify_def
Set
.
empty
y
(
fun
set
->
Set
.
union
set
(
Set
.
singleton
(
x
)))
rig
|
None
->
Hashtbl
.
add
rig
y
(
Set
.
singleton
x
)
end
|
None
->
Hashtbl
.
add
rig
x
(
Set
.
singleton
y
);
begin
match
Hashtbl
.
find_option
rig
y
with
|
Some
yset
->
Hashtbl
.
modify_def
Set
.
empty
y
(
fun
set
->
Set
.
union
set
(
Set
.
singleton
(
x
)))
rig
|
None
->
Hashtbl
.
add
rig
y
(
Set
.
singleton
x
)
end
end
(* [make_interf_live rig live] ajoute des arcs dans le graphe d'interférence
...
...
@@ -89,7 +104,12 @@ let make_interf_live
(
rig
:
(
reg
,
reg
Set
.
t
)
Hashtbl
.
t
)
(
live
:
(
int
,
reg
Set
.
t
)
Hashtbl
.
t
)
:
unit
=
(* TODO *)
()
Hashtbl
.
iter
(
fun
node
set_of_regliving
->
Set
.
iter
(
fun
reg1
->
Set
.
iter
(
fun
reg2
->
add_interf
rig
reg1
reg2
)
(
Set
.
diff
set_of_regliving
(
Set
.
singleton
reg1
))
)
set_of_regliving
)
live
(* [build_interference_graph live_out] construit, en utilisant les fonctions que
vous avez écrites, le graphe d'interférence en fonction de la vivacité des
...
...
@@ -121,7 +141,8 @@ let build_interference_graph (live_out : (int, reg Set.t) Hashtbl.t) code : (reg
[rig]. *)
let
remove_from_rig
(
rig
:
(
reg
,
reg
Set
.
t
)
Hashtbl
.
t
)
(
v
:
reg
)
:
unit
=
(* TODO *)
()
Hashtbl
.
remove
rig
v
;
Hashtbl
.
iter
(
fun
key
keyset
->
Hashtbl
.
replace
rig
key
(
Set
.
remove
v
keyset
))
rig
;
(* Type représentant les différentes décisions qui peuvent être prises par
...
...
@@ -160,7 +181,10 @@ type regalloc_decision =
ne satisfait cette condition. *)
let
pick_node_with_fewer_than_n_neighbors
(
rig
:
(
reg
,
reg
Set
.
t
)
Hashtbl
.
t
)
(
n
:
int
)
:
reg
option
=
(* TODO *)
None
Hashtbl
.
fold
(
fun
k
d
acc
->
if
(
Set
.
cardinal
d
)
<
n
then
Some
k
else
acc
)
rig
None
(* Lorsque la fonction précédente échoue (i.e. aucun sommet n'a moins de [n]
voisins), on choisit un pseudo-registre à évincer.
...
...
@@ -172,14 +196,27 @@ let pick_node_with_fewer_than_n_neighbors (rig : (reg, reg Set.t) Hashtbl.t) (n:
plus de voisins dans [rig], ou [None] si [rig] est vide. *)
let
pick_spilling_candidate
(
rig
:
(
reg
,
reg
Set
.
t
)
Hashtbl
.
t
)
:
reg
option
=
(* TODO *)
None
Hashtbl
.
to_list
rig
|>
List
.
map
(
fun
(
reg
,
regset
)
->
(
reg
,
Set
.
cardinal
regset
))
|>
List
.
sort
(
fun
(
reg1
,
card1
)
(
reg2
,
card2
)
->
card2
-
card1
)
|>
fun
list_sorted
->
List
.
nth_opt
list_sorted
0
|>
Option
.
map
fst
(* [make_stack rig stack ncolors] construit la pile, selon l'algorithme vu en
cours (slides 60 à 63 du cours "Allocation de registres - Autres slides"
présent sur Edunao.) *)
let
rec
make_stack
(
rig
:
(
reg
,
reg
Set
.
t
)
Hashtbl
.
t
)
(
stack
:
regalloc_decision
list
)
(
ncolors
:
int
)
:
regalloc_decision
list
=
(* TODO *)
stack
begin
match
pick_node_with_fewer_than_n_neighbors
rig
ncolors
with
|
Some
node
->
remove_from_rig
rig
node
;
make_stack
rig
(
NoSpill
node
::
stack
)
ncolors
|
None
->
(
match
pick_spilling_candidate
rig
with
|
Some
node_to_spill
->
remove_from_rig
rig
node_to_spill
;
make_stack
rig
(
Spill
node_to_spill
::
stack
)
ncolors
|
None
->
stack
)
end
(* Maintenant que nous avons une pile de [regalloc_decision], il est temps de
colorer notre graphe, i.e. associer une couleur (un numéro de registre
...
...
@@ -219,7 +256,26 @@ let allocate (allocation: (reg, loc) Hashtbl.t) (rig: (reg, reg Set.t) Hashtbl.t
(
next_stack_slot
:
int
)
(
decision
:
regalloc_decision
)
:
int
=
(* TODO *)
next_stack_slot
match
decision
with
|
Spill
r
->
Hashtbl
.
add
allocation
r
(
Stk
(
next_stack_slot
))
;
next_stack_slot
-
1
|
NoSpill
r
->
let
set__of__neightbours
=
match
Hashtbl
.
find_option
rig
r
with
|
Some
a
->
a
|
None
->
Set
.
empty
in
let
colours_used
=
Set
.
fold
(
fun
neightbour
acc
->
match
Hashtbl
.
find_option
allocation
neightbour
with
|
Some
i
->
begin
match
i
with
|
Reg
colour
->
Set
.
union
acc
(
Set
.
singleton
colour
)
|
Stk
shift
->
acc
end
|
None
->
acc
)
set__of__neightbours
Set
.
empty
in
let
colours_usable
=
Set
.
diff
all_colors
colours_used
in
Hashtbl
.
add
allocation
r
(
Reg
(
Set
.
choose
colours_usable
))
;
next_stack_slot
(* [regalloc_fun f live_out all_colors] effectue l'allocation de registres pour
la fonction [f].
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment