Skip to content

Commit 2933994

Browse files
authored
Random heuristics for testing greedy regalloc (oxcaml#2276)
1 parent 769f9fb commit 2933994

File tree

3 files changed

+61
-16
lines changed

3 files changed

+61
-16
lines changed

backend/regalloc/regalloc_gi.ml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ let priority_heuristics : Reg.t -> Interval.t -> int =
6868
fun _reg itv ->
6969
match Lazy.force Priority_heuristics.value with
7070
| Priority_heuristics.Interval_length -> Interval.length itv
71+
| Priority_heuristics.Random_for_testing -> Priority_heuristics.random ()
7172

7273
let make_hardware_registers_and_prio_queue (cfg_with_infos : Cfg_with_infos.t) :
7374
Hardware_registers.t * prio_queue =
@@ -111,8 +112,8 @@ let max_rounds = 32
111112
(* CR xclerc for xclerc: the `round` parameter is temporary; this is an hybrid
112113
version of "greedy" using the `rewrite` function from IRC when it needs to
113114
spill. *)
114-
let rec main : round:int -> State.t -> Cfg_with_infos.t -> unit =
115-
fun ~round state cfg_with_infos ->
115+
let rec main : round:int -> flat:bool -> State.t -> Cfg_with_infos.t -> unit =
116+
fun ~round ~flat state cfg_with_infos ->
116117
if round > max_rounds
117118
then
118119
fatal "register allocation was not succesful after %d rounds (%s)"
@@ -122,11 +123,6 @@ let rec main : round:int -> State.t -> Cfg_with_infos.t -> unit =
122123
log ~indent:0 "main, round #%d" round;
123124
log_cfg_with_infos ~indent:0 cfg_with_infos);
124125
if gi_debug then log ~indent:0 "updating spilling costs";
125-
let flat =
126-
match Lazy.force Spilling_heuristics.value with
127-
| Flat_uses -> true
128-
| Hierarchical_uses -> false
129-
in
130126
update_spill_cost cfg_with_infos ~flat ();
131127
State.iter_introduced_temporaries state ~f:(fun (reg : Reg.t) ->
132128
reg.Reg.spill_cost <- reg.Reg.spill_cost + 10_000);
@@ -232,7 +228,7 @@ let rec main : round:int -> State.t -> Cfg_with_infos.t -> unit =
232228
~spilled_nodes:(List.map spilled_nodes ~f:fst)
233229
with
234230
| false -> if gi_debug then log ~indent:1 "(end of main)"
235-
| true -> main ~round:(succ round) state cfg_with_infos)
231+
| true -> main ~round:(succ round) ~flat state cfg_with_infos)
236232

237233
let run : Cfg_with_infos.t -> Cfg_with_infos.t =
238234
fun cfg_with_infos ->
@@ -261,7 +257,13 @@ let run : Cfg_with_infos.t -> Cfg_with_infos.t =
261257
work list and set the field to unknown. *)
262258
let (_ : bool) = rewrite state cfg_with_infos ~spilled_nodes in
263259
Cfg_with_infos.invalidate_liveness cfg_with_infos);
264-
main ~round:1 state cfg_with_infos;
260+
let flat =
261+
match Lazy.force Spilling_heuristics.value with
262+
| Flat_uses -> true
263+
| Hierarchical_uses -> false
264+
| Random_for_testing -> Spilling_heuristics.random ()
265+
in
266+
main ~round:1 ~flat state cfg_with_infos;
265267
if gi_debug then log_cfg_with_infos ~indent:1 cfg_with_infos;
266268
Regalloc_rewrite.postlude
267269
(module State)

backend/regalloc/regalloc_gi_utils.ml

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ module DLL = Flambda_backend_utils.Doubly_linked_list
55

66
let gi_debug = true
77

8+
let gi_rng = Random.State.make [| 4; 6; 2 |]
9+
810
let bool_of_param param_name =
911
bool_of_param ~guard:(gi_debug, "gi_debug") param_name
1012

@@ -43,11 +45,17 @@ let log_cfg_with_infos : indent:int -> Cfg_with_infos.t -> unit =
4345

4446
(* CR xclerc for xclerc: add more heuristics *)
4547
module Priority_heuristics = struct
46-
type t = Interval_length
48+
type t =
49+
| Interval_length
50+
| Random_for_testing
4751

48-
let all = [Interval_length]
52+
let all = [Interval_length; Random_for_testing]
53+
54+
let to_string = function
55+
| Interval_length -> "interval_length"
56+
| Random_for_testing -> "random"
4957

50-
let to_string = function Interval_length -> "interval_length"
58+
let random () = Random.State.int gi_rng 10_000
5159

