Alternate patch for PR 23868 (fixes IA64, not other platforms)

Steve Ellcey sje@cup.hp.com
Mon Aug 21 17:57:00 GMT 2006


There has been a patch for PR 23868 that has been out there for a while:

	http://gcc.gnu.org/ml/gcc-patches/2005-08/msg00129.html

by Joern Rennecke but it has not been approved.  That patch target-izes
apply_result_mode and fixes some platforms but does not completely fix
IA64.  To fix IA64 we would need to targetize apply_args_mode as well.

The original change that caused this failure (at least on ia64) was a
change in how the reg_raw_mode array was initialized so here is a
different patch that, instead of targetizing apply_result_mode and
apply_args_mode, targetizes choose_hard_reg_mode in order to get
reg_raw_mode inialized to better values.  I also created an IA64
specific version of choose_hard_reg_mode which fixes the failure of
builtin_apply4.c on that target.  As a side benefit on IA64, I was able
to get rid of the use of the HARD_REGNO_CALLER_SAVE_MODE macro.  I think
that if we created a specialized version of choose_hard_reg_mode for
i386, we could get rid of it from that directory too.

Anyway, is there any chance that someone could look over this patch and
approve either this approach or the original patch?

Tested on IA64 HP-UX and Linux.

Steve Ellcey
sje@cup.hp.com



2006-08-21  Steve Ellcey  <sje@cup.hp.com>

	* doc/tm.texi (TARGET_CHOOSE_HARD_REG_MODE): New.
	* targhooks.h (default_choose_hard_reg_mode): New.
	* target-def.h (TARGET_CHOOSE_HARD_REG_MODE): New.
	* target.h (choose_hard_reg_mode): New.
	* rtl.h (choose_hard_reg_mode): Rename to default_choose_hard_reg_mode.
	* regs.h (HARD_REGNO_CALLER_SAVE_MODE): Use
	targetm.choose_hard_reg_mode.
	* caller-save.c (init_reg_modes_once): Ditto.
	* dwarf2out.c (expand_builtin_init_dwarf_reg_sizes): Ditto.
	* config/i386/i386.h (HARD_REGNO_CALLER_SAVE_MODE): Ditto.
	* config/ia64/ia64.h (HARD_REGNO_CALLER_SAVE_MODE): Remove.
	* config/ia64/ia64.c (ia64_choose_hard_reg_mode): New.
	(TARGET_CHOOSE_HARD_REG_MODE): Set to ia64_choose_hard_reg_mode.


Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 116256)
+++ doc/tm.texi	(working copy)
@@ -4585,6 +4585,16 @@ The default version of this hook invokes
 normally defined in @file{libgcc2.c}.
 @end deftypefn
 
+@deftypefn {Target Hook} enum machine_mode TARGET_CHOOSE_HARD_REG_MODE (unsigned int regno, unsigned int nregs, bool call_saved)
+This hook returns a mode that is legitimate for hard reg REGNO and large
+enough to save nregs.  If we can't find one, return VOIDmode.  If
+CALL_SAVED is true, only consider modes that are call saved
+
+The default version of this hook invokes a function called
+@samp{default_choose_hard_reg_mode}.  This function is defined in
+@file{regclass.c}.
+@end deftypefn
+
 @node Varargs
 @section Implementing the Varargs Macros
 @cindex varargs implementation


Index: targhooks.h
===================================================================
--- targhooks.h	(revision 116256)
+++ targhooks.h	(working copy)
@@ -77,4 +77,6 @@ extern rtx default_internal_arg_pointer 
 extern enum reg_class default_secondary_reload (bool, rtx, enum reg_class,
 						enum machine_mode,
 						secondary_reload_info *);
+extern enum machine_mode default_choose_hard_reg_mode
+  (unsigned int regno ATTRIBUTE_UNUSED, unsigned int nregs, bool call_saved);
 extern void hook_void_bitmap (bitmap);


Index: target-def.h
===================================================================
--- target-def.h	(revision 116256)
+++ target-def.h	(working copy)
@@ -535,6 +535,10 @@ Foundation, 51 Franklin Street, Fifth Fl
 #define TARGET_SECONDARY_RELOAD default_secondary_reload
 #endif
 
