Patchwork Hookize PREFERRED_OUTPUT_RELOAD_CLASS

login
register
mail settings
Submitter Anatoly Sokolov
Date Oct. 15, 2010, 5:31 p.m.
Message ID <769948200.20101015213124@post.ru>
Download mbox | patch
Permalink /patch/67986/
State New
Headers show

Comments

Anatoly Sokolov - Oct. 15, 2010, 5:31 p.m.
Hello.

  This patch turns PREFERRED_OUTPUT_RELOAD_CLASS macro into a hook.

  The patch has been bootstrapped on and regression tested on
x86_64-unknown-linux-gnu for c.

  This patch is pre-approved and should be committed within a week if no
objections.

        * target.def (preferred_output_reload_class): New hook.
        * doc/tm.texi.in (TARGET_PREFERRED_OUTPUT_RELOAD_CLASS): Document.
        * doc/tm.texi: Regenerate.
        * targhooks.c (default_preferred_output_reload_class): New function.
        * targhooks.h (default_preferred_output_reload_class): Declare.
        * reload.c (find_dummy_reload): Change rclass argument type from 
        enum reg_class to reg_class_t. Change this_alternative array type
        from enum reg_class to reg_class_t.
        Use TARGET_PREFERRED_OUTPUT_RELOAD_CLASS target hook.
        (push_reload): Change preferred_class variable type to reg_class_t.
        Use TARGET_PREFERRED_OUTPUT_RELOAD_CLASS target hook.
        * recog.c (reg_fits_class_p): Change result type to bool. Change cl
        argument type from enum reg_class to reg_class_t. Use
        HARD_REGISTER_NUM_P predicate.
        * recog.h (reg_fits_class_p): Update prototype.
        
        * config/i386/i386.h (PREFERRED_OUTPUT_RELOAD_CLASS): Remove.
        * config/i386/i386.c (ix86_preferred_output_reload_class): Remove.
        * config/i386/i386.c (ix86_preferred_output_reload_class): Make
        static. Change regclass argument and result types from enum reg_class
        to reg_class_t.
        (TARGET_PREFERRED_OUTPUT_RELOAD_CLASS): Define.




Anatoly.
Richard Henderson - Oct. 15, 2010, 6:04 p.m.
On 10/15/2010 10:31 AM, Anatoly Sokolov wrote:
> -  /* Output reloads may need analogous treatment, different in detail.  */
> -#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
> +    /* Output reloads may need analogous treatment, different in detail.  */
>      if (out != 0)
> -      preferred_class = PREFERRED_OUTPUT_RELOAD_CLASS (out, preferred_class);
> -#endif
> +      preferred_class = targetm.preferred_reload_class (out,
> +                                                       preferred_class);

You're not calling output_reload_class here.

