This patch converts LEGITIMATE_CONSTANT_P into a target hook and
passes along the mode of the constant.  This can then be used by 5/5.

The patch is a version of:

    http://gcc.gnu.org/ml/gcc-patches/2011-04/msg00195.html

which is still pending review after two pings.  It seems pretty simple
though, so I think it's worth backporting now rather than waiting for
upstream approval.

The backport is very much a cut-down version.  Rather than convert all
targets to the new hook, I've kept LEGITIMATE_CONSTANT_P around and
made it the default implementation of the new hook.  Only ARM defines
the hook directly.

Note that the ARM definition is supposed to be identical to the old
LEGITIMATE_CONSTANT_P version.  Only 5/5 is meant to change it.

Richard


gcc/
        * doc/tm.texi (LEGITIMATE_CONSTANT_P): Replace with...
        (TARGET_LEGITIMATE_CONSTANT_P): ...this.
        * target.h (gcc_target): Add legitimate_constant_p.
        * target-def.h (TARGET_LEGITIMATE_CONSTANT_P): Define.
        (TARGET_INITIALIZER): Include it.
        * calls.c (precompute_register_parameters): Replace uses of
        LEGITIMATE_CONSTANT_P with targetm.legitimate_constant_p.
        (emit_library_call_value_1): Likewise.
        * expr.c (move_block_to_reg, can_store_by_pieces, emit_move_insn)
        (compress_float_constant, emit_push_insn, expand_expr_real_1): Likewise.
        * recog.c (general_operand, immediate_operand): Likewise.
        * reload.c (find_reloads_toplev, find_reloads_address_part): Likewise.
        * reload1.c (init_eliminable_invariants): Likewise.
        * targhooks.h (default_legitimate_constant_p); Declare.
        * targhooks.c (default_legitimate_constant_p): New function.

        * config/arm/arm-protos.h (arm_cannot_force_const_mem): Delete.
        * config/arm/arm.h (ARM_LEGITIMATE_CONSTANT_P): Likewise.
        (THUMB_LEGITIMATE_CONSTANT_P, LEGITIMATE_CONSTANT_P): Likewise.
        * config/arm/arm.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
        (arm_legitimate_constant_p_1, thumb_legitimate_constant_p)
        (arm_legitimate_constant_p): New functions.
        (arm_cannot_force_const_mem): Make static.

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi     2011-04-19 16:38:08.000000000 +0000
+++ gcc/doc/tm.texi     2011-04-19 16:38:15.000000000 +0000
@@ -2642,8 +2642,8 @@ instruction for loading an immediate val
 register, so @code{PREFERRED_RELOAD_CLASS} returns @code{NO_REGS} when
 @var{x} is a floating-point constant.  If the constant can't be loaded
 into any kind of register, code generation will be better if
