Patchwork [5/27] Use target structures for init_regs (1)

login
register
mail settings
Submitter Richard Sandiford
Date July 7, 2010, 8:37 p.m.
Message ID <87hbkbuixo.fsf@firetop.home>
Download mbox | patch
Permalink /patch/58168/
State New
Headers show

Comments

Richard Sandiford - July 7, 2010, 8:37 p.m.
This part moves on to the next line of backend_init_target:

      /* This reinitializes hard_frame_pointer, and calls init_reg_modes_target()
         to initialize reg_raw_mode[].  */
      init_emit_regs ();

      /* This invokes target hooks to set fixed_reg[] etc, which is
         mode-dependent.  */
==>   init_regs ();

      /* This depends on stack_pointer_rtx.  */
      init_fake_stack_mems ();

init_regs actually initialises two sets of structures: those defined
in hard-reg-set.h and those defined in regs.h.  This patch deals
with the former group.

Some of the variables have static initialisers.  The patch arranges
for these values to be initialised by init_reg_sets instead (as some
others already are).  The arrays are small.

Richard


gcc/
	* hard-reg-set.h (target_hard_regs): New structure.
	(default_target_hard_regs): Declare.
	(this_target_hard_regs): Declare as a variable or define as a macro.
	(fixed_regs, fixed_reg_set, call_used_regs, call_really_used_regs)
	(call_used_reg_set, call_fixed_reg_set, regs_invalidated_by_call)
	(reg_alloc_order, inv_reg_alloc_order, reg_class_contents)
	(reg_class_size, reg_class_subclasses, reg_class_subunion)
	(reg_class_superunion, reg_names): Redefine as macros.
	* reginfo.c (fixed_regs, fixed_reg_set, call_used_regs)
	(call_used_reg_set, call_really_used_regs, call_fixed_reg_set)
	(regs_invalidated_by_call, reg_alloc_order, inv_reg_alloc_order)
	(reg_class_contents, reg_class_size, reg_class_subclasses)
	(reg_class_subunion, reg_class_superunion, reg_names): Delete.
	(default_target_hard_regs): New variable
	(this_target_hard_regs, initial_call_really_used_regs)
	(initial_reg_alloc_order): New conditional variables.
	(initial_reg_names): New variable.
	(init_reg_sets): Assert that initial_call_really_used_regs,
	initial_reg_alloc_order and initial_reg_names
	are all the same size as their variable counterparts.  Use them to
	initialize those counterparts.
	* target-globals.h (this_target_hard_regs): Declare.
	(target_globals): Add a hard_regs field.
	(restore_target_globals): Copy the hard_regs field to
	this_target_hard_regs.
	* target-globals.c: Include hard-reg-set.h.
	(default_target_globals): Initialize the hard_regs field.
	(save_target_globals): Likewise.

Patch

Index: gcc/hard-reg-set.h
===================================================================
--- gcc/hard-reg-set.h	2010-07-03 22:52:32.000000000 +0100
+++ gcc/hard-reg-set.h	2010-07-03 22:56:39.000000000 +0100
@@ -576,94 +576,116 @@  #define EXECUTE_IF_SET_IN_HARD_REG_SET(S
 /* Define some standard sets of registers.  */
 
 /* Indexed by hard register number, contains 1 for registers
-   that are fixed use (stack pointer, pc, frame pointer, etc.).
-   These are the registers that cannot be used to allocate
-   a pseudo reg whose life does not cross calls.  */
-
-extern char fixed_regs[FIRST_PSEUDO_REGISTER];
-
-/* The same info as a HARD_REG_SET.  */
-
-extern HARD_REG_SET fixed_reg_set;
-
-/* Indexed by hard register number, contains 1 for registers
-   that are fixed use or are clobbered by function calls.
-   These are the registers that cannot be used to allocate
-   a pseudo reg whose life crosses calls.  */
-
-extern char call_used_regs[FIRST_PSEUDO_REGISTER];
-
-#ifdef CALL_REALLY_USED_REGISTERS
-extern char call_really_used_regs[];
-#endif
-
-/* The same info as a HARD_REG_SET.  */
-
-extern HARD_REG_SET call_used_reg_set;
-
-/* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or
-   a function value return register or TARGET_STRUCT_VALUE_RTX or
-   STATIC_CHAIN_REGNUM.  These are the registers that cannot hold quantities
-   across calls even if we are willing to save and restore them.  */
-
-extern HARD_REG_SET call_fixed_reg_set;
-
-/* Indexed by hard register number, contains 1 for registers
    that are being used for global register decls.
    These must be exempt from ordinary flow analysis
    and are also considered fixed.  */
 
 extern char global_regs[FIRST_PSEUDO_REGISTER];
 
