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]

Re: [PING] Bugfix: Additional parameter for canonicalize comparison


On Wed, Dec 19, 2012 at 3:04 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Wed, Dec 19, 2012 at 12:34 PM, Richard Earnshaw <rearnsha@arm.com> wrote:
>> On 19/12/12 09:53, Andreas Krebbel wrote:
>>>
>>> Hi,
>>>
>>> are the ARM parts of the patch below ok for mainline?
>>>
>>
>> Yes.
>>
>> Sorry for the delay.
>
> I think this broke bootstrap on x86_64:
>
> /space/rguenther/src/svn/trunk/gcc/config/i386/i386.c: At global scope:
> /space/rguenther/src/svn/trunk/gcc/config/i386/i386.c:42503: error:
> invalid conversion from 'bool (*)(int*, rtx_def**, rtx_def**, bool)'
> to 'void (*)(int*, rtx_def**, rtx_def**, bool)'
> make[3]: *** [i386.o] Error 1
>
> or maybe even everywhere.  Yeah, bool vs. void return value in the default
> implementation.
>
> Please fix.

I also can't find a definition of default_canonicalize_comparison - did you
forget to commit a part of the patch?

Thanks,
Richard.

> Richard.
>
>> R.
>>
>>
>>> I did a compile test with a cross.
>>>
>>> Bye,
>>>
>>> -Andreas-
>>>
>>>
>>> -------- Original Message --------
>>> Subject: [PATCH] Bugfix: Additional parameter for canonicalize comparison
>>> Date: Wed, 12 Dec 2012 12:23:14 +0100
>>> From: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
>>> To: rearnsha@arm.com
>>> CC: gcc-patches@gcc.gnu.org
>>>
>>> Hi Richard,
>>>
>>> is the attached patch ok for ARM?
>>>
>>> Bye,
>>>
>>> -Andreas-
>>>
>>> 2012-12-12  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
>>>
>>>          * target.def: Define canonicalize_comparison hook.
>>>          * targhooks.h (default_canonicalize_comparison): New prototype.
>>>          * targhooks.c (default_canonicalize_comparison): New function.
>>>          * doc/tm.texi: Add documentation for the new target hook.
>>>          * doc/tm.texi.in: Likewise.
>>>          * combine.c (try_combine): Adjust to use the target hook.
>>>          * config/alpha/alpha.h (CANONICALIZE_COMPARISON): Remove macro
>>>          definition.
>>>          * config/alpha/alpha.c (alpha_canonicalize_comparison): New
>>>          function.
>>>          (TARGET_CANONICALIZE_COMPARISON): New macro definition.
>>>          * config/arm/arm-protos.h (arm_canonicalize_comparison): Remove
>>>          prototype.
>>>          * config/arm/arm.c (arm_canonicalize_comparison): Add new
>>>          parameter.
>>>          (TARGET_CANONICALIZE_COMPARISON): New macro definition.
>>>          * config/arm/arm.h (CANONICALIZE_COMPARISON): Remove macro
>>>          definition.
>>>          * config/s390/s390-protos.h (s390_canonicalize_comparison):
>>> Remove
>>>          prototype.
>>>          * config/s390/s390.c (s390_canonicalize_comparison): Add new
>>>          parameter.
>>>          (TARGET_CANONICALIZE_COMPARISON): New macro definition.
>>>          * config/s390/s390.h (CANONICALIZE_COMPARISON): Remove macro
>>>          definition.
>>>          * config/sh/sh-protos.h (sh_canonicalize_comparison): Remove
>>>          prototype.
>>>          * config/sh/sh.c (sh_canonicalize_comparison): Add new prototype.
>>> New
>>>          function overloading the old one.
>>>          (TARGET_CANONICALIZE_COMPARISON): New macro definition.
>>>          * config/sh/sh.h (CANONICALIZE_COMPARISON): Remove macro
>>>          definition.
>>>          * config/spu/spu.c (spu_canonicalize_comparison): New function.
>>>          (TARGET_CANONICALIZE_COMPARISON): New macro definition.
>>>          * config/spu/spu.h (CANONICALIZE_COMPARISON): Remove macro
>>>          definition.
>>>
>>> ---
>>>   gcc/combine.c                 |   19 ++++++-!!!
>>>   gcc/config/alpha/alpha.c      |   27 ++++++++++++++++
>>>   gcc/config/alpha/alpha.h      |   20 ------------
>>>   gcc/config/arm/arm-protos.h   |    1
>>>   gcc/config/arm/arm.c          |   68
>>> ++-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
>>>   gcc/config/arm/arm.h          |    3 -
>>>   gcc/config/s390/s390-protos.h |    1
>>>   gcc/config/s390/s390.c        |   13 +++!!!!!
>>>   gcc/config/s390/s390.h        |    4 --
>>>   gcc/config/sh/sh-protos.h     |    2 -
>>>   gcc/config/sh/sh.c            |   34 +++++++++++!!!!!!!!!!
>>>   gcc/config/sh/sh.h            |    4 --
>>>   gcc/config/spu/spu.c          |   17 ++++++++++
>>>   gcc/config/spu/spu.h          |   12 -------
>>>   gcc/doc/tm.texi               |   20 !!!!!!!!!!!!
>>>   gcc/doc/tm.texi.in            |   20 !!!!!!!!!!!!
>>>   gcc/target.def                |    8 ++++
>>>   gcc/targhooks.h               |    2 +
>>>   18 files changed, 94 insertions(+), 50 deletions(-), 131
>>> modifications(!)
>>>
>>> Index: gcc/combine.c
>>> ===================================================================
>>> *** gcc/combine.c.orig
>>> --- gcc/combine.c
>>> *************** static rtx gen_lowpart_or_truncate (enum
>>> *** 494,499 ****
>>> --- 494,510 ----
>>>    static const struct rtl_hooks combine_rtl_hooks =
>>> RTL_HOOKS_INITIALIZER;
>>>
>>>
>>> + /* Convenience wrapper for the canonicalize_comparison target hook.
>>> +    Target hooks cannot use enum rtx_code.  */
>>> + static inline void
>>> + target_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1,
>>> +                               bool op0_preserve_value)
>>> + {
>>> +   int code_int = (int)*code;
>>> +   targetm.canonicalize_comparison (&code_int, op0, op1,
>>> op0_preserve_value);
>>> +   *code = (enum rtx_code)code_int;
>>> + }
>>> +
>>>    /* Try to split PATTERN found in INSN.  This returns NULL_RTX if
>>>       PATTERN can not be split.  Otherwise, it returns an insn sequence.
>>>       This is a wrapper around split_insns which ensures that the
>>> *************** try_combine (rtx i3, rtx i2, rtx i1, rtx
>>> *** 2944,2952 ****
>>>            compare_code = orig_compare_code = GET_CODE (*cc_use_loc);
>>>            compare_code = simplify_compare_const (compare_code,
>>>                                                   op0, &op1);
>>> ! #ifdef CANONICALIZE_COMPARISON
>>> !         CANONICALIZE_COMPARISON (compare_code, op0, op1);
>>> ! #endif
>>>          }
>>>
>>>          /* Do the rest only if op1 is const0_rtx, which may be the
>>> --- 2955,2961 ----
>>>            compare_code = orig_compare_code = GET_CODE (*cc_use_loc);
>>>            compare_code = simplify_compare_const (compare_code,
>>>                                                   op0, &op1);
>>> !         target_canonicalize_comparison (&compare_code, &op0, &op1, 1);
>>>          }
>>>
>>>          /* Do the rest only if op1 is const0_rtx, which may be the
>>> *************** simplify_comparison (enum rtx_code code,
>>> *** 11959,11969 ****
>>>              }
>>>          }
>>>
>>> - #ifdef CANONICALIZE_COMPARISON
>>>      /* If this machine only supports a subset of valid comparisons, see
>>> if we
>>>         can convert an unsupported one into a supported one.  */
>>> !   CANONICALIZE_COMPARISON (code, op0, op1);
>>> ! #endif
>>>
>>>      *pop0 = op0;
>>>      *pop1 = op1;
>>> --- 11968,11976 ----
>>>              }
>>>          }
>>>
>>>      /* If this machine only supports a subset of valid comparisons, see
>>> if we
>>>         can convert an unsupported one into a supported one.  */
>>> !   target_canonicalize_comparison (&code, &op0, &op1, 0);
>>>
>>>      *pop0 = op0;
>>>      *pop1 = op1;
>>> Index: gcc/config/alpha/alpha.c
>>> ===================================================================
>>> *** gcc/config/alpha/alpha.c.orig
>>> --- gcc/config/alpha/alpha.c
>>> *************** alpha_conditional_register_usage (void)
>>> *** 9683,9688 ****
>>> --- 9683,9712 ----
>>>        for (i = 32; i < 63; i++)
>>>          fixed_regs[i] = call_used_regs[i] = 1;
>>>    }
>>> +
>>> + /* Canonicalize a comparison from one we don't have to one we do have.
>>> */
>>> +
>>> + static void
>>> + alpha_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
>>> +                              bool op0_preserve_value)
>>> + {
>>> +   if (!op0_preserve_value
>>> +       && (*code == GE || *code == GT || *code == GEU || *code == GTU)
>>> +       && (REG_P (*op1) || *op1 == const0_rtx))
>>> +     {
>>> +       rtx tem = *op0;
>>> +       *op0 = *op1;
>>> +       *op1 = tem;
>>> +       *code = (int)swap_condition ((enum rtx_code)*code);
>>> +     }
>>> +
>>> +   if ((*code == LT || *code == LTU)
>>> +       && CONST_INT_P (*op1) && INTVAL (*op1) == 256)
>>> +     {
>>> +       *code = *code == LT ? LE : LEU;
>>> +       *op1 = GEN_INT (255);
>>> +     }
>>> + }
>>>
>>>    /* Initialize the GCC target structure.  */
>>>    #if TARGET_ABI_OPEN_VMS
>>> *************** alpha_conditional_register_usage (void)
>>> *** 9850,9855 ****
>>> --- 9874,9882 ----
>>>    #undef TARGET_CONDITIONAL_REGISTER_USAGE
>>>    #define TARGET_CONDITIONAL_REGISTER_USAGE
>>> alpha_conditional_register_usage
>>>
>>> + #undef TARGET_CANONICALIZE_COMPARISON
>>> + #define TARGET_CANONICALIZE_COMPARISON alpha_canonicalize_comparison
>>> +
>>>    struct gcc_target targetm = TARGET_INITIALIZER;
>>>
>>>
>>> Index: gcc/config/alpha/alpha.h
>>> ===================================================================
>>> *** gcc/config/alpha/alpha.h.orig
>>> --- gcc/config/alpha/alpha.h
>>> *************** do {
>>> \
>>> *** 922,947 ****
>>>    #define FLOAT_STORE_FLAG_VALUE(MODE) \
>>>      REAL_VALUE_ATOF ((TARGET_FLOAT_VAX ? "0.5" : "2.0"), (MODE))
>>>
>>> - /* Canonicalize a comparison from one we don't have to one we do have.
>>> */
>>> -
>>> - #define CANONICALIZE_COMPARISON(CODE,OP0,OP1) \
>>> -   do {
>>> \
>>> -     if (((CODE) == GE || (CODE) == GT || (CODE) == GEU || (CODE) == GTU)
>>> \
>>> -       && (REG_P (OP1) || (OP1) == const0_rtx))                \
>>> -       {
>>> \
>>> -       rtx tem = (OP0);                                                \
>>> -       (OP0) = (OP1);                                                  \
>>> -       (OP1) = tem;                                                    \
>>> -       (CODE) = swap_condition (CODE);                                 \
>>> -       }
>>> \
>>> -     if (((CODE) == LT || (CODE) == LTU)
>>> \
>>> -       && CONST_INT_P (OP1) && INTVAL (OP1) == 256)                    \
>>> -       {
>>> \
>>> -       (CODE) = (CODE) == LT ? LE : LEU;                               \
>>> -       (OP1) = GEN_INT (255);                                          \
>>> -       }
>>> \
>>> -   } while (0)
>>> -
>>>    /* Specify the machine mode that pointers have.
>>>       After generation of rtl, the compiler makes no further distinction
>>>       between pointers and any other objects of this machine mode.  */
>>> --- 922,927 ----
>>> Index: gcc/config/arm/arm-protos.h
>>> ===================================================================
>>> *** gcc/config/arm/arm-protos.h.orig
>>> --- gcc/config/arm/arm-protos.h
>>> *************** extern int const_ok_for_op (HOST_WIDE_IN
>>> *** 53,59 ****
>>>    extern int const_ok_for_dimode_op (HOST_WIDE_INT, enum rtx_code);
>>>    extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
>>>                                 HOST_WIDE_INT, rtx, rtx, int);
>>> - extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *, rtx *);
>>>    extern int legitimate_pic_operand_p (rtx);
>>>    extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
>>>    extern rtx legitimize_tls_address (rtx, rtx);
>>> --- 53,58 ----
>>> Index: gcc/config/arm/arm.c
>>> ===================================================================
>>> *** gcc/config/arm/arm.c.orig
>>> --- gcc/config/arm/arm.c
>>> *************** static int arm_cortex_a5_branch_cost (bo
>>> *** 269,275 ****
>>>
>>>    static bool arm_vectorize_vec_perm_const_ok (enum machine_mode vmode,
>>>                                               const unsigned char *sel);
>>> !
>>>
>>>    /* Table of machine attributes.  */
>>>    static const struct attribute_spec arm_attribute_table[] =
>>> --- 269,276 ----
>>>
>>>    static bool arm_vectorize_vec_perm_const_ok (enum machine_mode vmode,
>>>                                               const unsigned char *sel);
>>> ! static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
>>> !                                        bool op0_preserve_value);
>>>
>>>    /* Table of machine attributes.  */
>>>    static const struct attribute_spec arm_attribute_table[] =
>>> *************** static const struct attribute_spec arm_a
>>> *** 626,631 ****
>>> --- 627,636 ----
>>>    #define TARGET_VECTORIZE_VEC_PERM_CONST_OK \
>>>      arm_vectorize_vec_perm_const_ok
>>>
>>> + #undef TARGET_CANONICALIZE_COMPARISON
>>> + #define TARGET_CANONICALIZE_COMPARISON \
>>> +   arm_canonicalize_comparison
>>> +
>>>    struct gcc_target targetm = TARGET_INITIALIZER;
>>>
>>>    /* Obstack for minipool constant handling.  */
>>> *************** arm_gen_constant (enum rtx_code code, en
>>> *** 3543,3550 ****
>>>       This can be done for a few constant compares, where we can make the
>>>       immediate value easier to load.  */
>>>
>>> ! enum rtx_code
>>> ! arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
>>>    {
>>>      enum machine_mode mode;
>>>      unsigned HOST_WIDE_INT i, maxval;
>>> --- 3548,3556 ----
>>>       This can be done for a few constant compares, where we can make the
>>>       immediate value easier to load.  */
>>>
>>> ! static void
>>> ! arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
>>> !                            bool op0_preserve_value)
>>>    {
>>>      enum machine_mode mode;
>>>      unsigned HOST_WIDE_INT i, maxval;
>>> *************** arm_canonicalize_comparison (enum rtx_co
>>> *** 3563,3577 ****
>>>        {
>>>          rtx tem;
>>>
>>> !       if (code == GT || code == LE
>>> !         || (!TARGET_ARM && (code == GTU || code == LEU)))
>>>          {
>>>            /* Missing comparison.  First try to use an available
>>>               comparison.  */
>>>            if (CONST_INT_P (*op1))
>>>              {
>>>                i = INTVAL (*op1);
>>> !             switch (code)
>>>                  {
>>>                  case GT:
>>>                  case LE:
>>> --- 3569,3583 ----
>>>        {
>>>          rtx tem;
>>>
>>> !       if (*code == GT || *code == LE
>>> !         || (!TARGET_ARM && (*code == GTU || *code == LEU)))
>>>          {
>>>            /* Missing comparison.  First try to use an available
>>>               comparison.  */
>>>            if (CONST_INT_P (*op1))
>>>              {
>>>                i = INTVAL (*op1);
>>> !             switch (*code)
>>>                  {
>>>                  case GT:
>>>                  case LE:
>>> *************** arm_canonicalize_comparison (enum rtx_co
>>> *** 3579,3585 ****
>>>                        && arm_const_double_by_immediates (GEN_INT (i +
>>> 1)))
>>>                      {
>>>                        *op1 = GEN_INT (i + 1);
>>> !                     return code == GT ? GE : LT;
>>>                      }
>>>                    break;
>>>                  case GTU:
>>> --- 3585,3592 ----
>>>                        && arm_const_double_by_immediates (GEN_INT (i +
>>> 1)))
>>>                      {
>>>                        *op1 = GEN_INT (i + 1);
>>> !                     *code = *code == GT ? GE : LT;
>>> !                     return;
>>>                      }
>>>                    break;
>>>                  case GTU:
>>> *************** arm_canonicalize_comparison (enum rtx_co
>>> *** 3588,3594 ****
>>>                        && arm_const_double_by_immediates (GEN_INT (i +
>>> 1)))
>>>                      {
>>>                        *op1 = GEN_INT (i + 1);
>>> !                     return code == GTU ? GEU : LTU;
>>>                      }
>>>                    break;
>>>                  default:
>>> --- 3595,3602 ----
>>>                        && arm_const_double_by_immediates (GEN_INT (i +
>>> 1)))
>>>                      {
>>>                        *op1 = GEN_INT (i + 1);
>>> !                     *code = *code == GTU ? GEU : LTU;
>>> !                     return;
>>>                      }
>>>                    break;
>>>                  default:
>>> *************** arm_canonicalize_comparison (enum rtx_co
>>> *** 3597,3615 ****
>>>              }
>>>
>>>            /* If that did not work, reverse the condition.  */
>>> !         tem = *op0;
>>> !         *op0 = *op1;
>>> !         *op1 = tem;
>>> !         return swap_condition (code);
>>>          }
>>> !
>>> !       return code;
>>>        }
>>>
>>>      /* If *op0 is (zero_extend:SI (subreg:QI (reg:SI) 0)) and comparing
>>>         with const0_rtx, change it to (and:SI (reg:SI) (const_int 255)),
>>>         to facilitate possible combining with a cmp into 'ands'.  */
>>> !   if (mode == SImode
>>>          && GET_CODE (*op0) == ZERO_EXTEND
>>>          && GET_CODE (XEXP (*op0, 0)) == SUBREG
>>>          && GET_MODE (XEXP (*op0, 0)) == QImode
>>> --- 3605,3626 ----
>>>              }
>>>
>>>            /* If that did not work, reverse the condition.  */
>>> !         if (!op0_preserve_value)
>>> !           {
>>> !             tem = *op0;
>>> !             *op0 = *op1;
>>> !             *op1 = tem;
>>> !             *code = (int)swap_condition ((enum rtx_code)*code);
>>> !           }
>>>          }
>>> !       return;
>>>        }
>>>
>>>      /* If *op0 is (zero_extend:SI (subreg:QI (reg:SI) 0)) and comparing
>>>         with const0_rtx, change it to (and:SI (reg:SI) (const_int 255)),
>>>         to facilitate possible combining with a cmp into 'ands'.  */
>>> !   if (!op0_preserve_value
>>> !       && mode == SImode
>>>          && GET_CODE (*op0) == ZERO_EXTEND
>>>          && GET_CODE (XEXP (*op0, 0)) == SUBREG
>>>          && GET_MODE (XEXP (*op0, 0)) == QImode
>>> *************** arm_canonicalize_comparison (enum rtx_co
>>> *** 3624,3638 ****
>>>      if (!CONST_INT_P (*op1)
>>>          || const_ok_for_arm (INTVAL (*op1))
>>>          || const_ok_for_arm (- INTVAL (*op1)))
>>> !     return code;
>>>
>>>      i = INTVAL (*op1);
>>>
>>> !   switch (code)
>>>        {
>>>        case EQ:
>>>        case NE:
>>> !       return code;
>>>
>>>        case GT:
>>>        case LE:
>>> --- 3635,3649 ----
>>>      if (!CONST_INT_P (*op1)
>>>          || const_ok_for_arm (INTVAL (*op1))
>>>          || const_ok_for_arm (- INTVAL (*op1)))
>>> !     return;
>>>
>>>      i = INTVAL (*op1);
>>>
>>> !   switch (*code)
>>>        {
>>>        case EQ:
>>>        case NE:
>>> !       return;
>>>
>>>        case GT:
>>>        case LE:
>>> *************** arm_canonicalize_comparison (enum rtx_co
>>> *** 3640,3646 ****
>>>            && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
>>>          {
>>>            *op1 = GEN_INT (i + 1);
>>> !         return code == GT ? GE : LT;
>>>          }
>>>          break;
>>>
>>> --- 3651,3658 ----
>>>            && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
>>>          {
>>>            *op1 = GEN_INT (i + 1);
>>> !         *code = *code == GT ? GE : LT;
>>> !         return;
>>>          }
>>>          break;
>>>
>>> *************** arm_canonicalize_comparison (enum rtx_co
>>> *** 3650,3656 ****
>>>            && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
>>>          {
>>>            *op1 = GEN_INT (i - 1);
>>> !         return code == GE ? GT : LE;
>>>          }
>>>          break;
>>>
>>> --- 3662,3669 ----
>>>            && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
>>>          {
>>>            *op1 = GEN_INT (i - 1);
>>> !         *code = *code == GE ? GT : LE;
>>> !         return;
>>>          }
>>>          break;
>>>
>>> *************** arm_canonicalize_comparison (enum rtx_co
>>> *** 3660,3666 ****
>>>            && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
>>>          {
>>>            *op1 = GEN_INT (i + 1);
>>> !         return code == GTU ? GEU : LTU;
>>>          }
>>>          break;
>>>
>>> --- 3673,3680 ----
>>>            && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
>>>          {
>>>            *op1 = GEN_INT (i + 1);
>>> !         *code = *code == GTU ? GEU : LTU;
>>> !         return;
>>>          }
>>>          break;
>>>
>>> *************** arm_canonicalize_comparison (enum rtx_co
>>> *** 3670,3684 ****
>>>            && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
>>>          {
>>>            *op1 = GEN_INT (i - 1);
>>> !         return code == GEU ? GTU : LEU;
>>>          }
>>>          break;
>>>
>>>        default:
>>>          gcc_unreachable ();
>>>        }
>>> -
>>> -   return code;
>>>    }
>>>
>>>
>>> --- 3684,3697 ----
>>>            && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
>>>          {
>>>            *op1 = GEN_INT (i - 1);
>>> !         *code = *code == GEU ? GTU : LEU;
>>> !         return;
>>>          }
>>>          break;
>>>
>>>        default:
>>>          gcc_unreachable ();
>>>        }
>>>    }
>>>
>>>
>>> *************** bool
>>> *** 26979,26985 ****
>>>    arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2)
>>>    {
>>>      enum rtx_code code = GET_CODE (*comparison);
>>> !   enum rtx_code canonical_code;
>>>      enum machine_mode mode = (GET_MODE (*op1) == VOIDmode)
>>>        ? GET_MODE (*op2) : GET_MODE (*op1);
>>>
>>> --- 26992,26998 ----
>>>    arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2)
>>>    {
>>>      enum rtx_code code = GET_CODE (*comparison);
>>> !   int code_int;
>>>      enum machine_mode mode = (GET_MODE (*op1) == VOIDmode)
>>>        ? GET_MODE (*op2) : GET_MODE (*op1);
>>>
>>> *************** arm_validize_comparison (rtx *comparison
>>> *** 26988,26995 ****
>>>      if (code == UNEQ || code == LTGT)
>>>        return false;
>>>
>>> !   canonical_code = arm_canonicalize_comparison (code, op1, op2);
>>> !   PUT_CODE (*comparison, canonical_code);
>>>
>>>      switch (mode)
>>>        {
>>> --- 27001,27009 ----
>>>      if (code == UNEQ || code == LTGT)
>>>        return false;
>>>
>>> !   code_int = (int)code;
>>> !   arm_canonicalize_comparison (&code_int, op1, op2, 0);
>>> !   PUT_CODE (*comparison, (enum rtx_code)code_int);
>>>
>>>      switch (mode)
>>>        {
>>> Index: gcc/config/arm/arm.h
>>> ===================================================================
>>> *** gcc/config/arm/arm.h.orig
>>> --- gcc/config/arm/arm.h
>>> *************** extern int making_const_table;
>>> *** 2078,2086 ****
>>>       ? reverse_condition_maybe_unordered (code) \
>>>       : reverse_condition (code))
>>>
>>> - #define CANONICALIZE_COMPARISON(CODE, OP0, OP1)
>>> \
>>> -   (CODE) = arm_canonicalize_comparison (CODE, &(OP0), &(OP1))
>>> -
>>>    /* The arm5 clz instruction returns 32.  */
>>>    #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
>>>    #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE)  ((VALUE) = 32, 1)
>>> --- 2078,2083 ----
>>> Index: gcc/config/s390/s390-protos.h
>>> ===================================================================
>>> *** gcc/config/s390/s390-protos.h.orig
>>> --- gcc/config/s390/s390-protos.h
>>> *************** extern int tls_symbolic_operand (rtx);
>>> *** 58,64 ****
>>>    extern bool s390_match_ccmode (rtx, enum machine_mode);
>>>    extern enum machine_mode s390_tm_ccmode (rtx, rtx, bool);
>>>    extern enum machine_mode s390_select_ccmode (enum rtx_code, rtx, rtx);
>>> - extern void s390_canonicalize_comparison (enum rtx_code *, rtx *, rtx
>>> *);
>>>    extern rtx s390_emit_compare (enum rtx_code, rtx, rtx);
>>>    extern void s390_emit_jump (rtx, rtx);
>>>    extern bool symbolic_reference_mentioned_p (rtx);
>>> --- 58,63 ----
>>> Index: gcc/config/s390/s390.c
>>> ===================================================================
>>> *** gcc/config/s390/s390.c.orig
>>> --- gcc/config/s390/s390.c
>>> *************** s390_select_ccmode (enum rtx_code code,
>>> *** 745,753 ****
>>>    /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
>>>       that we can implement more efficiently.  */
>>>
>>> ! void
>>> ! s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
>>>    {
>>>      /* Convert ZERO_EXTRACT back to AND to enable TM patterns.  */
>>>      if ((*code == EQ || *code == NE)
>>>          && *op1 == const0_rtx
>>> --- 745,757 ----
>>>    /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
>>>       that we can implement more efficiently.  */
>>>
>>> ! static void
>>> ! s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
>>> !                             bool op0_preserve_value)
>>>    {
>>> +   if (op0_preserve_value)
>>> +     return;
>>> +
>>>      /* Convert ZERO_EXTRACT back to AND to enable TM patterns.  */
>>>      if ((*code == EQ || *code == NE)
>>>          && *op1 == const0_rtx
>>> *************** s390_canonicalize_comparison (enum rtx_c
>>> *** 894,900 ****
>>>      if (MEM_P (*op0) && REG_P (*op1))
>>>        {
>>>          rtx tem = *op0; *op0 = *op1; *op1 = tem;
>>> !       *code = swap_condition (*code);
>>>        }
>>>    }
>>>
>>> --- 898,904 ----
>>>      if (MEM_P (*op0) && REG_P (*op1))
>>>        {
>>>          rtx tem = *op0; *op0 = *op1; *op1 = tem;
>>> !       *code = (int)swap_condition ((enum rtx_code)*code);
>>>        }
>>>    }
>>>
>>> *************** s390_loop_unroll_adjust (unsigned nunrol
>>> *** 11071,11076 ****
>>> --- 11075,11083 ----
>>>    #undef TARGET_UNWIND_WORD_MODE
>>>    #define TARGET_UNWIND_WORD_MODE s390_unwind_word_mode
>>>
>>> + #undef TARGET_CANONICALIZE_COMPARISON
>>> + #define TARGET_CANONICALIZE_COMPARISON s390_canonicalize_comparison
>>> +
>>>    struct gcc_target targetm = TARGET_INITIALIZER;
>>>
>>>    #include "gt-s390.h"
>>> Index: gcc/config/s390/s390.h
>>> ===================================================================
>>> *** gcc/config/s390/s390.h.orig
>>> --- gcc/config/s390/s390.h
>>> *************** do {
>>> \
>>> *** 720,729 ****
>>>       return the mode to be used for the comparison.  */
>>>    #define SELECT_CC_MODE(OP, X, Y) s390_select_ccmode ((OP), (X), (Y))
>>>
>>> - /* Canonicalize a comparison from one we don't have to one we do have.
>>> */
>>> - #define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
>>> -   s390_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
>>> -
>>>    /* Relative costs of operations.  */
>>>
>>>    /* A C expression for the cost of a branch instruction.  A value of 1
>>> --- 720,725 ----
>>> Index: gcc/config/sh/sh-protos.h
>>> ===================================================================
>>> *** gcc/config/sh/sh-protos.h.orig
>>> --- gcc/config/sh/sh-protos.h
>>> *************** extern bool sh_expand_t_scc (rtx *);
>>> *** 159,166 ****
>>>    extern rtx sh_gen_truncate (enum machine_mode, rtx, int);
>>>    extern bool sh_vector_mode_supported_p (enum machine_mode);
>>>    extern bool sh_cfun_trap_exit_p (void);
>>> - extern void sh_canonicalize_comparison (enum rtx_code&, rtx&, rtx&,
>>> -                                       enum machine_mode mode =
>>> VOIDmode);
>>>    extern rtx sh_find_equiv_gbr_addr (rtx cur_insn, rtx mem);
>>>    extern int sh_eval_treg_value (rtx op);
>>>
>>> --- 159,164 ----
>>> Index: gcc/config/sh/sh.c
>>> ===================================================================
>>> *** gcc/config/sh/sh.c.orig
>>> --- gcc/config/sh/sh.c
>>> *************** static int max_mov_insn_displacement (en
>>> *** 314,319 ****
>>> --- 314,322 ----
>>>    static int mov_insn_alignment_mask (enum machine_mode, bool);
>>>    static HOST_WIDE_INT disp_addr_displacement (rtx);
>>>    static bool sequence_insn_p (rtx);
>>> + static void sh_canonicalize_comparison (int *, rtx *, rtx *, bool);
>>> + static void sh_canonicalize_comparison (enum rtx_code&, rtx&, rtx&,
>>> +                                       enum machine_mode, bool);
>>>
>>>    static void sh_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
>>>
>>> *************** static const struct attribute_spec sh_at
>>> *** 586,591 ****
>>> --- 589,597 ----
>>>    #undef TARGET_LEGITIMATE_CONSTANT_P
>>>    #define TARGET_LEGITIMATE_CONSTANT_P  sh_legitimate_constant_p
>>>
>>> + #undef TARGET_CANONICALIZE_COMPARISON
>>> + #define TARGET_CANONICALIZE_COMPARISON        sh_canonicalize_comparison
>>> +
>>>    /* Machine-specific symbol_ref flags.  */
>>>    #define SYMBOL_FLAG_FUNCVEC_FUNCTION    (SYMBOL_FLAG_MACH_DEP << 0)
>>>
>>> *************** prepare_move_operands (rtx operands[], e
>>> *** 1909,1920 ****
>>>        }
>>>    }
>>>
>>> ! /* Implement the CANONICALIZE_COMPARISON macro for the combine pass.
>>> !    This function is also re-used to canonicalize comparisons in cbranch
>>> !    pattern expanders.  */
>>> ! void
>>>    sh_canonicalize_comparison (enum rtx_code& cmp, rtx& op0, rtx& op1,
>>> !                           enum machine_mode mode)
>>>    {
>>>      /* When invoked from within the combine pass the mode is not
>>> specified,
>>>         so try to get it from one of the operands.  */
>>> --- 1915,1928 ----
>>>        }
>>>    }
>>>
>>> ! /* Implement the canonicalize_comparison target hook for the combine
>>> !    pass.  For the target hook this function is invoked via
>>> !    sh_canonicalize_comparison.  This function is also re-used to
>>> !    canonicalize comparisons in cbranch pattern expanders.  */
>>> ! static void
>>>    sh_canonicalize_comparison (enum rtx_code& cmp, rtx& op0, rtx& op1,
>>> !                           enum machine_mode mode,
>>> !                           bool op0_preserve_value ATTRIBUTE_UNUSED)
>>>    {
>>>      /* When invoked from within the combine pass the mode is not
>>> specified,
>>>         so try to get it from one of the operands.  */
>>> *************** sh_canonicalize_comparison (enum rtx_cod
>>> *** 2008,2013 ****
>>> --- 2016,2034 ----
>>>        }
>>>    }
>>>
>>> + /* This function implements the canonicalize_comparison target hook.
>>> +    This wrapper around the internally used sh_canonicalize_comparison
>>> +    function is needed to do the enum rtx_code <-> int conversion.
>>> +    Target hooks cannot use enum rtx_code in its definition.  */
>>> + static void
>>> + sh_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
>>> +                           bool op0_preserve_value)
>>> + {
>>> +   enum rtx_code tmp_code = (enum rtx_code)*code;
>>> +   sh_canonicalize_comparison (tmp_code, *op0, *op1,
>>> +                             VOIDmode, op0_preserve_value);
>>> +   *code = (int)tmp_code;
>>> + }
>>>    enum rtx_code
>>>    prepare_cbranch_operands (rtx *operands, enum machine_mode mode,
>>>                            enum rtx_code comparison)
>>> *************** prepare_cbranch_operands (rtx *operands,
>>> *** 2021,2027 ****
>>>      else
>>>        scratch = operands[4];
>>>
>>> !   sh_canonicalize_comparison (comparison, operands[1], operands[2],
>>> mode);
>>>
>>>      /* Notice that this function is also invoked after reload by
>>>         the cbranchdi4_i pattern, through expand_cbranchdi4.  */
>>> --- 2042,2049 ----
>>>      else
>>>        scratch = operands[4];
>>>
>>> !   sh_canonicalize_comparison (comparison, operands[1], operands[2],
>>> !                             mode, false);
>>>
>>>      /* Notice that this function is also invoked after reload by
>>>         the cbranchdi4_i pattern, through expand_cbranchdi4.  */
>>> Index: gcc/config/sh/sh.h
>>> ===================================================================
>>> *** gcc/config/sh/sh.h.orig
>>> --- gcc/config/sh/sh.h
>>> *************** struct sh_args {
>>> *** 1873,1882 ****
>>>       more compact code.  */
>>>    #define SHIFT_COUNT_TRUNCATED (0)
>>>
>>> - /* CANONICALIZE_COMPARISON macro for the combine pass.  */
>>> - #define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
>>> -   sh_canonicalize_comparison ((CODE), (OP0), (OP1))
>>> -
>>>    /* All integers have the same format so truncation is easy.  */
>>>    /* But SHmedia must sign-extend DImode when truncating to SImode.  */
>>>    #define TRULY_NOOP_TRUNCATION(OUTPREC,INPREC) \
>>> --- 1873,1878 ----
>>> Index: gcc/config/spu/spu.c
>>> ===================================================================
>>> *** gcc/config/spu/spu.c.orig
>>> --- gcc/config/spu/spu.c
>>> *************** spu_output_mi_thunk (FILE *file, tree th
>>> *** 7095,7100 ****
>>> --- 7095,7114 ----
>>>      final_end_function ();
>>>    }
>>>
>>> + /* Canonicalize a comparison from one we don't have to one we do have.
>>> */
>>> + static void
>>> + spu_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
>>> +                            bool op0_preserve_value)
>>> + {
>>> +   if (!op0_preserve_value
>>> +       && (*code == LE || *code == LT || *code == LEU || *code == LTU))
>>> +     {
>>> +       rtx tem = *op0;
>>> +       *op0 = *op1;
>>> +       *op1 = tem;
>>> +       *code = (int)swap_condition ((enum rtx_code)*code);
>>> +     }
>>> + }
>>>
>>>    /*  Table of machine attributes.  */
>>>    static const struct attribute_spec spu_attribute_table[] =
>>> *************** static const struct attribute_spec spu_a
>>> *** 7308,7313 ****
>>> --- 7322,7330 ----
>>>    #undef TARGET_DELAY_VARTRACK
>>>    #define TARGET_DELAY_VARTRACK true
>>>
>>> + #undef TARGET_CANONICALIZE_COMPARISON
>>> + #define TARGET_CANONICALIZE_COMPARISON spu_canonicalize_comparison
>>> +
>>>    struct gcc_target targetm = TARGET_INITIALIZER;
>>>
>>>    #include "gt-spu.h"
>>> Index: gcc/config/spu/spu.h
>>> ===================================================================
>>> *** gcc/config/spu/spu.h.orig
>>> --- gcc/config/spu/spu.h
>>> *************** do {
>>> \
>>> *** 520,537 ****
>>>
>>>    #define NO_IMPLICIT_EXTERN_C 1
>>>
>>> - /* Canonicalize a comparison from one we don't have to one we do have.
>>> */
>>> - #define CANONICALIZE_COMPARISON(CODE,OP0,OP1) \
>>> -   do {
>>> \
>>> -     if (((CODE) == LE || (CODE) == LT || (CODE) == LEU || (CODE) ==
>>> LTU)) \
>>> -       {
>>> \
>>> -         rtx tem = (OP0);
>>> \
>>> -         (OP0) = (OP1);
>>> \
>>> -         (OP1) = tem;
>>> \
>>> -         (CODE) = swap_condition (CODE);
>>> \
>>> -       }
>>> \
>>> -   } while (0)
>>> -
>>>
>>>    /* Address spaces.  */
>>>    #define ADDR_SPACE_EA 1
>>> --- 520,525 ----
>>> Index: gcc/doc/tm.texi.in
>>> ===================================================================
>>> *** gcc/doc/tm.texi.in.orig
>>> --- gcc/doc/tm.texi.in
>>> *************** You should define this macro if and only
>>> *** 5928,5952 ****
>>>    in @file{@var{machine}-modes.def}.
>>>    @end defmac
>>>
>>> ! @defmac CANONICALIZE_COMPARISON (@var{code}, @var{op0}, @var{op1})
>>>    On some machines not all possible comparisons are defined, but you can
>>>    convert an invalid comparison into a valid one.  For example, the Alpha
>>>    does not have a @code{GT} comparison, but you can use an @code{LT}
>>>    comparison instead and swap the order of the operands.
>>>
>>> ! On such machines, define this macro to be a C statement to do any
>>> ! required conversions.  @var{code} is the initial comparison code
>>> ! and @var{op0} and @var{op1} are the left and right operands of the
>>> ! comparison, respectively.  You should modify @var{code}, @var{op0}, and
>>> ! @var{op1} as required.
>>>
>>>    GCC will not assume that the comparison resulting from this macro is
>>>    valid but will see if the resulting insn matches a pattern in the
>>>    @file{md} file.
>>>
>>> ! You need not define this macro if it would never change the comparison
>>> ! code or operands.
>>> ! @end defmac
>>>
>>>    @defmac REVERSIBLE_CC_MODE (@var{mode})
>>>    A C expression whose value is one if it is always safe to reverse a
>>> --- 5928,5954 ----
>>>    in @file{@var{machine}-modes.def}.
>>>    @end defmac
>>>
>>> ! @hook TARGET_CANONICALIZE_COMPARISON (@var{code}, @var{op0}, @var{op1},
>>> @var{op0_preserve_value})
>>>    On some machines not all possible comparisons are defined, but you can
>>>    convert an invalid comparison into a valid one.  For example, the Alpha
>>>    does not have a @code{GT} comparison, but you can use an @code{LT}
>>>    comparison instead and swap the order of the operands.
>>>
>>> ! On such machines, implement this hook to do any required conversions.
>>> ! @var{code} is the initial comparison code and @var{op0} and @var{op1}
>>> ! are the left and right operands of the comparison, respectively.  If
>>> ! @var{op0_preserve_value} is @code{true} the implementation is not
>>> ! allowed to change the value of @var{op0} since the value might be used
>>> ! in RTXs which aren't comparisons.  E.g. the implementation is not
>>> ! allowed to swap operands in that case.
>>>
>>>    GCC will not assume that the comparison resulting from this macro is
>>>    valid but will see if the resulting insn matches a pattern in the
>>>    @file{md} file.
>>>
>>> ! You need not to implement this hook if it would never change the
>>> ! comparison code or operands.
>>> ! @end deftypefn
>>>
>>>    @defmac REVERSIBLE_CC_MODE (@var{mode})
>>>    A C expression whose value is one if it is always safe to reverse a
>>> Index: gcc/target.def
>>> ===================================================================
>>> *** gcc/target.def.orig
>>> --- gcc/target.def
>>> *************** DEFHOOK
>>> *** 2877,2882 ****
>>> --- 2877,2890 ----
>>>     enum unwind_info_type, (void),
>>>     default_debug_unwind_info)
>>>
>>> + /* The code parameter should be of type enum rtx_code but this is not
>>> +    defined at this time.  */
>>> + DEFHOOK
>>> + (canonicalize_comparison,
>>> +  "",
>>> +  void, (int *code, rtx *op0, rtx *op1, bool op0_preserve_value),
>>> +  default_canonicalize_comparison)
>>> +
>>>    DEFHOOKPOD
>>>    (atomic_test_and_set_trueval,
>>>     "This value should be set if the result written by\
>>> Index: gcc/targhooks.h
>>> ===================================================================
>>> *** gcc/targhooks.h.orig
>>> --- gcc/targhooks.h
>>> *************** extern unsigned char default_class_max_n
>>> *** 179,184 ****
>>> --- 179,186 ----
>>>
>>>    extern enum unwind_info_type default_debug_unwind_info (void);
>>>
>>> + extern bool default_canonicalize_comparison (int *, rtx *, rtx *, bool);
>>> +
>>>    extern int default_label_align_after_barrier_max_skip (rtx);
>>>    extern int default_loop_align_max_skip (rtx);
>>>    extern int default_label_align_max_skip (rtx);
>>> Index: gcc/doc/tm.texi
>>> ===================================================================
>>> *** gcc/doc/tm.texi.orig
>>> --- gcc/doc/tm.texi
>>> *************** You should define this macro if and only
>>> *** 6024,6048 ****
>>>    in @file{@var{machine}-modes.def}.
>>>    @end defmac
>>>
>>> ! @defmac CANONICALIZE_COMPARISON (@var{code}, @var{op0}, @var{op1})
>>>    On some machines not all possible comparisons are defined, but you can
>>>    convert an invalid comparison into a valid one.  For example, the Alpha
>>>    does not have a @code{GT} comparison, but you can use an @code{LT}
>>>    comparison instead and swap the order of the operands.
>>>
>>> ! On such machines, define this macro to be a C statement to do any
>>> ! required conversions.  @var{code} is the initial comparison code
>>> ! and @var{op0} and @var{op1} are the left and right operands of the
>>> ! comparison, respectively.  You should modify @var{code}, @var{op0}, and
>>> ! @var{op1} as required.
>>>
>>>    GCC will not assume that the comparison resulting from this macro is
>>>    valid but will see if the resulting insn matches a pattern in the
>>>    @file{md} file.
>>>
>>> ! You need not define this macro if it would never change the comparison
>>> ! code or operands.
>>> ! @end defmac
>>>
>>>    @defmac REVERSIBLE_CC_MODE (@var{mode})
>>>    A C expression whose value is one if it is always safe to reverse a
>>> --- 6024,6050 ----
>>>    in @file{@var{machine}-modes.def}.
>>>    @end defmac
>>>
>>> ! @deftypefn {Target Hook} void TARGET_CANONICALIZE_COMPARISON (int
>>> *@var{code}, rtx *@var{op0}, rtx
>>> *@var{op1}, bool @var{op0_preserve_value}) (@var{code}, @var{op0},
>>> @var{op1}, @var{op0_preserve_value})
>>>    On some machines not all possible comparisons are defined, but you can
>>>    convert an invalid comparison into a valid one.  For example, the Alpha
>>>    does not have a @code{GT} comparison, but you can use an @code{LT}
>>>    comparison instead and swap the order of the operands.
>>>
>>> ! On such machines, implement this hook to do any required conversions.
>>> ! @var{code} is the initial comparison code and @var{op0} and @var{op1}
>>> ! are the left and right operands of the comparison, respectively.  If
>>> ! @var{op0_preserve_value} is @code{true} the implementation is not
>>> ! allowed to change the value of @var{op0} since the value might be used
>>> ! in RTXs which aren't comparisons.  E.g. the implementation is not
>>> ! allowed to swap operands in that case.
>>>
>>>    GCC will not assume that the comparison resulting from this macro is
>>>    valid but will see if the resulting insn matches a pattern in the
>>>    @file{md} file.
>>>
>>> ! You need not to implement this hook if it would never change the
>>> ! comparison code or operands.
>>> ! @end deftypefn
>>>
>>>    @defmac REVERSIBLE_CC_MODE (@var{mode})
>>>    A C expression whose value is one if it is always safe to reverse a
>>>
>>>
>>>
>>>
>>
>>


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