-@code{LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
-of using @code{PREFERRED_RELOAD_CLASS}.
+@code{TARGET_LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
+of using @code{TARGET_PREFERRED_RELOAD_CLASS}.
 
 If an insn has pseudos in it after register allocation, reload will go
 through the alternatives and call repeatedly @code{PREFERRED_RELOAD_CLASS}
@@ -5628,13 +5628,13 @@ addresses.  Many RISC machines have no m
 You may assume that @var{addr} is a valid address for the machine.
 @end defmac
 
-@defmac LEGITIMATE_CONSTANT_P (@var{x})
-A C expression that is nonzero if @var{x} is a legitimate constant for
-an immediate operand on the target machine.  You can assume that
-@var{x} satisfies @code{CONSTANT_P}, so you need not check this.  In fact,
-@samp{1} is a suitable definition for this macro on machines where
-anything @code{CONSTANT_P} is valid.
-@end defmac
+@deftypefn {Target Hook} bool TARGET_LEGITIMATE_CONSTANT_P (enum machine_mode 
@var{mode}, rtx @var{x})
+This hook returns true if @var{x} is a legitimate constant for a
+@var{mode}-mode immediate operand on the target machine.  You can assume that
+@var{x} satisfies @code{CONSTANT_P}, so you need not check this.
+
+The default definition returns true.
+@end deftypefn
 
 @deftypefn {Target Hook} rtx TARGET_DELEGITIMIZE_ADDRESS (rtx @var{x})
 This hook is used to undo the possibly obfuscating effects of the
Index: gcc/target.h
===================================================================
--- gcc/target.h        2011-04-19 16:38:08.000000000 +0000
+++ gcc/target.h        2011-04-19 16:38:16.000000000 +0000
@@ -645,7 +645,10 @@ struct gcc_target
   /* Return true if the target supports conditional execution.  */
   bool (* have_conditional_execution) (void);
 
-  /* True if the constant X cannot be placed in the constant pool.  */
+  /* See tm.texi.  */
+  bool (* legitimate_constant_p) (enum machine_mode, rtx);
+
+    /* True if the constant X cannot be placed in the constant pool.  */
   bool (* cannot_force_const_mem) (rtx);
 
   /* True if the insn X cannot be duplicated.  */
Index: gcc/target-def.h
===================================================================
--- gcc/target-def.h    2011-04-19 16:38:08.000000000 +0000
+++ gcc/target-def.h    2011-04-19 16:38:16.000000000 +0000
@@ -563,6 +563,7 @@ #define TARGET_BRANCH_TARGET_REGISTER_CL
   default_branch_target_register_class
 #define TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED hook_bool_bool_false
 #define TARGET_HAVE_CONDITIONAL_EXECUTION default_have_conditional_execution
+#define TARGET_LEGITIMATE_CONSTANT_P default_legitimate_constant_p
 #define TARGET_CANNOT_FORCE_CONST_MEM hook_bool_rtx_false
 #define TARGET_CANNOT_COPY_INSN_P NULL
 #define TARGET_COMMUTATIVE_P hook_bool_const_rtx_commutative_p
@@ -965,6 +966,7 @@ #define TARGET_INITIALIZER                  \
   TARGET_BRANCH_TARGET_REGISTER_CLASS,         \
   TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED,  \
   TARGET_HAVE_CONDITIONAL_EXECUTION,           \
+  TARGET_LEGITIMATE_CONSTANT_P,                        \
   TARGET_CANNOT_FORCE_CONST_MEM,               \
   TARGET_CANNOT_COPY_INSN_P,                   \
   TARGET_COMMUTATIVE_P,                                \
Index: gcc/calls.c
===================================================================
--- gcc/calls.c 2011-04-19 16:38:08.000000000 +0000
+++ gcc/calls.c 2011-04-19 16:38:15.000000000 +0000
@@ -674,7 +674,7 @@ precompute_register_parameters (int num_
        /* If the value is a non-legitimate constant, force it into a
           pseudo now.  TLS symbols sometimes need a call to resolve.  */
        if (CONSTANT_P (args[i].value)
-           && !LEGITIMATE_CONSTANT_P (args[i].value))
+           && !targetm.legitimate_constant_p (args[i].mode, args[i].value))
          args[i].value = force_reg (args[i].mode, args[i].value);
 
        /* If we are to promote the function arg to a wider mode,
@@ -3413,7 +3413,8 @@ emit_library_call_value_1 (int retval, r
 
       /* Make sure it is a reasonable operand for a move or push insn.  */
       if (!REG_P (addr) && !MEM_P (addr)
-         && ! (CONSTANT_P (addr) && LEGITIMATE_CONSTANT_P (addr)))
+         && !(CONSTANT_P (addr)
+              && targetm.legitimate_constant_p (Pmode, addr)))
        addr = force_operand (addr, NULL_RTX);
 
       argvec[count].value = addr;
@@ -3453,7 +3454,7 @@ emit_library_call_value_1 (int retval, r
 
       /* Make sure it is a reasonable operand for a move or push insn.  */
       if (!REG_P (val) && !MEM_P (val)
-         && ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val)))
+         && !(CONSTANT_P (val) && targetm.legitimate_constant_p (mode, val)))
        val = force_operand (val, NULL_RTX);
 
       if (pass_by_reference (&args_so_far, mode, NULL_TREE, 1))
