Compute the degrees while building the interference graph.
This speeds up the register allocator and allows for further optimizations. git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@13142 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02master
parent
ff4e0a81f8
commit
2f077a9ab7
|
@ -47,20 +47,10 @@ let find_degree reg =
|
|||
if reg.spill then () else begin
|
||||
let cl = Proc.register_class reg in
|
||||
let avail_regs = Proc.num_available_registers.(cl) in
|
||||
if avail_regs = 0 then
|
||||
(* Don't bother computing the degree if there are no regs
|
||||
in this class *)
|
||||
if reg.degree < avail_regs then
|
||||
unconstrained := Reg.Set.add reg !unconstrained
|
||||
else begin
|
||||
let deg = ref 0 in
|
||||
List.iter
|
||||
(fun r -> if not r.spill && Proc.register_class r = cl then incr deg)
|
||||
reg.interf;
|
||||
reg.degree <- !deg;
|
||||
if !deg >= avail_regs
|
||||
then constrained := Reg.Set.add reg !constrained
|
||||
else unconstrained := Reg.Set.add reg !unconstrained
|
||||
end
|
||||
else
|
||||
constrained := Reg.Set.add reg !constrained
|
||||
end
|
||||
|
||||
(* Remove a register from the interference graph *)
|
||||
|
|
|
@ -29,13 +29,20 @@ let build_graph fundecl =
|
|||
|
||||
(* Record an interference between two registers *)
|
||||
let add_interf ri rj =
|
||||
let update rs rt =
|
||||
if rs.loc = Unknown then begin
|
||||
rs.interf <- rt :: rs.interf;
|
||||
if not rt.spill
|
||||
&& Proc.register_class rs = Proc.register_class rt
|
||||
then rs.degree <- rs.degree + 1
|
||||
end in
|
||||
let i = ri.stamp and j = rj.stamp in
|
||||
if i <> j then begin
|
||||
let p = if i < j then (i, j) else (j, i) in
|
||||
if not(IntPairSet.mem p !mat) then begin
|
||||
mat := IntPairSet.add p !mat;
|
||||
if ri.loc = Unknown then ri.interf <- rj :: ri.interf;
|
||||
if rj.loc = Unknown then rj.interf <- ri :: rj.interf
|
||||
update ri rj;
|
||||
update rj ri
|
||||
end
|
||||
end in
|
||||
|
||||
|
|
Loading…
Reference in New Issue