> @@ -3535,17 +3534,15 @@
>  
>               if (! CONSTANT_P (operand) && this_alternative[i] != NO_REGS)
>                 {
> -                 if (targetm.preferred_reload_class (operand, this_alternative[i])
> -                     == NO_REGS)
> -                   reject = 600;
> -
> -#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
>                   if (operand_type[i] == RELOAD_FOR_OUTPUT
> -                     && (PREFERRED_OUTPUT_RELOAD_CLASS (operand,
> -                                                       this_alternative[i])
> +                     && (targetm.preferred_output_reload_class (operand,
> +                                                                this_alternative[i])
>                           == NO_REGS))
>                     reject = 600;
> -#endif
> +                 else if (targetm.preferred_reload_class (operand,
> +                                                          this_alternative[i])
> +                     == NO_REGS)
> +                   reject = 600;

You're changing semantics here.

Previously, p_r_c always gets first shot.  This may be a desirable change,
but do not mix this with the hookize patch.



r~

Patch

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi     (revision 165513)
+++ gcc/doc/tm.texi     (working copy)
@@ -2665,6 +2665,17 @@ 
 reload from using some alternatives, like @code{PREFERRED_RELOAD_CLASS}.
 @end defmac
 
+@deftypefn {Target Hook} reg_class_t TARGET_PREFERRED_OUTPUT_RELOAD_CLASS (rtx @var{x}, reg_class_t @var{rclass})
+Like @code{TARGET_PREFERRED_RELOAD_CLASS}, but for output reloads instead of
+input reloads.
+
+The default version of this hook always returns value of @code{rclass}
+argument.
+
+You can also use @code{TARGET_PREFERRED_OUTPUT_RELOAD_CLASS} to discourage
+reload from using some alternatives, like @code{TARGET_PREFERRED_RELOAD_CLASS}.
+@end deftypefn
+
 @defmac LIMIT_RELOAD_CLASS (@var{mode}, @var{class})
 A C expression that places additional restrictions on the register class
 to use when it is necessary to be able to hold a value of mode
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in  (revision 165513)
+++ gcc/doc/tm.texi.in  (working copy)
@@ -2663,6 +2663,17 @@ 
 reload from using some alternatives, like @code{PREFERRED_RELOAD_CLASS}.
 @end defmac
 
+@hook TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
+Like @code{TARGET_PREFERRED_RELOAD_CLASS}, but for output reloads instead of
+input reloads.
+
+The default version of this hook always returns value of @code{rclass}
+argument.
+
+You can also use @code{TARGET_PREFERRED_OUTPUT_RELOAD_CLASS} to discourage
+reload from using some alternatives, like @code{TARGET_PREFERRED_RELOAD_CLASS}.
+@end deftypefn
+
 @defmac LIMIT_RELOAD_CLASS (@var{mode}, @var{class})
 A C expression that places additional restrictions on the register class
 to use when it is necessary to be able to hold a value of mode
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c     (revision 165513)
+++ gcc/targhooks.c     (working copy)
@@ -1243,6 +1243,19 @@ 
 #endif
 }
 
+/* The default implementation of TARGET_OUTPUT_PREFERRED_RELOAD_CLASS.  */
+
+reg_class_t
+default_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED,
+                                      reg_class_t rclass)
+{
+#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
+  return PREFERRED_OUTPUT_RELOAD_CLASS (x, (enum reg_class) rclass);
+#else
+  return rclass;
+#endif
+}
+
 /* The default implementation of TARGET_CLASS_LIKELY_SPILLED_P.  */
 
 bool
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h     (revision 165513)
+++ gcc/targhooks.h     (working copy)
@@ -155,6 +155,7 @@ 
 
 extern bool default_profile_before_prologue (void);
 extern reg_class_t default_preferred_reload_class (rtx, reg_class_t);
+extern reg_class_t default_preferred_output_reload_class (rtx, reg_class_t);
 extern bool default_class_likely_spilled_p (reg_class_t);
 
 extern enum unwind_info_type default_debug_unwind_info (void);
Index: gcc/target.def
===================================================================
--- gcc/target.def      (revision 165513)
+++ gcc/target.def      (working copy)
@@ -2042,7 +2042,16 @@ 
  (rtx x, reg_class_t rclass),
  default_preferred_reload_class)
 
+/* Like TARGET_PREFERRED_RELOAD_CLASS, but for output reloads instead of
+   input reloads.  */
 DEFHOOK
+(preferred_output_reload_class,
+ "",
+ reg_class_t,
+ (rtx x, reg_class_t rclass),
+ default_preferred_output_reload_class)
+
+DEFHOOK
 (class_likely_spilled_p,
  "",
  bool, (reg_class_t rclass),
Index: gcc/reload.c
===================================================================
--- gcc/reload.c        (revision 165513)
+++ gcc/reload.c        (working copy)
@@ -264,7 +264,7 @@ 
 static int find_reusable_reload (rtx *, rtx, enum reg_class,
                                 enum reload_type, int, int);
 static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, enum machine_mode,
-                             enum machine_mode, enum reg_class, int, int);
+                             enum machine_mode, reg_class_t, int, int);
 static int hard_reg_set_here_p (unsigned int, unsigned int, rtx);
 static struct decomposition decompose (rtx);
 static int immune_p (rtx, rtx, struct decomposition);
@@ -1224,21 +1224,20 @@ 
   /* Narrow down the class of register wanted if that is
      desirable on this machine for efficiency.  */
   {
-    enum reg_class preferred_class = rclass;
+    reg_class_t preferred_class = rclass;
 
     if (in != 0)
-      preferred_class = (enum reg_class) targetm.preferred_reload_class (in, rclass);
+      preferred_class = targetm.preferred_reload_class (in, rclass);
 
-  /* Output reloads may need analogous treatment, different in detail.  */
-#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
+    /* Output reloads may need analogous treatment, different in detail.  */
     if (out != 0)
-      preferred_class = PREFERRED_OUTPUT_RELOAD_CLASS (out, preferred_class);
-#endif
+      preferred_class = targetm.preferred_reload_class (out,
+                                                       preferred_class);
 
     /* Discard what the target said if we cannot do it.  */
     if (preferred_class != NO_REGS
        || (optional && type == RELOAD_FOR_OUTPUT))
-      rclass = preferred_class;
+      rclass = (enum reg_class) preferred_class;
   }
 
   /* Make sure we use a class that can handle the actual pseudo
@@ -1920,7 +1919,7 @@ 
 static rtx
 find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
                   enum machine_mode inmode, enum machine_mode outmode,
-                  enum reg_class rclass, int for_real, int earlyclobber)
+                  reg_class_t rclass, int for_real, int earlyclobber)
 {
   rtx in = real_in;
   rtx out = real_out;
@@ -2588,7 +2587,7 @@ 
   enum reload_usage { RELOAD_READ, RELOAD_READ_WRITE, RELOAD_WRITE } modified[MAX_RECOG_OPERANDS];
   int no_input_reloads = 0, no_output_reloads = 0;
   int n_alternatives;
-  enum reg_class this_alternative[MAX_RECOG_OPERANDS];
+  reg_class_t this_alternative[MAX_RECOG_OPERANDS];
   char this_alternative_match_win[MAX_RECOG_OPERANDS];
   char this_alternative_win[MAX_RECOG_OPERANDS];
   char this_alternative_offmemok[MAX_RECOG_OPERANDS];
@@ -3535,17 +3534,15 @@ 
 
              if (! CONSTANT_P (operand) && this_alternative[i] != NO_REGS)
                {
-                 if (targetm.preferred_reload_class (operand, this_alternative[i])
-                     == NO_REGS)
-                   reject = 600;
-
-#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
                  if (operand_type[i] == RELOAD_FOR_OUTPUT
-                     && (PREFERRED_OUTPUT_RELOAD_CLASS (operand,
-                                                       this_alternative[i])
+                     && (targetm.preferred_output_reload_class (operand,
+                                                                this_alternative[i])
                          == NO_REGS))
                    reject = 600;
-#endif
+                 else if (targetm.preferred_reload_class (operand,
+                                                          this_alternative[i])
+                     == NO_REGS)
+                   reject = 600;
                }
 
              /* We prefer to reload pseudos over reloading other things,
@@ -3696,7 +3693,7 @@ 
            {
              goal_alternative_win[i] = this_alternative_win[i];
              goal_alternative_match_win[i] = this_alternative_match_win[i];
-             goal_alternative[i] = (reg_class_t) this_alternative[i];
+             goal_alternative[i] = this_alternative[i];
              goal_alternative_offmemok[i] = this_alternative_offmemok[i];
              goal_alternative_matches[i] = this_alternative_matches[i];
              goal_alternative_earlyclobber[i]
@@ -3723,7 +3720,7 @@ 
            {
              for (i = 0; i < noperands; i++)
                {
-                 goal_alternative[i] = (reg_class_t) this_alternative[i];
+                 goal_alternative[i] = this_alternative[i];
                  goal_alternative_win[i] = this_alternative_win[i];
                  goal_alternative_match_win[i]
                    = this_alternative_match_win[i];
Index: gcc/recog.c
===================================================================
--- gcc/recog.c	(revision 165513)
+++ gcc/recog.c	(working copy)
@@ -2751,21 +2751,21 @@ 
     return 0;
 }
 
-/* Return 1 iff OPERAND (assumed to be a REG rtx)
+/* Return true iff OPERAND (assumed to be a REG rtx)
    is a hard reg in class CLASS when its regno is offset by OFFSET
    and changed to mode MODE.
    If REG occupies multiple hard regs, all of them must be in CLASS.  */
 
