Pass num_stack_slots as argument
parent
357932d9c3
commit
cae89d4e1b
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -15,4 +15,4 @@
|
|||
|
||||
(* Register allocation by coloring of the interference graph *)
|
||||
|
||||
val allocate_registers: unit -> unit
|
||||
val allocate_registers: unit -> int array
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,4 +16,4 @@
|
|||
|
||||
(* Linear scan register allocation. *)
|
||||
|
||||
val allocate_registers: unit -> unit
|
||||
val allocate_registers: unit -> int array
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue