This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Hookize ALLOCATE_INITIAL_VALUE


Hi,

The attached patch is to hookize ALLOCATE_INITIAL_VALUE which
is used only by SH, ATM.  It's suggested by Giovanni Bajo in
http://gcc.gnu.org/ml/gcc-patches/2005-06/msg01655.html.

Tested on i686-pc-linux-gnu and sh4-unknown-linux-gnu with full
bootstrap, "make -k check" at the top level, "make info" and
"make dvi" with no new failures.  For sh4-unknown-linux-gnu,
I need http://gcc.gnu.org/ml/gcc-patches/2005-06/msg01722.html
which isn't reviewed yet to workaround the bootstrap failure
on mainline.

Regards,
	kaz
--
2005-06-26  Kaz Kojima  <kkojima@gcc.gnu.org>

	* target.h (gcc_target): New field allocate_initial_value.
	* target-def.h (TARGET_ALLOCATE_INITIAL_VALUE): New macro.
	(TARGET_INITIALIZER): Include it.
	* integrate.c (allocate_initial_values): Use
	targetm.allocate_initial_value.
	* config/sh/sh-protos.h (sh_pr_n_sets): Delete.
	* config/sh/sh.c (sh_pr_n_sets): Make it static.
	(sh_allocate_initila_value): New function.
	(TARGET_ALLOCATE_INITIAL_VALUE): Override default.
	* config/sh/sh.h (ALLOCATE_INITIAL_VALUE): Delete.
	* doc/tm.texi (TARGET_ALLOCATE_INITIAL_VALUE): Rename and
	update from ALLOCATE_INITIAL_VALUE.

diff -uprN ORIG/gcc/gcc/target-def.h LOCAL/gcc/gcc/target-def.h
--- ORIG/gcc/gcc/target-def.h	2005-06-10 09:11:28.000000000 +0900
+++ LOCAL/gcc/gcc/target-def.h	2005-06-23 09:22:37.000000000 +0900
@@ -357,6 +357,7 @@ Foundation, 59 Temple Place - Suite 330,
 #define TARGET_ALIGN_ANON_BITFIELD hook_bool_void_false
 #define TARGET_RTX_COSTS hook_bool_rtx_int_int_intp_false
 #define TARGET_MANGLE_FUNDAMENTAL_TYPE hook_constcharptr_tree_null
+#define TARGET_ALLOCATE_INITIAL_VALUE NULL
 
 #ifndef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS hook_void_void
@@ -549,6 +550,7 @@ Foundation, 59 Temple Place - Suite 330,
   TARGET_VECTOR_OPAQUE_P,			\
   TARGET_RTX_COSTS,				\
   TARGET_ADDRESS_COST,				\
+  TARGET_ALLOCATE_INITIAL_VALUE,		\
   TARGET_DWARF_REGISTER_SPAN,                   \
   TARGET_FIXED_CONDITION_CODE_REGS,		\
   TARGET_CC_MODES_COMPATIBLE,			\
diff -uprN ORIG/gcc/gcc/target.h LOCAL/gcc/gcc/target.h
--- ORIG/gcc/gcc/target.h	2005-06-10 09:11:28.000000000 +0900
+++ LOCAL/gcc/gcc/target.h	2005-06-23 09:24:15.000000000 +0900
@@ -443,6 +443,10 @@ struct gcc_target
      invalid addresses.  */
   int (* address_cost) (rtx x);
 