-int
-reg_fits_class_p (rtx operand, enum reg_class cl, int offset,
+bool
+reg_fits_class_p (const_rtx operand, reg_class_t cl, int offset,
                  enum machine_mode mode)
 {
   int regno = REGNO (operand);
 
   if (cl == NO_REGS)
-    return 0;
+    return false;
 
-  return (regno < FIRST_PSEUDO_REGISTER
+  return (HARD_REGISTER_NUM_P (regno)
          && in_hard_reg_set_p (reg_class_contents[(int) cl],
                                mode, regno + offset));
 }
Index: gcc/recog.h
===================================================================
--- gcc/recog.h	(revision 165513)
+++ gcc/recog.h	(working copy)
@@ -102,7 +102,7 @@ 
 #ifdef HAVE_cc0
 extern int next_insn_tests_no_inequality (rtx);
 #endif
-extern int reg_fits_class_p (rtx, enum reg_class, int, enum machine_mode);
+extern bool reg_fits_class_p (const_rtx, reg_class_t, int, enum machine_mode);
 
 extern int offsettable_memref_p (rtx);
 extern int offsettable_nonstrict_memref_p (rtx);
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h      (revision 165513)
+++ gcc/config/i386/i386.h      (working copy)
@@ -1373,12 +1373,6 @@ 
        || (CLASS) == LEGACY_REGS || (CLASS) == INDEX_REGS)     \
    ? Q_REGS : (CLASS))
 
-/* Discourage putting floating-point values in SSE registers unless
-   SSE math is being used, and likewise for the 387 registers.  */
-
-#define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS) \
-   ix86_preferred_output_reload_class ((X), (CLASS))
-
 /* If we are copying between general and FP registers, we need a memory
    location. The same is true for SSE and MMX registers.  */
 #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
Index: gcc/config/i386/i386-protos.h
===================================================================
--- gcc/config/i386/i386-protos.h       (revision 165513)
+++ gcc/config/i386/i386-protos.h       (working copy)
@@ -153,7 +153,6 @@ 
                                          enum machine_mode, int);
 extern bool ix86_cannot_change_mode_class (enum machine_mode,
                                           enum machine_mode, enum reg_class);
-extern enum reg_class ix86_preferred_output_reload_class (rtx, enum reg_class);
 extern int ix86_mode_needed (int, rtx);
 extern void emit_i387_cw_initialization (int);
 extern void x86_order_regs_for_local_alloc (void);
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c      (revision 165513)
+++ gcc/config/i386/i386.c      (working copy)
@@ -26795,8 +26795,8 @@ 
 
 /* Discourage putting floating-point values in SSE registers unless
    SSE math is being used, and likewise for the 387 registers.  */
-enum reg_class
-ix86_preferred_output_reload_class (rtx x, enum reg_class regclass)
+static reg_class_t
+ix86_preferred_output_reload_class (rtx x, reg_class_t regclass)
 {
   enum machine_mode mode = GET_MODE (x);
 
@@ -33379,6 +33379,8 @@ 
 
 #undef TARGET_PREFERRED_RELOAD_CLASS
 #define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class
+#undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
+#define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS ix86_preferred_output_reload_class
 #undef TARGET_CLASS_LIKELY_SPILLED_P
 #define TARGET_CLASS_LIKELY_SPILLED_P ix86_class_likely_spilled_p