Index: gcc/expr.c
===================================================================
--- gcc/expr.c  2011-04-19 16:38:08.000000000 +0000
+++ gcc/expr.c  2011-04-19 16:38:16.000000000 +0000
@@ -1537,7 +1537,7 @@ move_block_to_reg (int regno, rtx x, int
   if (nregs == 0)
     return;
 
-  if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
+  if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
     x = validize_mem (force_const_mem (mode, x));
 
   /* See if the machine can do this with a load multiple insn.  */
@@ -2366,7 +2366,7 @@ can_store_by_pieces (unsigned HOST_WIDE_
                    offset -= size;
 
                  cst = (*constfun) (constfundata, offset, mode);
-                 if (!LEGITIMATE_CONSTANT_P (cst))
+                 if (!targetm.legitimate_constant_p (mode, cst))
                    return 0;
 
                  if (!reverse)
@@ -3440,7 +3440,7 @@ emit_move_insn (rtx x, rtx y)
 
       y_cst = y;
 
-      if (!LEGITIMATE_CONSTANT_P (y))
+      if (!targetm.legitimate_constant_p (mode, y))
        {
          y = force_const_mem (mode, y);
 
@@ -3496,7 +3496,7 @@ compress_float_constant (rtx x, rtx y)
 
   REAL_VALUE_FROM_CONST_DOUBLE (r, y);
 
-  if (LEGITIMATE_CONSTANT_P (y))
+  if (targetm.legitimate_constant_p (dstmode, y))
     oldcost = rtx_cost (y, SET, speed);
   else
     oldcost = rtx_cost (force_const_mem (dstmode, y), SET, speed);
@@ -3519,7 +3519,7 @@ compress_float_constant (rtx x, rtx y)
 
       trunc_y = CONST_DOUBLE_FROM_REAL_VALUE (r, srcmode);
 
-      if (LEGITIMATE_CONSTANT_P (trunc_y))
+      if (targetm.legitimate_constant_p (srcmode, trunc_y))
        {
          /* Skip if the target needs extra instructions to perform
             the extension.  */
@@ -3932,7 +3932,7 @@ emit_push_insn (rtx x, enum machine_mode
         by setting SKIP to 0.  */
       skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
 
-      if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
+      if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
        x = validize_mem (force_const_mem (mode, x));
 
       /* If X is a hard register in a non-integer mode, copy it into a pseudo;
@@ -8951,7 +8951,7 @@ expand_expr_real_1 (tree exp, rtx target
           constant and we don't need a memory reference.  */
        if (CONSTANT_P (op0)
            && mode2 != BLKmode
-           && LEGITIMATE_CONSTANT_P (op0)
+           && targetm.legitimate_constant_p (mode2, op0)
            && !must_force_mem)
          op0 = force_reg (mode2, op0);
 
Index: gcc/recog.c
===================================================================
--- gcc/recog.c 2011-04-19 16:38:08.000000000 +0000
+++ gcc/recog.c 2011-04-19 16:38:16.000000000 +0000
@@ -932,7 +932,9 @@ general_operand (rtx op, enum machine_mo
     return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
             || mode == VOIDmode)
            && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
-           && LEGITIMATE_CONSTANT_P (op));
+           && targetm.legitimate_constant_p (mode == VOIDmode
+                                             ? GET_MODE (op)
+                                             : mode, op));
 
   /* Except for certain constants with VOIDmode, already checked for,
      OP's mode must match MODE if MODE specifies a mode.  */
@@ -1109,7 +1111,9 @@ immediate_operand (rtx op, enum machine_
          && (GET_MODE (op) == mode || mode == VOIDmode
              || GET_MODE (op) == VOIDmode)
          && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
-         && LEGITIMATE_CONSTANT_P (op));
+         && targetm.legitimate_constant_p (mode == VOIDmode
+                                           ? GET_MODE (op)
+                                           : mode, op));
 }
 
 /* Returns 1 if OP is an operand that is a CONST_INT.  */
@@ -1175,7 +1179,9 @@ nonmemory_operand (rtx op, enum machine_
       return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
               || mode == VOIDmode)
              && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
-             && LEGITIMATE_CONSTANT_P (op));
+             && targetm.legitimate_constant_p (mode == VOIDmode
+                                               ? GET_MODE (op)
+                                               : mode, op));
     }
 
   if (GET_MODE (op) != mode && mode != VOIDmode)