5260
let value =
5361
let available_heuristics () =
@@ -64,6 +72,7 @@ module Priority_heuristics = struct
6472
| Some id -> (
6573
match String.lowercase_ascii id with
6674
| "interval_length" | "interval-length" -> Interval_length
75+
| "random" -> Random_for_testing
6776
| _ ->
6877
fatal "unknown heuristics %S (possible values: %s)" id
6978
(available_heuristics ())))
@@ -75,13 +84,24 @@ module Selection_heuristics = struct
7584
| First_available
7685
| Best_fit
7786
| Worst_fit
87+
| Random_for_testing
7888

79-
let all = [First_available; Best_fit; Worst_fit]
89+
let all = [First_available; Best_fit; Worst_fit; Random_for_testing]
8090

8191
let to_string = function
8292
| First_available -> "first_available"
8393
| Best_fit -> "best_fit"
8494
| Worst_fit -> "worst_fit"
95+
| Random_for_testing -> "random"
96+
97+
let include_in_random = function
98+
| Random_for_testing | Worst_fit -> false
99+
| First_available | Best_fit -> true
100+
101+
let random =
102+
let all = List.filter all ~f:include_in_random in
103+
let len = List.length all in
104+
fun () -> List.nth all (Random.State.int gi_rng len)
85105

86106
let value =
87107
let available_heuristics () =
@@ -100,6 +120,7 @@ module Selection_heuristics = struct
100120
| "first_available" | "first-available" -> First_available
101121
| "best_fit" | "best-fit" -> Best_fit
102122
| "worst_fit" | "worst-fit" -> Worst_fit
123+
| "random" -> Random_for_testing
103124
| _ ->
104125
fatal "unknown heuristics %S (possible values: %s)" id
105126
(available_heuristics ())))
@@ -109,12 +130,16 @@ module Spilling_heuristics = struct
109130
type t =
110131
| Flat_uses
111132
| Hierarchical_uses
133+
| Random_for_testing
112134

113-
let all = [Flat_uses; Hierarchical_uses]
135+
let all = [Flat_uses; Hierarchical_uses; Random_for_testing]
114136

115137
let to_string = function
116138
| Flat_uses -> "flat_uses"
117139
| Hierarchical_uses -> "hierarchical_uses"
140+
| Random_for_testing -> "random"
141+
142+
let random () = Random.State.bool gi_rng
118143

119144
let value =
120145
let available_heuristics () =
@@ -132,6 +157,7 @@ module Spilling_heuristics = struct
132157
match String.lowercase_ascii id with
133158
| "flat_uses" | "flat-uses" -> Flat_uses
134159
| "hierarchical_uses" | "hierarchical-uses" -> Hierarchical_uses
160+
| "random" -> Random_for_testing
135161
| _ ->
136162
fatal "unknown heuristics %S (possible values: %s)" id
137163
(available_heuristics ())))
@@ -705,7 +731,14 @@ module Hardware_registers = struct
705731
let find_available : t -> Reg.t -> Interval.t -> available =
706732
fun t reg interval ->
707733
let with_no_overlap =
708-
match Lazy.force Selection_heuristics.value with
734+
let heuristic =
735+
match Lazy.force Selection_heuristics.value with
736+
| Selection_heuristics.Random_for_testing ->
737+
Selection_heuristics.random ()
738+
| heuristic -> heuristic
739+
in
740+
match heuristic with
741+
| Selection_heuristics.Random_for_testing -> assert false
709742
| Selection_heuristics.First_available ->
710743
if gi_debug
711744
then

backend/regalloc/regalloc_gi_utils.mli

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@ val log_body_and_terminator :
2121
val log_cfg_with_infos : indent:int -> Cfg_with_infos.t -> unit
2222

2323
module Priority_heuristics : sig
24-
type t = Interval_length
24+
type t =
25+
| Interval_length
26+
| Random_for_testing
2527

2628
val all : t list
2729

2830
val to_string : t -> string
2931

32+
val random : unit -> int
33+
3034
val value : t Lazy.t
3135
end
3236

@@ -35,23 +39,29 @@ module Selection_heuristics : sig
3539
| First_available
3640
| Best_fit
3741
| Worst_fit
42+
| Random_for_testing
3843

3944
val all : t list
4045

4146
val to_string : t -> string
4247

48+
val random : unit -> t
49+
4350
val value : t Lazy.t
4451
end
4552

4653
module Spilling_heuristics : sig
4754
type t =
4855
| Flat_uses
4956
| Hierarchical_uses
57+
| Random_for_testing
5058

5159
val all : t list
5260

5361
val to_string : t -> string
5462

63+
val random : unit -> bool
64+
5565
val value : t Lazy.t
5666
end
5767

0 commit comments

Comments
 (0)