summaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-04-10 12:15:43 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-04-10 12:15:43 +0000
commita32ed5df6aa31aa5a38a55af9d75880e906721f2 (patch)
tree737bf6863dde159547d11941fde0af70ffad3278 /backend
parentbae0ed25d01388093ebcb4b32db0b6d1169f17db (diff)
Coloring: allow to exclude user-specified registers from allocation.
CPragmas (PPC/EABI only): add #pragma reserve_register git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1314 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'backend')
-rw-r--r--backend/Coloringaux.ml65
-rw-r--r--backend/Coloringaux.mli2
2 files changed, 42 insertions, 25 deletions
diff --git a/backend/Coloringaux.ml b/backend/Coloringaux.ml
index 9b65769..04cc1ee 100644
--- a/backend/Coloringaux.ml
+++ b/backend/Coloringaux.ml
@@ -167,6 +167,42 @@ module IntPairSet = Set.Make(struct
0
end)
+(* Register classes *)
+
+let class_of_type = function Tint -> 0 | Tfloat -> 1
+
+let num_register_classes = 2
+
+let caller_save_registers = Array.make num_register_classes [||]
+
+let callee_save_registers = Array.make num_register_classes [||]
+
+let num_available_registers = Array.make num_register_classes 0
+
+let reserved_registers = ref ([]: mreg list)
+
+let rec remove_reserved = function
+ | [] -> []
+ | hd :: tl ->
+ if List.mem hd !reserved_registers
+ then remove_reserved tl
+ else hd :: remove_reserved tl
+
+let init_regs() =
+ caller_save_registers.(0) <-
+ Array.of_list (remove_reserved Conventions.int_caller_save_regs);
+ caller_save_registers.(1) <-
+ Array.of_list (remove_reserved Conventions.float_caller_save_regs);
+ callee_save_registers.(0) <-
+ Array.of_list (remove_reserved Conventions.int_callee_save_regs);
+ callee_save_registers.(1) <-
+ Array.of_list (remove_reserved Conventions.float_callee_save_regs);
+ for i = 0 to num_register_classes - 1 do
+ num_available_registers.(i) <-
+ Array.length caller_save_registers.(i)
+ + Array.length callee_save_registers.(i)
+ done
+
(* \subsection{The George-Appel algorithm} *)
(* Below is a straigthforward translation of the pseudo-code at the end
@@ -208,7 +244,7 @@ let nextRegIdent = ref 0
(* Initialization of all global data structures *)
-let init() =
+let init_graph() =
adjSet := IntPairSet.empty;
nextRegIdent := 0;
DLinkNode.clear simplifyWorklist;
@@ -268,28 +304,6 @@ let nodeMoves n =
let moveRelated n =
List.exists moveIsActiveOrWorklist n.movelist
-(* Register classes *)
-
-let class_of_type = function Tint -> 0 | Tfloat -> 1
-
-let num_register_classes = 2
-
-let caller_save_registers = [|
- Array.of_list Conventions.int_caller_save_regs;
- Array.of_list Conventions.float_caller_save_regs
-|]
-
-let callee_save_registers = [|
- Array.of_list Conventions.int_callee_save_regs;
- Array.of_list Conventions.float_callee_save_regs
-|]
-
-let num_available_registers =
- [| Array.length caller_save_registers.(0)
- + Array.length callee_save_registers.(0);
- Array.length caller_save_registers.(1)
- + Array.length callee_save_registers.(1) |]
-
(*i
(* Check invariants *)
@@ -689,11 +703,12 @@ let spill_costs f = Hashtbl.create 7
let graph_coloring (f: coq_function) (g: graph) (env: regenv) (regs: Regset.t)
: (reg -> loc) =
- init();
+ init_regs();
+ init_graph();
Array.fill start_points 0 num_register_classes 0;
let mapping = build g env (spill_costs f) in
List.iter assign_color (nodeOrder []);
- init();
+ init_graph(); (* free data structures *)
fun r ->
try location_of_node (getAlias (Hashtbl.find mapping r))
with Not_found -> R IT1 (* any location *)
diff --git a/backend/Coloringaux.mli b/backend/Coloringaux.mli
index c5070f2..7597c7c 100644
--- a/backend/Coloringaux.mli
+++ b/backend/Coloringaux.mli
@@ -18,3 +18,5 @@ open InterfGraph
val graph_coloring:
coq_function -> graph -> regenv -> Regset.t -> (reg -> loc)
+
+val reserved_registers: Machregs.mreg list ref