Index: gcc/reload.c
===================================================================
--- gcc/reload.c        2011-04-19 16:38:08.000000000 +0000
+++ gcc/reload.c        2011-04-19 16:38:16.000000000 +0000
@@ -4739,7 +4739,8 @@ find_reloads_toplev (rtx x, int opnum, e
            simplify_gen_subreg (GET_MODE (x), reg_equiv_constant[regno],
                                 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
          gcc_assert (tem);
-         if (CONSTANT_P (tem) && !LEGITIMATE_CONSTANT_P (tem))
+         if (CONSTANT_P (tem)
+             && !targetm.legitimate_constant_p (GET_MODE (x), tem))
            {
              tem = force_const_mem (GET_MODE (x), tem);
              i = find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
@@ -6061,7 +6062,7 @@ find_reloads_address_part (rtx x, rtx *l
                           enum reload_type type, int ind_levels)
 {
   if (CONSTANT_P (x)
-      && (! LEGITIMATE_CONSTANT_P (x)
+      && (!targetm.legitimate_constant_p (mode, x)
          || PREFERRED_RELOAD_CLASS (x, rclass) == NO_REGS))
     {
       x = force_const_mem (mode, x);
@@ -6071,7 +6072,7 @@ find_reloads_address_part (rtx x, rtx *l
 
   else if (GET_CODE (x) == PLUS
           && CONSTANT_P (XEXP (x, 1))
-          && (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
+          && (!targetm.legitimate_constant_p (GET_MODE (x), XEXP (x, 1))
               || PREFERRED_RELOAD_CLASS (XEXP (x, 1), rclass) == NO_REGS))
     {
       rtx tem;
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c       2011-04-19 16:38:08.000000000 +0000
+++ gcc/reload1.c       2011-04-19 16:38:16.000000000 +0000
@@ -4164,6 +4164,9 @@ init_eliminable_invariants (rtx first, b
                }
              else if (function_invariant_p (x))
                {
+                 enum machine_mode mode;
+
+                 mode = GET_MODE (SET_DEST (set));
                  if (GET_CODE (x) == PLUS)
                    {
                      /* This is PLUS of frame pointer and a constant,
@@ -4176,12 +4179,11 @@ init_eliminable_invariants (rtx first, b
                      reg_equiv_invariant[i] = x;
                      num_eliminable_invariants++;
                    }
-                 else if (LEGITIMATE_CONSTANT_P (x))
+                 else if (targetm.legitimate_constant_p (mode, x))
                    reg_equiv_constant[i] = x;
                  else
                    {
-                     reg_equiv_memory_loc[i]
-                       = force_const_mem (GET_MODE (SET_DEST (set)), x);
+                     reg_equiv_memory_loc[i] = force_const_mem (mode, x);
                      if (! reg_equiv_memory_loc[i])
                        reg_equiv_init[i] = NULL_RTX;
                    }
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h     2011-04-19 16:38:08.000000000 +0000
+++ gcc/targhooks.h     2011-04-19 16:38:16.000000000 +0000
@@ -132,3 +132,4 @@ extern bool default_addr_space_subset_p
 extern rtx default_addr_space_convert (rtx, tree, tree);
 extern unsigned int default_case_values_threshold (void);
 extern bool default_have_conditional_execution (void);
+extern bool default_legitimate_constant_p (enum machine_mode, rtx);
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c     2011-04-19 16:38:08.000000000 +0000
+++ gcc/targhooks.c     2011-04-20 07:50:38.000000000 +0000
@@ -1008,4 +1008,15 @@ default_have_conditional_execution (void
 #endif
 }
 
+bool
+default_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+                              rtx x ATTRIBUTE_UNUSED)
+{
+#ifdef LEGITIMATE_CONSTANT_P
+  return LEGITIMATE_CONSTANT_P (x);
+#else
+  return true;
+#endif
+}
+
 #include "gt-targhooks.h"
Index: gcc/config/arm/arm-protos.h
===================================================================
--- gcc/config/arm/arm-protos.h 2011-04-19 16:38:08.000000000 +0000
+++ gcc/config/arm/arm-protos.h 2011-04-19 16:38:16.000000000 +0000
@@ -81,7 +81,6 @@ extern void neon_disambiguate_copy (rtx
 extern enum reg_class coproc_secondary_reload_class (enum machine_mode, rtx,
                                                     bool);
 extern bool arm_tls_referenced_p (rtx);
-extern bool arm_cannot_force_const_mem (rtx);
 
 extern int cirrus_memory_offset (rtx);
 extern int arm_coproc_mem_operand (rtx, bool);
Index: gcc/config/arm/arm.h
===================================================================
--- gcc/config/arm/arm.h        2011-04-19 16:38:08.000000000 +0000
+++ gcc/config/arm/arm.h        2011-04-19 16:38:16.000000000 +0000
@@ -1996,27 +1996,6 @@ #define ARM_OFFSETS_MUST_BE_WITHIN_SECTI
 #define TARGET_DEFAULT_WORD_RELOCATIONS 0
 #endif
 
-/* Nonzero if the constant value X is a legitimate general operand.
-   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
-
-   On the ARM, allow any integer (invalid ones are removed later by insn
-   patterns), nice doubles and symbol_refs which refer to the function's
-   constant pool XXX.
-
-   When generating pic allow anything.  */
-#define ARM_LEGITIMATE_CONSTANT_P(X)   (flag_pic || ! label_mentioned_p (X))
-
-#define THUMB_LEGITIMATE_CONSTANT_P(X) \
- (   GET_CODE (X) == CONST_INT         \
-  || GET_CODE (X) == CONST_DOUBLE      \
-  || CONSTANT_ADDRESS_P (X)            \
-  || flag_pic)
-
-#define LEGITIMATE_CONSTANT_P(X)                       \
-  (!arm_cannot_force_const_mem (X)                     \
-   && (TARGET_32BIT ? ARM_LEGITIMATE_CONSTANT_P (X)    \
-                   : THUMB_LEGITIMATE_CONSTANT_P (X)))
-
 #ifndef SUBTARGET_NAME_ENCODING_LENGTHS
 #define SUBTARGET_NAME_ENCODING_LENGTHS
 #endif
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c        2011-04-19 16:38:08.000000000 +0000
+++ gcc/config/arm/arm.c        2011-04-20 07:58:46.000000000 +0000
@@ -140,6 +140,8 @@ static void arm_internal_label (FILE *,
 static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
                                 tree);
 static bool arm_have_conditional_execution (void);
+static bool arm_cannot_force_const_mem (enum machine_mode, rtx);
+static bool arm_legitimate_constant_p (enum machine_mode, rtx);
 static bool arm_rtx_costs_1 (rtx, enum rtx_code, int*, bool);
 static bool arm_size_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
 static bool thumb2_size_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
@@ -471,6 +473,9 @@ #define TARGET_HAVE_TLS true
 #undef TARGET_HAVE_CONDITIONAL_EXECUTION
 #define TARGET_HAVE_CONDITIONAL_EXECUTION arm_have_conditional_execution
 
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P arm_legitimate_constant_p
+
 #undef TARGET_CANNOT_FORCE_CONST_MEM
 #define TARGET_CANNOT_FORCE_CONST_MEM arm_cannot_force_const_mem
 
@@ -6451,9 +6456,41 @@ arm_tls_referenced_p (rtx x)
   return for_each_rtx (&x, arm_tls_operand_p_1, NULL);
 }
 
+/* Implement TARGET_LEGITIMATE_CONSTANT_P.
+
+   On the ARM, allow any integer (invalid ones are removed later by insn
+   patterns), nice doubles and symbol_refs which refer to the function's
+   constant pool XXX.
+
+   When generating pic allow anything.  */
+
+static bool
+arm_legitimate_constant_p_1 (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+  return flag_pic || !label_mentioned_p (x);
+}
+
+static bool
+thumb_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+  return (GET_CODE (x) == CONST_INT
+         || GET_CODE (x) == CONST_DOUBLE
+         || CONSTANT_ADDRESS_P (x)
+         || flag_pic);
+}
+
+static bool
+arm_legitimate_constant_p (enum machine_mode mode, rtx x)
+{
+  return (!arm_cannot_force_const_mem (x)
+         && (TARGET_32BIT
+             ? arm_legitimate_constant_p_1 (mode, x)
+             : thumb_legitimate_constant_p (mode, x)));
+}
+
 /* Implement TARGET_CANNOT_FORCE_CONST_MEM.  */
 
-bool
+static bool
 arm_cannot_force_const_mem (rtx x)
 {
   rtx base, offset;

_______________________________________________
linaro-toolchain mailing list
linaro-toolchain@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-toolchain

Reply via email to