+  /* Return where to allocate pseudo for a given hard register initial
+     value.  */
+  rtx (* allocate_initial_value) (rtx x);
+
   /* Given a register, this hook should return a parallel of registers
      to represent where to find the register pieces.  Define this hook
      if the register and its mode are represented in Dwarf in
diff -uprN ORIG/gcc/gcc/integrate.c LOCAL/gcc/gcc/integrate.c
--- ORIG/gcc/gcc/integrate.c	2005-06-20 10:55:08.000000000 +0900
+++ LOCAL/gcc/gcc/integrate.c	2005-06-23 09:21:14.000000000 +0900
@@ -376,47 +376,50 @@ emit_initial_value_sets (void)
 void
 allocate_initial_values (rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED)
 {
-#ifdef ALLOCATE_INITIAL_VALUE
-  struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
-  int i;
-
-  if (ivs == 0)
-    return;
-
-  for (i = 0; i < ivs->num_entries; i++)
+  if (targetm.allocate_initial_value)
     {
-      int regno = REGNO (ivs->entries[i].pseudo);
-      rtx x = ALLOCATE_INITIAL_VALUE (ivs->entries[i].hard_reg);
+      struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
+      int i;
 
-      if (x && REG_N_SETS (REGNO (ivs->entries[i].pseudo)) <= 1)
+      if (ivs == 0)
+	return;
+
+      for (i = 0; i < ivs->num_entries; i++)
 	{
-	  if (MEM_P (x))
-	    reg_equiv_memory_loc[regno] = x;
-	  else
+	  int regno = REGNO (ivs->entries[i].pseudo);
+	  rtx x = targetm.allocate_initial_value (ivs->entries[i].hard_reg);
+  
+	  if (x && REG_N_SETS (REGNO (ivs->entries[i].pseudo)) <= 1)
 	    {
-	      basic_block bb;
-	      int new_regno;
-
-	      gcc_assert (REG_P (x));
-	      new_regno = REGNO (x);
-	      reg_renumber[regno] = new_regno;
-	      /* Poke the regno right into regno_reg_rtx so that even
-	     	 fixed regs are accepted.  */
-	      REGNO (ivs->entries[i].pseudo) = new_regno;
-	      /* Update global register liveness information.  */
-	      FOR_EACH_BB (bb)
+	      if (MEM_P (x))
+		reg_equiv_memory_loc[regno] = x;
+	      else
 		{
-		  struct rtl_bb_info *info = bb->il.rtl;
+		  basic_block bb;
+		  int new_regno;
 
-		  if (REGNO_REG_SET_P(info->global_live_at_start, regno))
-		    SET_REGNO_REG_SET (info->global_live_at_start, new_regno);
-		  if (REGNO_REG_SET_P(info->global_live_at_end, regno))
-		    SET_REGNO_REG_SET (info->global_live_at_end, new_regno);
+		  gcc_assert (REG_P (x));
+		  new_regno = REGNO (x);
+		  reg_renumber[regno] = new_regno;
+		  /* Poke the regno right into regno_reg_rtx so that even
+		     fixed regs are accepted.  */
+		  REGNO (ivs->entries[i].pseudo) = new_regno;
+		  /* Update global register liveness information.  */
+		  FOR_EACH_BB (bb)
+		    {
+		      struct rtl_bb_info *info = bb->il.rtl;
+
+		      if (REGNO_REG_SET_P(info->global_live_at_start, regno))
+			SET_REGNO_REG_SET (info->global_live_at_start,
+					   new_regno);
+		      if (REGNO_REG_SET_P(info->global_live_at_end, regno))
+			SET_REGNO_REG_SET (info->global_live_at_end,
+					   new_regno);
+		    }
 		}
 	    }
 	}
     }
-#endif
 }
 
 #include "gt-integrate.h"
diff -uprN ORIG/gcc/gcc/config/sh/sh-protos.h LOCAL/gcc/gcc/config/sh/sh-protos.h
--- ORIG/gcc/gcc/config/sh/sh-protos.h	2005-06-02 13:12:08.000000000 +0900
+++ LOCAL/gcc/gcc/config/sh/sh-protos.h	2005-06-23 08:32:41.000000000 +0900
@@ -132,7 +132,6 @@ extern int sh_need_epilogue (void);
 extern void sh_set_return_address (rtx, rtx);
 extern int initial_elimination_offset (int, int);
 extern int fldi_ok (void);
-extern int sh_pr_n_sets (void);
 extern int sh_hard_regno_rename_ok (unsigned int, unsigned int);
 extern int sh_cfun_interrupt_handler_p (void);
 extern int sh_attr_renesas_p (tree);
diff -uprN ORIG/gcc/gcc/config/sh/sh.c LOCAL/gcc/gcc/config/sh/sh.c
--- ORIG/gcc/gcc/config/sh/sh.c	2005-06-03 09:31:18.000000000 +0900
+++ LOCAL/gcc/gcc/config/sh/sh.c	2005-06-23 09:32:07.000000000 +0900
@@ -271,6 +271,8 @@ static int sh_address_cost (rtx);
 #ifdef TARGET_ADJUST_UNROLL_MAX
 static int sh_adjust_unroll_max (struct loop *, int, int, int, int);
 #endif
+static int sh_pr_n_sets (void);
+static rtx sh_allocate_initial_value (rtx);
 static int shmedia_target_regs_stack_space (HARD_REG_SET *);
 static int shmedia_reserve_space_for_target_registers_p (int, HARD_REG_SET *);
 static int shmedia_target_regs_stack_adjust (HARD_REG_SET *);
