Skip to content

Simplify the Utils module (register allocation) #3836

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions backend/regalloc/regalloc_gi.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,7 @@ open! Int_replace_polymorphic_compare
open! Regalloc_utils
open! Regalloc_gi_utils
module State = Regalloc_gi_state

module Utils = struct
include Regalloc_gi_utils

type state = State.t

let debug = debug

let invariants = invariants

let is_spilled _state reg = reg.Reg.spill

let set_spilled _state _reg = ()
end
module Utils = Regalloc_gi_utils

let rewrite : State.t -> Cfg_with_infos.t -> spilled_nodes:Reg.t list -> bool =
fun state cfg_with_infos ~spilled_nodes ->
Expand Down
21 changes: 1 addition & 20 deletions backend/regalloc/regalloc_irc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -384,26 +384,7 @@ let assign_colors : State.t -> Cfg_with_layout.t -> unit =
State.set_color state n (State.color state alias));
if debug then dedent ()

module Utils = struct
include Regalloc_irc_utils

type state = State.t

let debug = debug

let invariants = invariants

let is_spilled state reg =
match State.work_list_opt state reg with
| None ->
(* Freshly-created may not have been added to the map yet; such registers
would morally be in the "unknown" work list, hence returning
`false`. *)
false
| Some work_list -> WorkList.equal work_list WorkList.Spilled

let set_spilled _state reg = reg.Reg.spill <- true
end
module Utils = Regalloc_irc_utils

(* Returns `true` if new temporaries have been introduced. *)
let rewrite :
Expand Down
14 changes: 1 addition & 13 deletions backend/regalloc/regalloc_ls.ml
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,7 @@ module State = Regalloc_ls_state

let snapshot_for_fatal = ref None

module Utils = struct
include Regalloc_ls_utils

type state = State.t

let debug = debug

let invariants = invariants

let is_spilled _state reg = reg.Reg.spill

let set_spilled _state _reg = ()
end
module Utils = Regalloc_ls_utils

let rewrite :
State.t ->
Expand Down
41 changes: 15 additions & 26 deletions backend/regalloc/regalloc_rewrite.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ module type State = sig
end

module type Utils = sig
type state

val debug : bool

val invariants : bool Lazy.t