-/* Contains 1 for registers that are set or clobbered by calls.  */
-/* ??? Ideally, this would be just call_used_regs plus global_regs, but
-   for someone's bright idea to have call_used_regs strictly include
-   fixed_regs.  Which leaves us guessing as to the set of fixed_regs
-   that are actually preserved.  We know for sure that those associated
-   with the local stack frame are safe, but scant others.  */
-
-extern HARD_REG_SET regs_invalidated_by_call;
-
 /* Call used hard registers which can not be saved because there is no
    insn for this.  */
 
 extern HARD_REG_SET no_caller_save_reg_set;
 
-#ifdef REG_ALLOC_ORDER
-/* Table of register numbers in the order in which to try to use them.  */
-
-extern int reg_alloc_order[FIRST_PSEUDO_REGISTER];
-
-/* The inverse of reg_alloc_order.  */
-
-extern int inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
+struct target_hard_regs {
+  /* Indexed by hard register number, contains 1 for registers
+     that are fixed use (stack pointer, pc, frame pointer, etc.;.
+     These are the registers that cannot be used to allocate
+     a pseudo reg whose life does not cross calls.  */
+  char x_fixed_regs[FIRST_PSEUDO_REGISTER];
+
+  /* The same info as a HARD_REG_SET.  */
+  HARD_REG_SET x_fixed_reg_set;
+
+  /* Indexed by hard register number, contains 1 for registers
+     that are fixed use or are clobbered by function calls.
+     These are the registers that cannot be used to allocate
+     a pseudo reg whose life crosses calls.  */
+  char x_call_used_regs[FIRST_PSEUDO_REGISTER];
+
+  char x_call_really_used_regs[FIRST_PSEUDO_REGISTER];
+
+  /* The same info as a HARD_REG_SET.  */
+  HARD_REG_SET x_call_used_reg_set;
+
+  /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or
+     a function value return register or TARGET_STRUCT_VALUE_RTX or
+     STATIC_CHAIN_REGNUM.  These are the registers that cannot hold quantities
+     across calls even if we are willing to save and restore them.  */
+  HARD_REG_SET x_call_fixed_reg_set;
+
+  /* Contains 1 for registers that are set or clobbered by calls.  */
+  /* ??? Ideally, this would be just call_used_regs plus global_regs, but
+     for someone's bright idea to have call_used_regs strictly include
+     fixed_regs.  Which leaves us guessing as to the set of fixed_regs
+     that are actually preserved.  We know for sure that those associated
+     with the local stack frame are safe, but scant others.  */
+  HARD_REG_SET x_regs_invalidated_by_call;
+
+  /* Table of register numbers in the order in which to try to use them.  */
+  int x_reg_alloc_order[FIRST_PSEUDO_REGISTER];
+
+  /* The inverse of reg_alloc_order.  */
+  int x_inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
+
+  /* For each reg class, a HARD_REG_SET saying which registers are in it.  */
+  HARD_REG_SET x_reg_class_contents[N_REG_CLASSES];
+
+  /* For each reg class, number of regs it contains.  */
+  unsigned int x_reg_class_size[N_REG_CLASSES];
+
+  /* For each reg class, table listing all the classes contained in it.  */
+  enum reg_class x_reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
+
+  /* For each pair of reg classes,
+     a largest reg class contained in their union.  */
+  enum reg_class x_reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];
+
+  /* For each pair of reg classes,
+     the smallest reg class that contains their union.  */
+  enum reg_class x_reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
+
+  /* Vector indexed by hardware reg giving its name.  */
+  const char *x_reg_names[FIRST_PSEUDO_REGISTER];
+};
+
+extern struct target_hard_regs default_target_hard_regs;
+#if SWITCHABLE_TARGET
+extern struct target_hard_regs *this_target_hard_regs;
+#else
+#define this_target_hard_regs (&default_target_hard_regs)
 #endif
 