+#ifndef TARGET_CHOOSE_HARD_REG_MODE
+#define TARGET_CHOOSE_HARD_REG_MODE default_choose_hard_reg_mode
+#endif
+
 
 /* C++ specific.  */
 #ifndef TARGET_CXX_GUARD_TYPE
@@ -673,6 +677,7 @@ Foundation, 51 Franklin Street, Fifth Fl
   TARGET_INVALID_UNARY_OP,			\
   TARGET_INVALID_BINARY_OP,			\
   TARGET_SECONDARY_RELOAD,			\
+  TARGET_CHOOSE_HARD_REG_MODE,			\
   TARGET_CXX,					\
   TARGET_EXTRA_LIVE_ON_ENTRY,                    \
   TARGET_UNWIND_TABLES_DEFAULT,			\


Index: target.h
===================================================================
--- target.h	(revision 116256)
+++ target.h	(working copy)
@@ -738,6 +738,14 @@ struct gcc_target
 				      enum machine_mode,
 				      struct secondary_reload_info *);
 
+  /* Return a machine mode that is legitimate for hard reg REGNO and large
+     enough to save nregs.  If we can't find one, return VOIDmode.
+     If CALL_SAVED is true, only consider modes that are call saved.  */
+
+  enum machine_mode (*choose_hard_reg_mode) (unsigned int regno,
+					     unsigned int nregs,
+					     bool call_saved);
+
   /* Functions specific to the C++ frontend.  */
   struct cxx {
     /* Return the integer type used for guard variables.  */


Index: rtl.h
===================================================================
--- rtl.h	(revision 116256)
+++ rtl.h	(working copy)
@@ -1652,8 +1652,9 @@ extern bool constant_pool_reference_p (r
 extern bool mode_signbit_p (enum machine_mode, rtx);
 
 /* In regclass.c  */
-extern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
-					       bool);
+extern enum machine_mode default_choose_hard_reg_mode (unsigned int,
+						       unsigned int,
+						       bool);
 
 /* In emit-rtl.c  */
 extern rtx set_unique_reg_note (rtx, enum reg_note, rtx);


Index: regs.h
===================================================================
--- regs.h	(revision 116256)
+++ regs.h	(working copy)
@@ -225,7 +225,7 @@ extern int caller_save_needed;
 /* Select a register mode required for caller save of hard regno REGNO.  */
 #ifndef HARD_REGNO_CALLER_SAVE_MODE
 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
-  choose_hard_reg_mode (REGNO, NREGS, false)
+  targetm.choose_hard_reg_mode (REGNO, NREGS, false)
 #endif
 
 /* Registers that get partially clobbered by a call in a given mode.


Index: caller-save.c
===================================================================
--- caller-save.c	(revision 116256)
+++ caller-save.c	(working copy)
@@ -36,6 +36,7 @@ Software Foundation, 51 Franklin Street,
 #include "toplev.h"
 #include "tm_p.h"
 #include "addresses.h"
+#include "target.h"
 
 #ifndef MAX_MOVE_MAX
 #define MAX_MOVE_MAX MOVE_MAX


Index: regclass.c
===================================================================
--- regclass.c	(revision 116256)
+++ regclass.c	(working copy)
@@ -559,7 +559,7 @@ init_reg_modes_once (void)
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
-      reg_raw_mode[i] = choose_hard_reg_mode (i, 1, false);
+      reg_raw_mode[i] = targetm.choose_hard_reg_mode (i, 1, false);
 
       /* If we couldn't find a valid mode, just use the previous mode.
          ??? One situation in which we need to do this is on the mips where
@@ -642,7 +642,7 @@ memory_move_secondary_cost (enum machine
    If CALL_SAVED is true, only consider modes that are call saved.  */
 
 enum machine_mode
-choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
+default_choose_hard_reg_mode (unsigned int regno,
 		      unsigned int nregs, bool call_saved)
 {
   unsigned int /* enum machine_mode */ m;


Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 116256)
+++ dwarf2out.c	(working copy)
@@ -464,7 +464,7 @@ expand_builtin_init_dwarf_reg_sizes (tre
 	  HOST_WIDE_INT size;
 	  
 	  if (HARD_REGNO_CALL_PART_CLOBBERED (i, save_mode))
-	    save_mode = choose_hard_reg_mode (i, 1, true);
+	    save_mode = targetm.choose_hard_reg_mode (i, 1, true);
 	  if (DWARF_FRAME_REGNUM (i) == DWARF_FRAME_RETURN_COLUMN)
 	    {
 	      if (save_mode == VOIDmode)


Index: config/i386/i386.h
===================================================================
--- config/i386/i386.h	(revision 116256)
+++ config/i386/i386.h	(working copy)
@@ -916,7 +916,7 @@ do {									\
 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE)			\
   (CC_REGNO_P (REGNO) ? VOIDmode					\
    : (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode			\
-   : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), false)\
+   : (MODE) == VOIDmode ? targetm.choose_hard_reg_mode ((REGNO), (NREGS), false)\
    : (MODE) == HImode && !TARGET_PARTIAL_REG_STALL ? SImode		\
    : (MODE) == QImode && (REGNO) >= 4 && !TARGET_64BIT ? SImode 	\
    : (MODE))


Index: config/ia64/ia64.h
===================================================================
--- config/ia64/ia64.h	(revision 116256)
+++ config/ia64/ia64.h	(working copy)
@@ -677,13 +677,6 @@ while (0)
    && ((((MODE1) == XFmode) || ((MODE1) == XCmode))	\
        == (((MODE2) == XFmode) || ((MODE2) == XCmode)))	\
    && (((MODE1) == BImode) == ((MODE2) == BImode)))
-
-/* Specify the modes required to caller save a given hard regno.
-   We need to ensure floating pt regs are not saved as DImode.  */
-
-#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
-  ((FR_REGNO_P (REGNO) && (NREGS) == 1) ? XFmode        \
-   : choose_hard_reg_mode ((REGNO), (NREGS), false))
 
 /* Handling Leaf Functions */
 


Index: config/ia64/ia64.c
===================================================================
--- config/ia64/ia64.c	(revision 116256)
+++ config/ia64/ia64.c	(working copy)
@@ -279,6 +279,9 @@ static const char *ia64_mangle_fundament
 static const char *ia64_invalid_conversion (tree, tree);
 static const char *ia64_invalid_unary_op (int, tree);
 static const char *ia64_invalid_binary_op (int, tree, tree);
+static enum machine_mode ia64_choose_hard_reg_mode (unsigned int regno,
+						    unsigned int nregs,
+						    bool call_saved);
 
 /* Table of valid machine attributes.  */
 static const struct attribute_spec ia64_attribute_table[] =
@@ -476,6 +479,8 @@ static const struct attribute_spec ia64_
 #define TARGET_INVALID_UNARY_OP ia64_invalid_unary_op
 #undef TARGET_INVALID_BINARY_OP
 #define TARGET_INVALID_BINARY_OP ia64_invalid_binary_op
+#undef TARGET_CHOOSE_HARD_REG_MODE
+#define TARGET_CHOOSE_HARD_REG_MODE ia64_choose_hard_reg_mode
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
@@ -9757,6 +9762,24 @@ ia64_optimization_options (int level ATT
 {
   /* Let the scheduler form additional regions.  */
   set_param_value ("max-sched-extend-regions-iters", 2);
+}
+
+static enum machine_mode
+ia64_choose_hard_reg_mode (unsigned int regno, unsigned int nregs,
+			   bool call_saved)
+{
+  gcc_assert (nregs == 1 || (nregs == 2 && PR_REGNO_P (regno)));
+
+  if (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+    {
+      if (GR_REGNO_P (regno) || BR_REGNO_P (regno))
+	return DImode;
+      if (FR_REGNO_P (regno))
+	return XFmode;
+      if (PR_REGNO_P (regno))
+	return (nregs == 1) ? CCmode : BImode;
+     }
+  return VOIDmode;
 }
 
 #include "gt-ia64.h"



More information about the Gcc-patches mailing list