val log : ?no_eol:unit -> ('a, Format.formatter, unit) format -> 'a

val indent : unit -> unit
Expand All @@ -31,10 +25,6 @@ module type Utils = sig
Cfg.terminator Cfg.instruction ->
liveness ->
unit

val is_spilled : state -> Reg.t -> bool

val set_spilled : state -> Reg.t -> unit
end

type direction =
Expand Down Expand Up @@ -127,7 +117,7 @@ let equal_move_kind left right =
let rewrite_gen :
type s.
(module State with type t = s) ->
(module Utils with type state = s) ->
(module Utils) ->
s ->
Cfg_with_infos.t ->
spilled_nodes:Reg.t list ->
Expand All @@ -138,36 +128,35 @@ let rewrite_gen :
let should_coalesce_temp_spills_and_reloads =
Lazy.force Regalloc_utils.block_temporaries && block_temporaries
in
if Utils.debug
if debug
then (
Utils.log "rewrite";
Utils.indent ());
let block_insertion = ref false in
let spilled_map : Reg.t Reg.Tbl.t =
List.fold_left spilled_nodes ~init:(Reg.Tbl.create 17)
~f:(fun spilled_map reg ->
if Utils.debug then assert (Utils.is_spilled state reg);
let spilled = Reg.create reg.Reg.typ in
Utils.set_spilled state spilled;
(* for printing *)
spilled.Reg.raw_name <- reg.Reg.raw_name;
let slot =
Regalloc_stack_slots.get_or_create (State.stack_slots state) reg
in
spilled.Reg.loc <- Reg.(Stack (Local slot));
if Utils.debug
if debug
then Utils.log "spilling %a to %a" Printreg.reg reg Printreg.reg spilled;
Reg.Tbl.replace spilled_map reg spilled;
spilled_map)
in
let is_spilled reg = Reg.Tbl.mem spilled_map reg in
let new_inst_temporaries : Reg.t list ref = ref [] in
let new_block_temporaries = ref [] in
let make_new_temporary ~(move : Move.t) (reg : Reg.t) : Reg.t =
let res =
make_temporary ~same_class_and_base_name_as:reg ~name_prefix:"temp"
in
new_inst_temporaries := res :: !new_inst_temporaries;
if Utils.debug
if debug
then
Utils.log "adding temporary %a (to %s %a)" Printreg.reg res
(Move.to_string move) Printreg.reg reg;
Expand All @@ -176,7 +165,7 @@ let rewrite_gen :
let[@inline] array_contains_spilled (arr : Reg.t array) : bool =
let len = Array.length arr in
let i = ref 0 in
while !i < len && not (Utils.is_spilled state (Array.unsafe_get arr !i)) do
while !i < len && not (is_spilled (Array.unsafe_get arr !i)) do
incr i
done;
!i < len
Expand All @@ -188,7 +177,7 @@ let rewrite_gen :
~(sharing : (Reg.t * move_kind) Reg.Tbl.t) (instr : _ Cfg.instruction) :
unit =
let[@inline] rewrite_reg (reg : Reg.t) : Reg.t =
if Utils.is_spilled state reg
if is_spilled reg
then (
let spilled =
match Reg.Tbl.find_opt spilled_map reg with
Expand Down Expand Up @@ -239,7 +228,7 @@ let rewrite_gen :
in
let liveness = Cfg_with_infos.liveness cfg_with_infos in
Cfg.iter_blocks (Cfg_with_infos.cfg cfg_with_infos) ~f:(fun label block ->
if Utils.debug
if debug
then (
Utils.log "body of #%a, before:" Label.format label;
Utils.indent ();
Expand Down Expand Up @@ -307,14 +296,14 @@ let rewrite_gen :
then
coalesce_temp_spills_and_reloads block ~new_inst_temporaries
~new_block_temporaries;
if Utils.debug
if debug
then (
Utils.log "and after:";
Utils.indent ();
Utils.log_body_and_terminator block.body block.terminator liveness;
Utils.dedent ();
Utils.log "end"));
if Utils.debug then Utils.dedent ();
if debug then Utils.dedent ();
!new_inst_temporaries, !new_block_temporaries, !block_insertion

(* CR-soon xclerc for xclerc: investigate exactly why this threshold is
Expand All @@ -332,10 +321,10 @@ let prelude :
fun (module Utils) ~on_fatal_callback cfg_with_infos ->
let cfg_with_layout = Cfg_with_infos.cfg_with_layout cfg_with_infos in
on_fatal ~f:on_fatal_callback;
if Utils.debug
if debug
then Utils.log "run (%S)" (Cfg_with_layout.cfg cfg_with_layout).fun_name;
Reg.reinit ();
if Utils.debug && Lazy.force Utils.invariants
if debug && Lazy.force invariants
then (
Utils.log "precondition";
Regalloc_invariants.precondition cfg_with_layout);
Expand All @@ -346,7 +335,7 @@ let prelude :
the same results without computing the union. *)
Reg.Set.cardinal cfg_infos.arg
in
if Utils.debug then Utils.log "#temporaries(before):%d" num_temporaries;
if debug then Utils.log "#temporaries(before):%d" num_temporaries;
if num_temporaries >= threshold_split_live_ranges
|| Flambda2_ui.Flambda_features.classic_mode ()
then cfg_infos, Regalloc_stack_slots.make ()
Expand Down Expand Up @@ -379,7 +368,7 @@ let postlude :
();
Regalloc_stack_slots.update_cfg_with_layout (State.stack_slots state)
cfg_with_layout;
if Utils.debug
if debug
then (
Utils.indent ();
Stack_class.Tbl.iter
Expand All @@ -391,7 +380,7 @@ let postlude :
remove_prologue_if_not_required cfg_with_layout;
update_live_fields cfg_with_layout (Cfg_with_infos.liveness cfg_with_infos);
f ();
if Utils.debug && Lazy.force Utils.invariants
if debug && Lazy.force invariants
then (
Utils.log "postcondition";
Regalloc_invariants.postcondition_liveness cfg_with_infos)
14 changes: 1 addition & 13 deletions backend/regalloc/regalloc_rewrite.mli
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ module type State = sig
end

module type Utils = sig
type state

val debug : bool

val invariants : bool Lazy.t

val log : ?no_eol:unit -> ('a, Format.formatter, unit) format -> 'a

val indent : unit -> unit
Expand All @@ -28,12 +22,6 @@ module type Utils = sig
Cfg.terminator Cfg.instruction ->
liveness ->
unit

(* Tests whether the passed register is marked as "spilled". *)
val is_spilled : state -> Reg.t -> bool

(* Sets the passed register as "spilled". *)
val set_spilled : state -> Reg.t -> unit
end

(* This is the `rewrite` function from IRC, parametrized by state, functions for
Expand All @@ -48,7 +36,7 @@ end
will be empty. *)
val rewrite_gen :
(module State with type t = 's) ->
(module Utils with type state = 's) ->
(module Utils) ->
's ->
Cfg_with_infos.t ->
spilled_nodes:Reg.t list ->
Expand Down