-/* For each reg class, a HARD_REG_SET saying which registers are in it.  */
-
-extern HARD_REG_SET reg_class_contents[N_REG_CLASSES];
-
-/* For each reg class, number of regs it contains.  */
-
-extern unsigned int reg_class_size[N_REG_CLASSES];
-
-/* For each reg class, table listing all the classes contained in it.  */
-
-extern enum reg_class reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
-
-/* For each pair of reg classes,
-   a largest reg class contained in their union.  */
-
-extern enum reg_class reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];
-
-/* For each pair of reg classes,
-   the smallest reg class that contains their union.  */
-
-extern enum reg_class reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
-
-/* Vector indexed by hardware reg giving its name.  */
-
-extern const char * reg_names[FIRST_PSEUDO_REGISTER];
+#define fixed_regs \
+  (this_target_hard_regs->x_fixed_regs)
+#define fixed_reg_set \
+  (this_target_hard_regs->x_fixed_reg_set)
+#define call_used_regs \
+  (this_target_hard_regs->x_call_used_regs)
+#define call_really_used_regs \
+  (this_target_hard_regs->x_call_really_used_regs)
+#define call_used_reg_set \
+  (this_target_hard_regs->x_call_used_reg_set)
+#define call_fixed_reg_set \
+  (this_target_hard_regs->x_call_fixed_reg_set)
+#define regs_invalidated_by_call \
+  (this_target_hard_regs->x_regs_invalidated_by_call)
+#define reg_alloc_order \
+  (this_target_hard_regs->x_reg_alloc_order)
+#define inv_reg_alloc_order \
+  (this_target_hard_regs->x_inv_reg_alloc_order)
+#define reg_class_contents \
+  (this_target_hard_regs->x_reg_class_contents)
+#define reg_class_size \
+  (this_target_hard_regs->x_reg_class_size)
+#define reg_class_subclasses \
+  (this_target_hard_regs->x_reg_class_subclasses)
+#define reg_class_subunion \
+  (this_target_hard_regs->x_reg_class_subunion)
+#define reg_class_superunion \
+  (this_target_hard_regs->x_reg_class_superunion)
+#define reg_names \
+  (this_target_hard_regs->x_reg_names)
 
 /* Vector indexed by reg class giving its name.  */
 
Index: gcc/reginfo.c
===================================================================
--- gcc/reginfo.c	2010-07-03 22:52:32.000000000 +0100
+++ gcc/reginfo.c	2010-07-03 22:56:39.000000000 +0100
@@ -58,44 +58,22 @@  Software Foundation; either version 3, o
 int max_regno;
 
 
+struct target_hard_regs default_target_hard_regs;
 struct target_regs default_target_regs;
 #if SWITCHABLE_TARGET
+struct target_hard_regs *this_target_hard_regs = &default_target_hard_regs;
 struct target_regs *this_target_regs = &default_target_regs;
 #endif
 
-/* Register tables used by many passes.  */
-
-/* Indexed by hard register number, contains 1 for registers
-   that are fixed use (stack pointer, pc, frame pointer, etc.).
-   These are the registers that cannot be used to allocate
-   a pseudo reg for general use.  */
-char fixed_regs[FIRST_PSEUDO_REGISTER];
-
-/* Same info as a HARD_REG_SET.  */
-HARD_REG_SET fixed_reg_set;
-
-/* Data for initializing the above.  */
+/* Data for initializing fixed_regs.  */
 static const char initial_fixed_regs[] = FIXED_REGISTERS;
 
