Skip to content

Refactor stack classes #1763

New issue

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

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

Already on GitHub? # to your account

Closed
wants to merge 1 commit into from
Closed

Refactor stack classes #1763

wants to merge 1 commit into from

Conversation

xclerc
Copy link
Contributor

@xclerc xclerc commented Aug 23, 2023

This pull request refactors the handling of
stack classes. Since the introduction of
vector types (#1499), we distinguish
between register and stack classes.

Having both encoded as mere ints is
error-prone, so this pull request introduces
a proper and abstract type for stack
classes (a similar refactoring will be
performed on register classes, but it is
slightly more complex).

This pull request introduces the following
modules:

  • Stack_class_utils which defines what
    stack classes and tables with stack classes
    as keys are;
  • Stack_class which defines backend-dependent
    stack classes.

As of 23c8124, tables are implemented
as hash tables instead of arrays. If this causes
a performance or marshalling issue, it is
easy to use a bare array as the underlying
representation of the table.

@@ -338,7 +338,8 @@ let compile_fundecl ~ppf_dump ~funcnames fd_cmm =
(* Skip DWARF variable range generation for complicated functions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this PR, we should factor this out into a helper function (I missed it when it was merged, but perhaps we can sneak it in here since the code is changed?).

Comment on lines +58 to +60
val total_size_in_bytes_for_class : int t -> stack_class:stack_class -> int

val total_size_in_bytes : int t -> int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these for? They don't seem to fit in with the generic table.

val offset_in_bytes_for_class : stack_class:t -> slot:int -> int

val offset_in_bytes : int Tbl.t -> stack_class:t -> slot:int -> int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand these two functions: what is the difference between them, why do we need both?
What does int Tbl.t represent - can it be abstracted or named to make this more intuitive?
From the way it is used, I am guessing it is meant for num_stack_slots.

@@ -22,6 +22,6 @@ class reload_generic : object
method makereg : Reg.t -> Reg.t
(* Can be overridden to avoid creating new registers of some class
(i.e. if all "registers" of that class are actually on stack) *)
method fundecl : Mach.fundecl -> int array -> Mach.fundecl * bool
method fundecl : Mach.fundecl -> int Stack_class.Tbl.t -> Mach.fundecl * bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to label this argument? Something like num_stack_slots? Or perhaps the type can be more informative without a label, something lke Stack_class.num_stack_slots? This appears in a couple of other places, reload.mli.

Comment on lines 70 to 72
&& Stack_class.equal
(Stack_class.of_machtype arg.(0).typ)
(Stack_class.of_machtype res.(0).typ) then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This expression appears in a few places, maybe it deserves a helper function, something like Stack_class.equal_of_mach_types and an explanation that different mach types can share stack classes if their slots are of the same size, e.g., Val and Int?

let offset_in_bytes
: int Tbl.t -> stack_class:t -> slot:int -> int
= fun tbl ~stack_class ~slot ->
match stack_class with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
match stack_class with
match stack_class with
(* Preserves original ordering (int -> float) *)

but really this is the only remaining place where something important is implicit (the layout of slots), so it at least deserves a comment. Considering the upcoming vec256 and friends, it may be worth having a little loop here instead of the match, to sum up total_size_in_bytes_for_class for all classes prior to stack_class in the layout.

let copy : 'a t -> 'a t = fun tbl -> Tbl.copy tbl

let copy_values : from:'a t -> to_:'a t -> unit =
fun ~from ~to_ ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may be worth having an assert that from and to have the same keys.

{ stack_slots; num_stack_slots }

let[@inline] size_for_all_stack_classes t =
Array.fold_left t.num_stack_slots ~f:( + ) ~init:0
Stack_class.Tbl.fold t.num_stack_slots
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not from this PR but now size_for_all_stack_classes can be more confusing with Stack_class.Tbl.total_size. Maybe rename this to something like total_num_of_stack_slots_for_all_classes?

@xclerc xclerc force-pushed the refactor-stack-classes branch from e9fa6fe to 7d81e99 Compare February 29, 2024 14:25
@xclerc xclerc closed this Apr 7, 2025
@xclerc
Copy link
Contributor Author

xclerc commented Apr 7, 2025

Superseded by #3784.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants