@@ -256,8 +256,9 @@ let freeze : State.t -> unit =
256
256
State. add_simplify_work_list state reg;
257
257
freeze_moves state reg
258
258
259
- let select_spilling_register_using_heuristics : State.t -> Reg.t =
260
- fun state ->
259
+ let select_spilling_register_using_heuristics : State. t -> SpillCosts. t -> Reg. t
260
+ =
261
+ fun state costs ->
261
262
match Lazy. force Spilling_heuristics. value with
262
263
| Set_choose -> (
263
264
(* This is the "heuristics" from the IRC paper: pick any candidate, just try
@@ -280,8 +281,9 @@ let select_spilling_register_using_heuristics : State.t -> Reg.t =
280
281
let weighted_cost (reg : Reg.t ) =
281
282
if debug
282
283
then
283
- log " register %a has spill cost %d" Printreg. reg reg reg.Reg. spill_cost;
284
- (float reg.Reg. spill_cost /. float (State. degree state reg))
284
+ log " register %a has spill cost %d" Printreg. reg reg
285
+ (SpillCosts. for_reg costs reg);
286
+ (float (SpillCosts. for_reg costs reg) /. float (State. degree state reg))
285
287
(* note: while this magic constant is questionable, it is key to not favor
286
288
the introduced temporaries which, by construct, have very few
287
289
occurrences. *)
@@ -300,13 +302,13 @@ let select_spilling_register_using_heuristics : State.t -> Reg.t =
300
302
else acc)
301
303
|> fst)
302
304
303
- let select_spill : State.t -> unit =
304
- fun state ->
305
+ let select_spill : State.t -> SpillCosts.t -> unit =
306
+ fun state costs ->
305
307
if debug
306
308
then (
307
309
log " select_spill" ;
308
310
indent () );
309
- let reg = select_spilling_register_using_heuristics state in
311
+ let reg = select_spilling_register_using_heuristics state costs in
310
312
if debug
311
313
then
312
314
log " chose %a using heuristics %S" Printreg. reg reg
@@ -461,7 +463,7 @@ let rec main : round:int -> State.t -> Cfg_with_infos.t -> unit =
461
463
make_work_list state;
462
464
State. invariant state;
463
465
if debug then log_work_list_desc " before loop" ;
464
- let spill_cost_is_up_to_date = ref false in
466
+ let spill_costs = ref ( None : SpillCosts.t option ) in
465
467
let continue = ref true in
466
468
while ! continue do
467
469
if not (State. is_empty_simplify_work_list state)
@@ -471,16 +473,24 @@ let rec main : round:int -> State.t -> Cfg_with_infos.t -> unit =
471
473
else if not (State. is_empty_freeze_work_list state)
472
474
then freeze state
473
475
else if not (State. is_empty_spill_work_list state)
474
- then (
475
- if not ! spill_cost_is_up_to_date
476
- then (
477
- (match Lazy. force Spilling_heuristics. value with
478
- | Set_choose ->
479
- (* note: `spill_cost` will not be used by the heuristics *) ()
480
- | Flat_uses -> update_spill_cost cfg_with_infos ~flat: true ()
481
- | Hierarchical_uses -> update_spill_cost cfg_with_infos ~flat: false () );
482
- spill_cost_is_up_to_date := true );
483
- select_spill state)
476
+ then
477
+ let costs =
478
+ match ! spill_costs with
479
+ | Some costs -> costs
480
+ | None ->
481
+ let costs =
482
+ match Lazy. force Spilling_heuristics. value with
483
+ | Set_choose ->
484
+ (* note: `spill_cost` will not be used by the heuristics *)
485
+ SpillCosts. empty ()
486
+ | Flat_uses -> SpillCosts. compute cfg_with_infos ~flat: true ()
487
+ | Hierarchical_uses ->
488
+ SpillCosts. compute cfg_with_infos ~flat: false ()
489
+ in
490
+ spill_costs := Some costs;
491
+ costs
492
+ in
493
+ select_spill state costs
484
494
else continue := false ;
485
495
if debug then log_work_list_desc " end of loop" ;
486
496
State. invariant state
0 commit comments