-/* Indexed by hard register number, contains 1 for registers
-   that are fixed use or are clobbered by function calls.
-   These are the registers that cannot be used to allocate
-   a pseudo reg whose life crosses calls unless we are able
-   to save/restore them across the calls.  */
-char call_used_regs[FIRST_PSEUDO_REGISTER];
-
-/* Same info as a HARD_REG_SET.  */
-HARD_REG_SET call_used_reg_set;
-
-/* Data for initializing the above.  */
+/* Data for initializing call_used_regs.  */
 static const char initial_call_used_regs[] = CALL_USED_REGISTERS;
 
-/* This is much like call_used_regs, except it doesn't have to
-   be a superset of FIXED_REGISTERS. This vector indicates
-   what is really call clobbered, and is used when defining
-   regs_invalidated_by_call.  */
 #ifdef CALL_REALLY_USED_REGISTERS
-char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
+/* Data for initializing call_really_used_regs.  */
+static const char initial_call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
 #endif
 
 #ifdef CALL_REALLY_USED_REGISTERS
@@ -104,28 +82,12 @@  #define CALL_REALLY_USED_REGNO_P(X)  cal
 #define CALL_REALLY_USED_REGNO_P(X)  call_used_regs[X]
 #endif
 
-
-/* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or
-   a function value return register or TARGET_STRUCT_VALUE_RTX or
-   STATIC_CHAIN_REGNUM.  These are the registers that cannot hold quantities
-   across calls even if we are willing to save and restore them.  */
-
-HARD_REG_SET call_fixed_reg_set;
-
 /* Indexed by hard register number, contains 1 for registers
    that are being used for global register decls.
    These must be exempt from ordinary flow analysis
    and are also considered fixed.  */
 char global_regs[FIRST_PSEUDO_REGISTER];
 
-/* Contains 1 for registers that are set or clobbered by calls.  */
-/* ??? Ideally, this would be just call_used_regs plus global_regs, but
-   for someone's bright idea to have call_used_regs strictly include
-   fixed_regs.  Which leaves us guessing as to the set of fixed_regs
-   that are actually preserved.  We know for sure that those associated
-   with the local stack frame are safe, but scant others.  */
-HARD_REG_SET regs_invalidated_by_call;
-
 /* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used
    in dataflow more conveniently.  */
 regset regs_invalidated_by_call_regset;
@@ -134,17 +96,11 @@  #define CALL_REALLY_USED_REGNO_P(X)  cal
    should not be reset after each function is compiled.  */
 static bitmap_obstack persistent_obstack;
 
-/* Table of register numbers in the order in which to try to use them.  */
+/* Used to initialize reg_alloc_order.  */
 #ifdef REG_ALLOC_ORDER
-int reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
-
-/* The inverse of reg_alloc_order.  */
-int inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
+static int initial_reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
 #endif
 
-/* For each reg class, a HARD_REG_SET saying which registers are in it.  */
-HARD_REG_SET reg_class_contents[N_REG_CLASSES];
-
 /* The same information, but as an array of unsigned ints.  We copy from
    these unsigned ints to the table above.  We do this so the tm.h files
    do not have to be aware of the wordsize for machines with <= 64 regs.
@@ -155,22 +111,8 @@  #define N_REG_INTS  \
 static const unsigned int_reg_class_contents[N_REG_CLASSES][N_REG_INTS]
   = REG_CLASS_CONTENTS;
 
-/* For each reg class, number of regs it contains.  */
-unsigned int reg_class_size[N_REG_CLASSES];
-
-/* For each reg class, table listing all the classes contained in it.  */
-enum reg_class reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
-
-/* For each pair of reg classes,
-   a largest reg class contained in their union.  */
-enum reg_class reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];
-
-/* For each pair of reg classes,
-   the smallest reg class containing their union.  */
-enum reg_class reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
-
 /* Array containing all of the register names.  */
