Pass num_stack_slots as argument

master
Greta Yorsh 2019-09-11 18:38:09 +01:00
parent 357932d9c3
commit cae89d4e1b
14 changed files with 56 additions and 57 deletions

View File

@ -124,5 +124,5 @@ method! reload_test tst arg =
end
let fundecl f =
(new reload)#fundecl f
let fundecl f num_stack_slots =
(new reload)#fundecl f num_stack_slots

View File

@ -53,5 +53,5 @@ method! reload_operation op arg res =
argres'
end
let fundecl f =
(new reload)#fundecl f
let fundecl f num_stack_slots =
(new reload)#fundecl f num_stack_slots

View File

@ -15,5 +15,5 @@
(* Reloading for the ARM 64 bits *)
let fundecl f =
(new Reloadgen.reload_generic)#fundecl f
let fundecl f num_stack_slots =
(new Reloadgen.reload_generic)#fundecl f num_stack_slots

View File

@ -44,20 +44,22 @@ let rec regalloc ~ppf_dump round fd =
fatal_error(fd.Mach.fun_name ^
": function too complex, cannot complete register allocation");
dump_if ppf_dump dump_live "Liveness analysis" fd;
if !use_linscan then begin
(* Linear Scan *)
Interval.build_intervals fd;
if !dump_interval then Printmach.intervals ppf_dump ();
Linscan.allocate_registers()
end else begin
(* Graph Coloring *)
Interf.build_graph fd;
if !dump_interf then Printmach.interferences ppf_dump ();
if !dump_prefer then Printmach.preferences ppf_dump ();
Coloring.allocate_registers()
end;
let num_stack_slots =
if !use_linscan then begin
(* Linear Scan *)
Interval.build_intervals fd;
if !dump_interval then Printmach.intervals ppf_dump ();
Linscan.allocate_registers()
end else begin
(* Graph Coloring *)
Interf.build_graph fd;
if !dump_interf then Printmach.interferences ppf_dump ();
if !dump_prefer then Printmach.preferences ppf_dump ();
Coloring.allocate_registers()
end
in
dump_if ppf_dump dump_regalloc "After register allocation" fd;
let (newfd, redo_regalloc) = Reload.fundecl fd in
let (newfd, redo_regalloc) = Reload.fundecl fd num_stack_slots in
dump_if ppf_dump dump_reload "After insertion of reloading code" newfd;
if redo_regalloc then begin
Reg.reinit(); Liveness.fundecl newfd; regalloc ~ppf_dump (round + 1) newfd

View File

@ -43,13 +43,16 @@ let allocate_registers() =
(* Unconstrained regs with degree < number of available registers *)
let unconstrained = ref [] in
(* Reset the stack slot counts *)
let num_stack_slots = Array.make Proc.num_register_classes 0 in
(* Preallocate the spilled registers in the stack.
Split the remaining registers into constrained and unconstrained. *)
let remove_reg reg =
let cl = Proc.register_class reg in
if reg.spill then begin
(* Preallocate the registers in the stack *)
let nslots = Reloadgen.num_stack_slots.(cl) in
let nslots = num_stack_slots.(cl) in
let conflict = Array.make nslots false in
List.iter
(fun r ->
@ -61,7 +64,7 @@ let allocate_registers() =
let slot = ref 0 in
while !slot < nslots && conflict.(!slot) do incr slot done;
reg.loc <- Stack(Local !slot);
if !slot >= nslots then Reloadgen.num_stack_slots.(cl) <- !slot + 1
if !slot >= nslots then num_stack_slots.(cl) <- !slot + 1
end else if reg.degree < Proc.num_available_registers.(cl) then
unconstrained := reg :: !unconstrained
else begin
@ -163,7 +166,7 @@ let allocate_registers() =
if start >= num_regs then 0 else start)
end else begin
(* Sorry, we must put the pseudoreg in a stack location *)
let nslots = Reloadgen.num_stack_slots.(cl) in
let nslots = num_stack_slots.(cl) in
let score = Array.make nslots 0 in
(* Compute the scores as for registers *)
List.iter
@ -206,21 +209,17 @@ let allocate_registers() =
else begin
(* Allocate a new stack slot *)
reg.loc <- Stack(Local nslots);
Reloadgen.num_stack_slots.(cl) <- nslots + 1
num_stack_slots.(cl) <- nslots + 1
end
end;
(* Cancel the preferences of this register so that they don't influence
transitively the allocation of registers that prefer this reg. *)
reg.prefer <- [] in
(* Reset the stack slot counts *)
for i = 0 to Proc.num_register_classes - 1 do
Reloadgen.num_stack_slots.(i) <- 0;
done;
(* First pass: preallocate spill registers and split remaining regs
Second pass: assign locations to constrained regs
Third pass: assign locations to unconstrained regs *)
List.iter remove_reg (Reg.all_registers());
OrderedRegSet.iter assign_location !constrained;
List.iter assign_location !unconstrained
List.iter assign_location !unconstrained;
num_stack_slots

View File

@ -15,4 +15,4 @@
(* Register allocation by coloring of the interference graph *)
val allocate_registers: unit -> unit
val allocate_registers: unit -> int array