@@ -422,6 +424,8 @@ static int hard_regs_intersect_p (HARD_R
 #define TARGET_RTX_COSTS sh_rtx_costs
 #undef TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST sh_address_cost
+#undef TARGET_ALLOCATE_INITIAL_VALUE
+#define TARGET_ALLOCATE_INITIAL_VALUE sh_allocate_initial_value
 
 #undef TARGET_MACHINE_DEPENDENT_REORG
 #define TARGET_MACHINE_DEPENDENT_REORG sh_reorg
@@ -8348,16 +8352,41 @@ flow_dependent_p_1 (rtx x, rtx pat ATTRI
     *pinsn = NULL_RTX;
 }
 
-/* For use by ALLOCATE_INITIAL_VALUE.  Note that sh.md contains some
+/* For use by sh_allocate_initial_value.  Note that sh.md contains some
    'special function' patterns (type sfunc) that clobber pr, but that
    do not look like function calls to leaf_function_p.  Hence we must
    do this extra check.  */
-int
+static int
 sh_pr_n_sets (void)
 {
   return REG_N_SETS (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG);
 }
 
+/* Return where to allocate pseudo for a given hard register initial
+   value.  */
+static rtx
+sh_allocate_initial_value (rtx hard_reg)
+{
+  rtx x;
+
+  if (REGNO (hard_reg) == (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG))
+    {
+      if (current_function_is_leaf
+	  && ! sh_pr_n_sets ()
+	  && ! (TARGET_SHCOMPACT
+		&& ((current_function_args_info.call_cookie
+		     & ~ CALL_COOKIE_RET_TRAMP (1))
+		    || current_function_has_nonlocal_label)))
+	x = hard_reg;
+      else
+	x = gen_rtx_MEM (Pmode, return_address_pointer_rtx);
+    }
+  else
+    x = NULL_RTX;
+
+  return x;
+}
+
 /* This function returns "2" to indicate dual issue for the SH4
    processor.  To be used by the DFA pipeline description.  */
 static int
@@ -9592,6 +9621,8 @@ sh_output_mi_thunk (FILE *file, tree thu
 
   if (optimize > 0 && flag_schedule_insns_after_reload)
     {
+      basic_block bb;
+
       /* Initialize the bitmap obstacks.  */
       bitmap_obstack_initialize (NULL);
       bitmap_obstack_initialize (&reg_obstack);
diff -uprN ORIG/gcc/gcc/config/sh/sh.h LOCAL/gcc/gcc/config/sh/sh.h
--- ORIG/gcc/gcc/config/sh/sh.h	2005-06-03 09:31:18.000000000 +0900
+++ LOCAL/gcc/gcc/config/sh/sh.h	2005-06-23 08:22:25.000000000 +0900
@@ -3360,18 +3360,6 @@ extern struct rtx_def *sp_switch;
 2:\n" TEXT_SECTION_ASM_OP);
 #endif /* (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__ */
 
-#define ALLOCATE_INITIAL_VALUE(hard_reg) \
-  (REGNO (hard_reg) == (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG) \
-   ? (current_function_is_leaf \
-      && ! sh_pr_n_sets () \
-      && ! (TARGET_SHCOMPACT \
-	    && ((current_function_args_info.call_cookie \
-		 & ~ CALL_COOKIE_RET_TRAMP (1)) \
-		|| current_function_has_nonlocal_label)) \
-      ? (hard_reg) \
-      : gen_rtx_MEM (Pmode, return_address_pointer_rtx)) \
-   : NULL_RTX)
-
 #define SIMULTANEOUS_PREFETCHES 2
 
 /* FIXME: middle-end support for highpart optimizations is missing.  */
diff -uprN ORIG/gcc/gcc/doc/tm.texi LOCAL/gcc/gcc/doc/tm.texi
--- ORIG/gcc/gcc/doc/tm.texi	2005-06-10 09:11:46.000000000 +0900
+++ LOCAL/gcc/gcc/doc/tm.texi	2005-06-24 08:13:55.000000000 +0900
@@ -9400,14 +9400,14 @@ filling of delay slots can result in bra
 may in turn cause a branch offset to overflow.
 @end defmac
 
-@defmac ALLOCATE_INITIAL_VALUE (@var{hard_reg})
+@deftypefn {Target Hook} rtx TARGET_ALLOCATE_INITIAL_VALUE (rtx @var{hard_reg})
 
 When the initial value of a hard register has been copied in a pseudo
 register, it is often not necessary to actually allocate another register
 to this pseudo register, because the original hard register or a stack slot
-it has been saved into can be used.  @code{ALLOCATE_INITIAL_VALUE}, if
-defined, is called at the start of register allocation once for each
-hard register that had its initial value copied by using
+it has been saved into can be used.  @code{TARGET_ALLOCATE_INITIAL_VALUE}
+is called at the start of register allocation once for each hard register
+that had its initial value copied by using
 @code{get_func_hard_reg_initial_val} or @code{get_hard_reg_initial_val}.
 Possible values are @code{NULL_RTX}, if you don't want
 to do any special allocation, a @code{REG} rtx---that would typically be
@@ -9415,10 +9415,12 @@ the hard register itself, if it is known
 @code{MEM}.
 If you are returning a @code{MEM}, this is only a hint for the allocator;
 it might decide to use another register anyways.
-You may use @code{current_function_leaf_function} in the definition of the
-macro, functions that use @code{REG_N_SETS}, to determine if the hard
+You may use @code{current_function_leaf_function} in the hook, functions
+that use @code{REG_N_SETS}, to determine if the hard
 register in question will not be clobbered.
-@end defmac
+The default value of this hook is @code{NULL}, which disables any special
+allocation.
+@end deftypefn
 
 @defmac TARGET_OBJECT_SUFFIX
 Define this macro to be a C string representing the suffix for object


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]