-const char * reg_names[] = REGISTER_NAMES;
+static const char *const initial_reg_names[] = REGISTER_NAMES;
 
 /* Array containing all of the register class names.  */
 const char * reg_class_names[] = REG_CLASS_NAMES;
@@ -246,9 +188,25 @@  init_reg_sets (void)
      CALL_USED_REGISTERS had the right number of initializers.  */
   gcc_assert (sizeof fixed_regs == sizeof initial_fixed_regs);
   gcc_assert (sizeof call_used_regs == sizeof initial_call_used_regs);
+#ifdef CALL_REALLY_USED_REGISTERS
+  gcc_assert (sizeof call_really_used_regs
+	      == sizeof initial_call_really_used_regs);
+#endif
+#ifdef REG_ALLOC_ORDER
+  gcc_assert (sizeof reg_alloc_order == sizeof initial_reg_alloc_order);
+#endif
+  gcc_assert (sizeof reg_names == sizeof initial_reg_names);
 
   memcpy (fixed_regs, initial_fixed_regs, sizeof fixed_regs);
   memcpy (call_used_regs, initial_call_used_regs, sizeof call_used_regs);
+#ifdef CALL_REALLY_USED_REGISTERS
+  memcpy (call_really_used_regs, initial_call_really_used_regs,
+	  sizeof call_really_used_regs);
+#endif
+#ifdef REG_ALLOC_ORDER
+  memcpy (reg_alloc_order, initial_reg_alloc_order, sizeof reg_alloc_order);
+#endif
+  memcpy (reg_names, initial_reg_names, sizeof reg_names);
   memset (global_regs, 0, sizeof global_regs);
 }
 
Index: gcc/target-globals.h
===================================================================
--- gcc/target-globals.h	2010-07-03 22:52:32.000000000 +0100
+++ gcc/target-globals.h	2010-07-03 22:56:39.000000000 +0100
@@ -24,11 +24,13 @@  #define TARGET_GLOBALS_H 1
 extern struct target_flag_state *this_target_flag_state;
 extern struct target_rtl *this_target_rtl;
 extern struct target_regs *this_target_regs;
+extern struct target_hard_regs *this_target_hard_regs;
 
 struct GTY(()) target_globals {
   struct target_flag_state *GTY((skip)) flag_state;
   struct target_rtl *rtl;
   struct target_regs *GTY((skip)) regs;
+  struct target_hard_regs *GTY((skip)) hard_regs;
 };
 
 extern struct target_globals default_target_globals;
@@ -41,6 +43,7 @@  restore_target_globals (struct target_gl
   this_target_flag_state = g->flag_state;
   this_target_rtl = g->rtl;
   this_target_regs = g->regs;
+  this_target_hard_regs = g->hard_regs;
 }
 #endif
 
Index: gcc/target-globals.c
===================================================================
--- gcc/target-globals.c	2010-07-03 22:52:32.000000000 +0100
+++ gcc/target-globals.c	2010-07-03 22:56:39.000000000 +0100
@@ -28,12 +28,14 @@  Software Foundation; either version 3, o
 #include "flags.h"
 #include "rtl.h"
 #include "regs.h"
+#include "hard-reg-set.h"
 
 #if SWITCHABLE_TARGET
 struct target_globals default_target_globals = {
   &default_target_flag_state,
   &default_target_rtl,
-  &default_target_regs
+  &default_target_regs,
+  &default_target_hard_regs
 };
 
 struct target_globals *
@@ -45,6 +47,7 @@  save_target_globals (void)
   g->flag_state = XCNEW (struct target_flag_state);
   g->rtl = ggc_alloc_cleared_target_rtl ();
   g->regs = XCNEW (struct target_regs);
+  g->hard_regs = XCNEW (struct target_hard_regs);
   restore_target_globals (g);
   target_reinit ();
   return g;