View File

@ -82,5 +82,5 @@ method! reload_test tst arg =
end
let fundecl f =
(new reload)#fundecl f
let fundecl f num_stack_slots =
(new reload)#fundecl f num_stack_slots

View File

@ -71,10 +71,10 @@ let rec release_expired_inactive ci pos = function
(* Allocate a new stack slot to the interval. *)
let allocate_stack_slot i =
let allocate_stack_slot num_stack_slots i =
let cl = Proc.register_class i.reg in
let ss = Reloadgen.num_stack_slots.(cl) in
Reloadgen.num_stack_slots.(cl) <- succ ss;
let ss = num_stack_slots.(cl) in
num_stack_slots.(cl) <- succ ss;
i.reg.loc <- Stack(Local ss);
i.reg.spill <- true
@ -82,11 +82,11 @@ let allocate_stack_slot i =
The interval is added to active. Raises Not_found if no free registers
left. *)
let allocate_free_register i =
let allocate_free_register num_stack_slots i =
begin match i.reg.loc, i.reg.spill with
Unknown, true ->
(* Allocate a stack slot for the already spilled interval *)
allocate_stack_slot i
allocate_stack_slot num_stack_slots i
| Unknown, _ ->
(* We need to allocate a register to this interval somehow *)
let cl = Proc.register_class i.reg in
@ -136,7 +136,7 @@ let allocate_free_register i =
| _ -> ()
end
let allocate_blocked_register i =
let allocate_blocked_register num_stack_slots i =
let cl = Proc.register_class i.reg in
let ci = active.(cl) in
match ci.ci_active with
@ -154,14 +154,14 @@ let allocate_blocked_register i =
(* Remove the last interval from active and insert the current *)
ci.ci_active <- insert_interval_sorted i il;
(* Now get a new stack slot for the spilled register *)
allocate_stack_slot ilast
allocate_stack_slot num_stack_slots ilast
| _ ->
(* Either the current interval is last and we have to spill it,
or there are no registers at all in the register class (i.e.
floating point class on i386). *)
allocate_stack_slot i
allocate_stack_slot num_stack_slots i
let walk_interval i =
let walk_interval num_stack_slots i =
let pos = i.ibegin land (lnot 0x01) in
(* Release all intervals that have been expired at the current position *)
Array.iter
@ -172,11 +172,11 @@ let walk_interval i =
active;
try
(* Allocate free register (if any) *)
allocate_free_register i
allocate_free_register num_stack_slots i
with
Not_found ->
(* No free register, need to decide which interval to spill *)
allocate_blocked_register i
allocate_blocked_register num_stack_slots i
let allocate_registers() =
(* Initialize the stack slots and interval lists *)
@ -187,8 +187,9 @@ let allocate_registers() =
ci_active = [];
ci_inactive = []
};
Reloadgen.num_stack_slots.(cl) <- 0
done;
(* Reset the stack slot counts *)
let num_stack_slots = Array.make Proc.num_register_classes 0 in
(* Add all fixed intervals (sorted by end position) *)
List.iter
(fun i ->
@ -196,4 +197,5 @@ let allocate_registers() =
ci.ci_fixed <- insert_interval_sorted i ci.ci_fixed)
(Interval.all_fixed_intervals());
(* Walk all the intervals within the list *)
List.iter walk_interval (Interval.all_intervals())
List.iter (walk_interval num_stack_slots) (Interval.all_intervals());
num_stack_slots

View File

@ -16,4 +16,4 @@
(* Linear scan register allocation. *)
val allocate_registers: unit -> unit
val allocate_registers: unit -> int array

View File

@ -15,5 +15,5 @@
(* Reloading for the PowerPC *)
let fundecl f =
(new Reloadgen.reload_generic)#fundecl f
let fundecl f num_stack_slots =
(new Reloadgen.reload_generic)#fundecl f num_stack_slots

View File

@ -15,4 +15,4 @@
(* Insert load/stores for pseudoregs that got assigned to stack locations. *)
val fundecl: Mach.fundecl -> Mach.fundecl * bool
val fundecl: Mach.fundecl -> int array -> Mach.fundecl * bool

View File

@ -19,8 +19,6 @@ open Misc
open Reg
open Mach
let num_stack_slots = Array.make Proc.num_register_classes 0
let insert_move src dst next =
if src.loc = dst.loc
then next
@ -125,7 +123,7 @@ method private reload i =
instr_cons (Itrywith(self#reload body, self#reload handler)) [||] [||]
(self#reload i.next)
method fundecl f =
method fundecl f num_stack_slots =
redo_regalloc <- false;
let new_body = self#reload f.fun_body in
({fun_name = f.fun_name; fun_args = f.fun_args;

View File

@ -22,8 +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 -> Mach.fundecl * bool
method fundecl : Mach.fundecl -> int array -> Mach.fundecl * bool
(* The entry point *)
end
val num_stack_slots: int array

View File

@ -46,5 +46,5 @@ method! reload_operation op arg res =
end
let fundecl f =
(new reload)#fundecl f
let fundecl f num_stack_slots =
(new reload)#fundecl f num_stack_slots