aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-04-10 12:15:43 +0000
committerxleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-04-10 12:15:43 +0000
commita32ed5df6aa31aa5a38a55af9d75880e906721f2 (patch)
tree737bf6863dde159547d11941fde0af70ffad3278
parentbae0ed25d01388093ebcb4b32db0b6d1169f17db (diff)
downloadcompcert-kvx-a32ed5df6aa31aa5a38a55af9d75880e906721f2.tar.gz
compcert-kvx-a32ed5df6aa31aa5a38a55af9d75880e906721f2.zip
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
-rw-r--r--backend/Coloringaux.ml65
-rw-r--r--backend/Coloringaux.mli2
-rw-r--r--powerpc/Machregsaux.ml45
-rw-r--r--powerpc/Machregsaux.mli16
-rw-r--r--powerpc/eabi/CPragmas.ml31
5 files changed, 131 insertions, 28 deletions
diff --git a/backend/Coloringaux.ml b/backend/Coloringaux.ml
index 9b657697..04cc1ee2 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 c5070f20..7597c7ca 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
diff --git a/powerpc/Machregsaux.ml b/powerpc/Machregsaux.ml
new file mode 100644
index 00000000..b729d100
--- /dev/null
+++ b/powerpc/Machregsaux.ml
@@ -0,0 +1,45 @@
+(* *********************************************************************)
+(* *)
+(* The Compcert verified compiler *)
+(* *)
+(* Xavier Leroy, INRIA Paris-Rocquencourt *)
+(* *)
+(* Copyright Institut National de Recherche en Informatique et en *)
+(* Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the INRIA Non-Commercial License Agreement. *)
+(* *)
+(* *********************************************************************)
+
+(** Auxiliary functions on machine registers *)
+
+open Machregs
+
+let register_names = [
+ ("R3", R3); ("R4", R4); ("R5", R5); ("R6", R6);
+ ("R7", R7); ("R8", R8); ("R9", R9); ("R10", R10);
+ ("R14", R14); ("R15", R15); ("R16", R16);
+ ("R17", R17); ("R18", R18); ("R19", R19); ("R20", R20);
+ ("R21", R21); ("R22", R22); ("R23", R23); ("R24", R24);
+ ("R25", R25); ("R26", R26); ("R27", R27); ("R28", R28);
+ ("R29", R29); ("R30", R30); ("R31", R31);
+ ("F1", F1); ("F2", F2); ("F3", F3); ("F4", F4);
+ ("F5", F5); ("F6", F6); ("F7", F7); ("F8", F8);
+ ("F9", F9); ("F10", F10); ("F14", F14); ("F15", F15);
+ ("F16", F16); ("F17", F17); ("F18", F18); ("F19", F19);
+ ("F20", F20); ("F21", F21); ("F22", F22); ("F23", F23);
+ ("F24", F24); ("F25", F25); ("F26", F26); ("F27", F27);
+ ("F28", F28); ("F29", F29); ("F30", F30); ("F31", F31);
+ ("R11", IT1); ("R0", IT2);
+ ("F11", FT1); ("F12", FT2); ("F0", FT3)
+]
+
+let register_by_name s =
+ try
+ Some(List.assoc (String.uppercase s) register_names)
+ with Not_found ->
+ None
+
+let can_reserve_register r =
+ List.mem r Conventions.int_callee_save_regs
+ || List.mem r Conventions.float_callee_save_regs
+
diff --git a/powerpc/Machregsaux.mli b/powerpc/Machregsaux.mli
new file mode 100644
index 00000000..6d819882
--- /dev/null
+++ b/powerpc/Machregsaux.mli
@@ -0,0 +1,16 @@
+(* *********************************************************************)
+(* *)
+(* The Compcert verified compiler *)
+(* *)
+(* Xavier Leroy, INRIA Paris-Rocquencourt *)
+(* *)
+(* Copyright Institut National de Recherche en Informatique et en *)
+(* Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the INRIA Non-Commercial License Agreement. *)
+(* *)
+(* *********************************************************************)
+
+(** Auxiliary functions on machine registers *)
+
+val register_by_name: string -> Machregs.mreg option
+val can_reserve_register: Machregs.mreg -> bool
diff --git a/powerpc/eabi/CPragmas.ml b/powerpc/eabi/CPragmas.ml
index 4bb7786e..3104cc88 100644
--- a/powerpc/eabi/CPragmas.ml
+++ b/powerpc/eabi/CPragmas.ml
@@ -68,6 +68,8 @@ let _ =
sec_near_access = false}
]
+(* #pragma section *)
+
let process_section_pragma classname istring ustring addrmode accmode =
let old_si =
try Hashtbl.find section_table classname
@@ -85,6 +87,7 @@ let process_section_pragma classname istring ustring addrmode accmode =
else (addrmode = "near-code") || (addrmode = "near-data") } in
Hashtbl.add section_table classname si
+(* #pragma use_section *)
let use_section_table : (AST.ident, section_info) Hashtbl.t =
Hashtbl.create 51
@@ -122,6 +125,19 @@ let define_variable id d =
if is_small !Clflags.option_small_data then "SDATA" else "DATA" in
default_use_section id sect
+(* #pragma reserve_register *)
+
+let process_reserve_register_pragma name =
+ match Machregsaux.register_by_name name with
+ | None ->
+ C2Clight.error "unknown register in `reserve_register' pragma"
+ | Some r ->
+ if Machregsaux.can_reserve_register r then
+ Coloringaux.reserved_registers :=
+ r :: !Coloringaux.reserved_registers
+ else
+ C2Clight.error "cannot reserve this register (not a callee-save)"
+
(* Parsing of pragmas using regexps *)
let re_start_pragma_section = Str.regexp "section\\b"
@@ -144,6 +160,11 @@ let re_pragma_use_section = Str.regexp
let re_split_idents = Str.regexp "[ \t,]+"
+let re_start_pragma_reserve_register = Str.regexp "reserve_register\\b"
+
+let re_pragma_reserve_register = Str.regexp
+ "reserve_register[ \t]+\\([A-Za-z0-9]+\\)"
+
let process_pragma name =
if Str.string_match re_pragma_section name 0 then begin
process_section_pragma
@@ -162,9 +183,13 @@ let process_pragma name =
if identlist = [] then C2Clight.warning "vacuous `use_section' pragma";
List.iter (process_use_section_pragma classname) identlist;
true
- end else if Str.string_match re_start_pragma_use_section name 0 then
- (C2Clight.error "ill-formed `use_section' pragma"; true)
- else
+ end else if Str.string_match re_start_pragma_use_section name 0 then begin
+ C2Clight.error "ill-formed `use_section' pragma"; true
+ end else if Str.string_match re_pragma_reserve_register name 0 then begin
+ process_reserve_register_pragma (Str.matched_group 1 name); true
+ end else if Str.string_match re_start_pragma_reserve_register name 0 then begin
+ C2Clight.error "ill-formed `reserve_register' pragma"; true
+ end else
false
let initialize () =