diff mbox series

[5/7] Allow match-and-simplified phiopt to run in early phiopt

Message ID 1624138980-5805-1-git-send-email-apinski@marvell.com
State New
Headers show
Series None | expand

Commit Message

Li, Pan2 via Gcc-patches June 19, 2021, 9:42 p.m. UTC
From: Andrew Pinski <apinski@marvell.com>

To move a few things more to match-and-simplify from phiopt,
we need to allow match_simplify_replacement to run in early
phiopt.  To do this, we need to mark some match patterns
if they can be done in early phiopt or not.

OK? Bootstrapped and tested on x86_64-linux-gnu with no
regressions.

gcc/ChangeLog:

	* generic-match-head.c (phiopt_earlymode): New function.
	* gimple-match-head.c (phiopt_earlymode): New function.
	* match.pd (A ? CST0 : CST1): Disable for early phiopt.
	(x >= 0 ? ~y : y): Likewise.
	(x >= 0 ? y : ~y): Likewise.
	* tree-pass.h (PROP_gimple_lomp_dev): Increment bit by one.
	(PROP_rtl_split_insns): Likewise.
	(PROP_phioptearly): New define.
	* tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Set and unset
	PROP_phioptearly on curr_properties if early.
---
 gcc/generic-match-head.c |  7 +++++
 gcc/gimple-match-head.c  |  7 +++++
 gcc/match.pd             | 76 ++++++++++++++++++++++++++----------------------
 gcc/tree-pass.h          |  5 ++--
 gcc/tree-ssa-phiopt.c    |  8 +++--
 5 files changed, 63 insertions(+), 40 deletions(-)

Comments

Richard Biener June 21, 2021, 9:49 a.m. UTC | #1
On Sat, Jun 19, 2021 at 11:44 PM apinski--- via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> From: Andrew Pinski <apinski@marvell.com>
>
> To move a few things more to match-and-simplify from phiopt,
> we need to allow match_simplify_replacement to run in early
> phiopt.  To do this, we need to mark some match patterns
> if they can be done in early phiopt or not.
>
> OK? Bootstrapped and tested on x86_64-linux-gnu with no
> regressions.

I wonder if it would be easier to change

  result = gimple_simplify (COND_EXPR, type,
                            cond,
                            arg0, arg1,
                            &seq, NULL);

to

  gimple_match_op op (gimple_match_cond::UNCOND,
                                      COND_EXPR, type, arg0, arg1);
  if (op.resimplify (early_p ? NULL : &seq, NULL))
    {
       /* Early we only want MIN/MAX, etc.  */
       if (early_p
          && (!op.code.is_tree_code ()
                 || (tree_code)op.code != ...))
         return false;
      result = mabe_push_res_to_seq (op, &seq);
      if (!result)
         ...

thus avoid complex transforms by passing a NULL seq.  'op'
will be the piecewise result which you can check before
eventually re-materializing it as GIMPLE stmt via
mabe_push_res_to_seq.

Note I didn't really try to look at the ultimate results of allowing
all phi-opts early but the testsuite fallout was spectacular as
(too) simple jump-threading tests fail since the code is no longer
jumpy as we arrive at the first DOM/VRP ...

Richard.

> gcc/ChangeLog:
>
>         * generic-match-head.c (phiopt_earlymode): New function.
>         * gimple-match-head.c (phiopt_earlymode): New function.
>         * match.pd (A ? CST0 : CST1): Disable for early phiopt.
>         (x >= 0 ? ~y : y): Likewise.
>         (x >= 0 ? y : ~y): Likewise.
>         * tree-pass.h (PROP_gimple_lomp_dev): Increment bit by one.
>         (PROP_rtl_split_insns): Likewise.
>         (PROP_phioptearly): New define.
>         * tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Set and unset
>         PROP_phioptearly on curr_properties if early.
> ---
>  gcc/generic-match-head.c |  7 +++++
>  gcc/gimple-match-head.c  |  7 +++++
>  gcc/match.pd             | 76 ++++++++++++++++++++++++++----------------------
>  gcc/tree-pass.h          |  5 ++--
>  gcc/tree-ssa-phiopt.c    |  8 +++--
>  5 files changed, 63 insertions(+), 40 deletions(-)
>
> diff --git a/gcc/generic-match-head.c b/gcc/generic-match-head.c
> index f426208..90ebf84 100644
> --- a/gcc/generic-match-head.c
> +++ b/gcc/generic-match-head.c
> @@ -91,6 +91,13 @@ optimize_vectors_before_lowering_p ()
>    return true;
>  }
>
> +/* Return true if phiopt is in early mode. */
> +static inline bool
> +phiopt_earlymode ()
> +{
> +  return false;
> +}
> +
>  /* Return true if successive divisions can be optimized.
>     Defer to GIMPLE opts.  */
>
> diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c
> index 7112c11..1eafbb7 100644
> --- a/gcc/gimple-match-head.c
> +++ b/gcc/gimple-match-head.c
> @@ -1159,6 +1159,13 @@ canonicalize_math_after_vectorization_p ()
>    return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
>  }
>
> +/* Return true if phiopt is in early mode. */
> +static inline bool
> +phiopt_earlymode ()
> +{
> +  return !cfun || (cfun->curr_properties & PROP_phioptearly) != 0;
> +}
> +
>  /* Return true if we can still perform transformations that may introduce
>     vector operations that are not supported by the target. Vector lowering
>     normally handles those, but after that pass, it becomes unsafe.  */
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 39fb57e..f38baf2 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -3728,39 +3728,40 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>  #if GIMPLE
>  (simplify
>   (cond @0 INTEGER_CST@1 INTEGER_CST@2)
> - (switch
> -  (if (integer_zerop (@2))
> -   (switch
> -    /* a ? 1 : 0 -> a if 0 and 1 are integral types. */
> -    (if (integer_onep (@1))
> -     (convert (convert:boolean_type_node @0)))
> -    /* a ? -1 : 0 -> -a. */
> -    (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1))
> -     (negate (convert (convert:boolean_type_node @0))))
> -    /* a ? powerof2cst : 0 -> a << (log2(powerof2cst)) */
> -    (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@1))
> -     (with {
> -       tree shift = build_int_cst (integer_type_node, tree_log2 (@1));
> -      }
> -      (lshift (convert (convert:boolean_type_node @0)) { shift; })))))
> -  (if (integer_zerop (@1))
> -   (with {
> -      tree booltrue = constant_boolean_node (true, boolean_type_node);
> -    }
> + (if (!phiopt_earlymode ())
> +  (switch
> +   (if (integer_zerop (@2))
>      (switch
> -     /* a ? 0 : 1 -> !a. */
> -     (if (integer_onep (@2))
> -      (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )))
> -     /* a ? -1 : 0 -> -(!a). */
> -     (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2))
> -      (negate (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))))
> -     /* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */
> -     (if (INTEGRAL_TYPE_P (type) &&  integer_pow2p (@2))
> +     /* a ? 1 : 0 -> a if 0 and 1 are integral types. */
> +     (if (integer_onep (@1))
> +      (convert (convert:boolean_type_node @0)))
> +     /* a ? -1 : 0 -> -a. */
> +     (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1))
> +      (negate (convert (convert:boolean_type_node @0))))
> +     /* a ? powerof2cst : 0 -> a << (log2(powerof2cst)) */
> +     (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@1))
>        (with {
> -       tree shift = build_int_cst (integer_type_node, tree_log2 (@2));
> +        tree shift = build_int_cst (integer_type_node, tree_log2 (@1));
>         }
> -       (lshift (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))
> -        { shift; }))))))))
> +       (lshift (convert (convert:boolean_type_node @0)) { shift; })))))
> +   (if (integer_zerop (@1))
> +    (with {
> +       tree booltrue = constant_boolean_node (true, boolean_type_node);
> +     }
> +     (switch
> +      /* a ? 0 : 1 -> !a. */
> +      (if (integer_onep (@2))
> +       (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )))
> +      /* a ? -1 : 0 -> -(!a). */
> +      (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2))
> +       (negate (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))))
> +      /* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */
> +      (if (INTEGRAL_TYPE_P (type) &&  integer_pow2p (@2))
> +       (with {
> +        tree shift = build_int_cst (integer_type_node, tree_log2 (@2));
> +        }
> +        (lshift (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))
> +         { shift; })))))))))
>  #endif
>
>  /* Simplification moved from fold_cond_expr_with_comparison.  It may also
> @@ -4891,7 +4892,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>  /* x >= 0 ? ~y : y into ~((x >> (prec-1)) ^ y). */
>   (simplify
>    (cond (cmp @0 integer_zerop) (bit_not @1) @1)
> -   (if (INTEGRAL_TYPE_P (type)
> +   (if (!phiopt_earlymode ()
> +       && INTEGRAL_TYPE_P (type)
>         && INTEGRAL_TYPE_P (TREE_TYPE (@0))
>          && !TYPE_UNSIGNED (TREE_TYPE (@0))
>          && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type))
> @@ -4906,7 +4908,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>  /* x >= 0 ? y : ~y into (x >> (prec-1)) ^ y. */
>   (simplify
>    (cond (cmp @0 integer_zerop) @1 (bit_not @1))
> -   (if (INTEGRAL_TYPE_P (type)
> +   (if (!phiopt_earlymode ()
> +       && INTEGRAL_TYPE_P (type)
>         && INTEGRAL_TYPE_P (TREE_TYPE (@0))
>          && !TYPE_UNSIGNED (TREE_TYPE (@0))
>          && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type))
> @@ -4924,7 +4927,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>   (cond
>    (ne (bit_and @0 integer_pow2p@1) integer_zerop)
>    INTEGER_CST@2 integer_zerop)
> - (if (!POINTER_TYPE_P (type) && integer_pow2p (@2))
> + (if (!phiopt_earlymode ()
> +      && !POINTER_TYPE_P (type) && integer_pow2p (@2))
>    (with {
>       int shift = (wi::exact_log2 (wi::to_wide (@2))
>                   - wi::exact_log2 (wi::to_wide (@1)));
> @@ -4942,7 +4946,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>       ncmp (ge lt)
>   (simplify
>    (cmp (bit_and (convert?@2 @0) integer_pow2p@1) integer_zerop)
> -  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
> +  (if (!phiopt_earlymode ()
> +       && INTEGRAL_TYPE_P (TREE_TYPE (@0))
>         && type_has_mode_precision_p (TREE_TYPE (@0))
>         && element_precision (@2) >= element_precision (@0)
>         && wi::only_sign_bit_p (wi::to_wide (@1), element_precision (@0)))
> @@ -4955,7 +4960,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>   (cond
>    (lt @0 integer_zerop)
>    INTEGER_CST@1 integer_zerop)
> - (if (integer_pow2p (@1)
> + (if (!phiopt_earlymode ()
> +      && integer_pow2p (@1)
>        && !TYPE_UNSIGNED (TREE_TYPE (@0)))
>    (with {
>      int shift = element_precision (@0) - wi::exact_log2 (wi::to_wide (@1)) - 1;
> diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
> index 15693fe..07ee151 100644
> --- a/gcc/tree-pass.h
> +++ b/gcc/tree-pass.h
> @@ -222,8 +222,9 @@ protected:
>                                                    of math functions; the
>                                                    current choices have
>                                                    been optimized.  */
> -#define PROP_gimple_lomp_dev   (1 << 16)       /* done omp_device_lower */
> -#define PROP_rtl_split_insns   (1 << 17)       /* RTL has insns split.  */
> +#define PROP_phioptearly       (1 << 16)       /* Sets while phiopt is in early mode. */
> +#define PROP_gimple_lomp_dev   (1 << 17)       /* done omp_device_lower */
> +#define PROP_rtl_split_insns   (1 << 18)       /* RTL has insns split.  */
>
>  #define PROP_gimple \
>    (PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_lomp)
> diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
> index 3b3762a..8b289be 100644
> --- a/gcc/tree-ssa-phiopt.c
> +++ b/gcc/tree-ssa-phiopt.c
> @@ -175,6 +175,8 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
>    unsigned n, i;
>    bool cfgchanged = false;
>    hash_set<tree> *nontrap = 0;
> +  if (early_p)
> +    cfun->curr_properties |= PROP_phioptearly;
>
>    calculate_dominance_info (CDI_DOMINATORS);
>
> @@ -345,9 +347,8 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
>           /* Do the replacement of conditional if it can be done.  */
>           if (!early_p && two_value_replacement (bb, bb1, e2, phi, arg0, arg1))
>             cfgchanged = true;
> -         else if (!early_p
> -                  && match_simplify_replacement (bb, bb1, e1, e2, phi,
> -                                                 arg0, arg1))
> +         else if (match_simplify_replacement (bb, bb1, e1, e2, phi,
> +                                              arg0, arg1))
>             cfgchanged = true;
>           else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
>             cfgchanged = true;
> @@ -364,6 +365,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
>      }
>
>    free (bb_order);
> +  cfun->curr_properties &= ~PROP_phioptearly;
>
>    if (do_store_elim)
>      delete nontrap;
> --
> 1.8.3.1
>
Andrew Pinski June 23, 2021, 8:23 a.m. UTC | #2
On Mon, Jun 21, 2021 at 2:50 AM Richard Biener via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Sat, Jun 19, 2021 at 11:44 PM apinski--- via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > From: Andrew Pinski <apinski@marvell.com>
> >
> > To move a few things more to match-and-simplify from phiopt,
> > we need to allow match_simplify_replacement to run in early
> > phiopt.  To do this, we need to mark some match patterns
> > if they can be done in early phiopt or not.
> >
> > OK? Bootstrapped and tested on x86_64-linux-gnu with no
> > regressions.
>
> I wonder if it would be easier to change
>
>   result = gimple_simplify (COND_EXPR, type,
>                             cond,
>                             arg0, arg1,
>                             &seq, NULL);
>
> to
>
>   gimple_match_op op (gimple_match_cond::UNCOND,
>                                       COND_EXPR, type, arg0, arg1);
>   if (op.resimplify (early_p ? NULL : &seq, NULL))
>     {
>        /* Early we only want MIN/MAX, etc.  */
>        if (early_p
>           && (!op.code.is_tree_code ()
>                  || (tree_code)op.code != ...))
>          return false;
>       result = mabe_push_res_to_seq (op, &seq);
>       if (!result)
>          ...
>
> thus avoid complex transforms by passing a NULL seq.  'op'
> will be the piecewise result which you can check before
> eventually re-materializing it as GIMPLE stmt via
> mabe_push_res_to_seq.

This sounds like a good idea and I have an implementation for it
and it seems to work.

>
> Note I didn't really try to look at the ultimate results of allowing
> all phi-opts early but the testsuite fallout was spectacular as
> (too) simple jump-threading tests fail since the code is no longer
> jumpy as we arrive at the first DOM/VRP ...

One thing I noticed when I tried having non-early mode before was that
the if-to-switch optimization also needed "a ? CST1 : CST2" conversion
to happen early. I did not check out fully or even record which testcases
failed.

Thanks,
Andrew

>
> Richard.
>
> > gcc/ChangeLog:
> >
> >         * generic-match-head.c (phiopt_earlymode): New function.
> >         * gimple-match-head.c (phiopt_earlymode): New function.
> >         * match.pd (A ? CST0 : CST1): Disable for early phiopt.
> >         (x >= 0 ? ~y : y): Likewise.
> >         (x >= 0 ? y : ~y): Likewise.
> >         * tree-pass.h (PROP_gimple_lomp_dev): Increment bit by one.
> >         (PROP_rtl_split_insns): Likewise.
> >         (PROP_phioptearly): New define.
> >         * tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Set and unset
> >         PROP_phioptearly on curr_properties if early.
> > ---
> >  gcc/generic-match-head.c |  7 +++++
> >  gcc/gimple-match-head.c  |  7 +++++
> >  gcc/match.pd             | 76 ++++++++++++++++++++++++++----------------------
> >  gcc/tree-pass.h          |  5 ++--
> >  gcc/tree-ssa-phiopt.c    |  8 +++--
> >  5 files changed, 63 insertions(+), 40 deletions(-)
> >
> > diff --git a/gcc/generic-match-head.c b/gcc/generic-match-head.c
> > index f426208..90ebf84 100644
> > --- a/gcc/generic-match-head.c
> > +++ b/gcc/generic-match-head.c
> > @@ -91,6 +91,13 @@ optimize_vectors_before_lowering_p ()
> >    return true;
> >  }
> >
> > +/* Return true if phiopt is in early mode. */
> > +static inline bool
> > +phiopt_earlymode ()
> > +{
> > +  return false;
> > +}
> > +
> >  /* Return true if successive divisions can be optimized.
> >     Defer to GIMPLE opts.  */
> >
> > diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c
> > index 7112c11..1eafbb7 100644
> > --- a/gcc/gimple-match-head.c
> > +++ b/gcc/gimple-match-head.c
> > @@ -1159,6 +1159,13 @@ canonicalize_math_after_vectorization_p ()
> >    return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
> >  }
> >
> > +/* Return true if phiopt is in early mode. */
> > +static inline bool
> > +phiopt_earlymode ()
> > +{
> > +  return !cfun || (cfun->curr_properties & PROP_phioptearly) != 0;
> > +}
> > +
> >  /* Return true if we can still perform transformations that may introduce
> >     vector operations that are not supported by the target. Vector lowering
> >     normally handles those, but after that pass, it becomes unsafe.  */
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index 39fb57e..f38baf2 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -3728,39 +3728,40 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >  #if GIMPLE
> >  (simplify
> >   (cond @0 INTEGER_CST@1 INTEGER_CST@2)
> > - (switch
> > -  (if (integer_zerop (@2))
> > -   (switch
> > -    /* a ? 1 : 0 -> a if 0 and 1 are integral types. */
> > -    (if (integer_onep (@1))
> > -     (convert (convert:boolean_type_node @0)))
> > -    /* a ? -1 : 0 -> -a. */
> > -    (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1))
> > -     (negate (convert (convert:boolean_type_node @0))))
> > -    /* a ? powerof2cst : 0 -> a << (log2(powerof2cst)) */
> > -    (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@1))
> > -     (with {
> > -       tree shift = build_int_cst (integer_type_node, tree_log2 (@1));
> > -      }
> > -      (lshift (convert (convert:boolean_type_node @0)) { shift; })))))
> > -  (if (integer_zerop (@1))
> > -   (with {
> > -      tree booltrue = constant_boolean_node (true, boolean_type_node);
> > -    }
> > + (if (!phiopt_earlymode ())
> > +  (switch
> > +   (if (integer_zerop (@2))
> >      (switch
> > -     /* a ? 0 : 1 -> !a. */
> > -     (if (integer_onep (@2))
> > -      (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )))
> > -     /* a ? -1 : 0 -> -(!a). */
> > -     (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2))
> > -      (negate (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))))
> > -     /* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */
> > -     (if (INTEGRAL_TYPE_P (type) &&  integer_pow2p (@2))
> > +     /* a ? 1 : 0 -> a if 0 and 1 are integral types. */
> > +     (if (integer_onep (@1))
> > +      (convert (convert:boolean_type_node @0)))
> > +     /* a ? -1 : 0 -> -a. */
> > +     (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1))
> > +      (negate (convert (convert:boolean_type_node @0))))
> > +     /* a ? powerof2cst : 0 -> a << (log2(powerof2cst)) */
> > +     (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@1))
> >        (with {
> > -       tree shift = build_int_cst (integer_type_node, tree_log2 (@2));
> > +        tree shift = build_int_cst (integer_type_node, tree_log2 (@1));
> >         }
> > -       (lshift (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))
> > -        { shift; }))))))))
> > +       (lshift (convert (convert:boolean_type_node @0)) { shift; })))))
> > +   (if (integer_zerop (@1))
> > +    (with {
> > +       tree booltrue = constant_boolean_node (true, boolean_type_node);
> > +     }
> > +     (switch
> > +      /* a ? 0 : 1 -> !a. */
> > +      (if (integer_onep (@2))
> > +       (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )))
> > +      /* a ? -1 : 0 -> -(!a). */
> > +      (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2))
> > +       (negate (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))))
> > +      /* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */
> > +      (if (INTEGRAL_TYPE_P (type) &&  integer_pow2p (@2))
> > +       (with {
> > +        tree shift = build_int_cst (integer_type_node, tree_log2 (@2));
> > +        }
> > +        (lshift (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))
> > +         { shift; })))))))))
> >  #endif
> >
> >  /* Simplification moved from fold_cond_expr_with_comparison.  It may also
> > @@ -4891,7 +4892,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >  /* x >= 0 ? ~y : y into ~((x >> (prec-1)) ^ y). */
> >   (simplify
> >    (cond (cmp @0 integer_zerop) (bit_not @1) @1)
> > -   (if (INTEGRAL_TYPE_P (type)
> > +   (if (!phiopt_earlymode ()
> > +       && INTEGRAL_TYPE_P (type)
> >         && INTEGRAL_TYPE_P (TREE_TYPE (@0))
> >          && !TYPE_UNSIGNED (TREE_TYPE (@0))
> >          && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type))
> > @@ -4906,7 +4908,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >  /* x >= 0 ? y : ~y into (x >> (prec-1)) ^ y. */
> >   (simplify
> >    (cond (cmp @0 integer_zerop) @1 (bit_not @1))
> > -   (if (INTEGRAL_TYPE_P (type)
> > +   (if (!phiopt_earlymode ()
> > +       && INTEGRAL_TYPE_P (type)
> >         && INTEGRAL_TYPE_P (TREE_TYPE (@0))
> >          && !TYPE_UNSIGNED (TREE_TYPE (@0))
> >          && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type))
> > @@ -4924,7 +4927,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >   (cond
> >    (ne (bit_and @0 integer_pow2p@1) integer_zerop)
> >    INTEGER_CST@2 integer_zerop)
> > - (if (!POINTER_TYPE_P (type) && integer_pow2p (@2))
> > + (if (!phiopt_earlymode ()
> > +      && !POINTER_TYPE_P (type) && integer_pow2p (@2))
> >    (with {
> >       int shift = (wi::exact_log2 (wi::to_wide (@2))
> >                   - wi::exact_log2 (wi::to_wide (@1)));
> > @@ -4942,7 +4946,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >       ncmp (ge lt)
> >   (simplify
> >    (cmp (bit_and (convert?@2 @0) integer_pow2p@1) integer_zerop)
> > -  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
> > +  (if (!phiopt_earlymode ()
> > +       && INTEGRAL_TYPE_P (TREE_TYPE (@0))
> >         && type_has_mode_precision_p (TREE_TYPE (@0))
> >         && element_precision (@2) >= element_precision (@0)
> >         && wi::only_sign_bit_p (wi::to_wide (@1), element_precision (@0)))
> > @@ -4955,7 +4960,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >   (cond
> >    (lt @0 integer_zerop)
> >    INTEGER_CST@1 integer_zerop)
> > - (if (integer_pow2p (@1)
> > + (if (!phiopt_earlymode ()
> > +      && integer_pow2p (@1)
> >        && !TYPE_UNSIGNED (TREE_TYPE (@0)))
> >    (with {
> >      int shift = element_precision (@0) - wi::exact_log2 (wi::to_wide (@1)) - 1;
> > diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
> > index 15693fe..07ee151 100644
> > --- a/gcc/tree-pass.h
> > +++ b/gcc/tree-pass.h
> > @@ -222,8 +222,9 @@ protected:
> >                                                    of math functions; the
> >                                                    current choices have
> >                                                    been optimized.  */
> > -#define PROP_gimple_lomp_dev   (1 << 16)       /* done omp_device_lower */
> > -#define PROP_rtl_split_insns   (1 << 17)       /* RTL has insns split.  */
> > +#define PROP_phioptearly       (1 << 16)       /* Sets while phiopt is in early mode. */
> > +#define PROP_gimple_lomp_dev   (1 << 17)       /* done omp_device_lower */
> > +#define PROP_rtl_split_insns   (1 << 18)       /* RTL has insns split.  */
> >
> >  #define PROP_gimple \
> >    (PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_lomp)
> > diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
> > index 3b3762a..8b289be 100644
> > --- a/gcc/tree-ssa-phiopt.c
> > +++ b/gcc/tree-ssa-phiopt.c
> > @@ -175,6 +175,8 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
> >    unsigned n, i;
> >    bool cfgchanged = false;
> >    hash_set<tree> *nontrap = 0;
> > +  if (early_p)
> > +    cfun->curr_properties |= PROP_phioptearly;
> >
> >    calculate_dominance_info (CDI_DOMINATORS);
> >
> > @@ -345,9 +347,8 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
> >           /* Do the replacement of conditional if it can be done.  */
> >           if (!early_p && two_value_replacement (bb, bb1, e2, phi, arg0, arg1))
> >             cfgchanged = true;
> > -         else if (!early_p
> > -                  && match_simplify_replacement (bb, bb1, e1, e2, phi,
> > -                                                 arg0, arg1))
> > +         else if (match_simplify_replacement (bb, bb1, e1, e2, phi,
> > +                                              arg0, arg1))
> >             cfgchanged = true;
> >           else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
> >             cfgchanged = true;
> > @@ -364,6 +365,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
> >      }
> >
> >    free (bb_order);
> > +  cfun->curr_properties &= ~PROP_phioptearly;
> >
> >    if (do_store_elim)
> >      delete nontrap;
> > --
> > 1.8.3.1
> >
diff mbox series

Patch

diff --git a/gcc/generic-match-head.c b/gcc/generic-match-head.c
index f426208..90ebf84 100644
--- a/gcc/generic-match-head.c
+++ b/gcc/generic-match-head.c
@@ -91,6 +91,13 @@  optimize_vectors_before_lowering_p ()
   return true;
 }
 
+/* Return true if phiopt is in early mode. */
+static inline bool
+phiopt_earlymode ()
+{
+  return false;
+}
+
 /* Return true if successive divisions can be optimized.
    Defer to GIMPLE opts.  */
 
diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c
index 7112c11..1eafbb7 100644
--- a/gcc/gimple-match-head.c
+++ b/gcc/gimple-match-head.c
@@ -1159,6 +1159,13 @@  canonicalize_math_after_vectorization_p ()
   return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
 }
 
+/* Return true if phiopt is in early mode. */
+static inline bool
+phiopt_earlymode ()
+{
+  return !cfun || (cfun->curr_properties & PROP_phioptearly) != 0;
+}
+
 /* Return true if we can still perform transformations that may introduce
    vector operations that are not supported by the target. Vector lowering
    normally handles those, but after that pass, it becomes unsafe.  */
diff --git a/gcc/match.pd b/gcc/match.pd
index 39fb57e..f38baf2 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3728,39 +3728,40 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 #if GIMPLE
 (simplify
  (cond @0 INTEGER_CST@1 INTEGER_CST@2)
- (switch
-  (if (integer_zerop (@2))
-   (switch
-    /* a ? 1 : 0 -> a if 0 and 1 are integral types. */
-    (if (integer_onep (@1))
-     (convert (convert:boolean_type_node @0)))
-    /* a ? -1 : 0 -> -a. */
-    (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1))
-     (negate (convert (convert:boolean_type_node @0))))
-    /* a ? powerof2cst : 0 -> a << (log2(powerof2cst)) */
-    (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@1))
-     (with {
-       tree shift = build_int_cst (integer_type_node, tree_log2 (@1));
-      }
-      (lshift (convert (convert:boolean_type_node @0)) { shift; })))))
-  (if (integer_zerop (@1))
-   (with {
-      tree booltrue = constant_boolean_node (true, boolean_type_node);
-    }
+ (if (!phiopt_earlymode ())
+  (switch
+   (if (integer_zerop (@2))
     (switch
-     /* a ? 0 : 1 -> !a. */
-     (if (integer_onep (@2))
-      (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )))
-     /* a ? -1 : 0 -> -(!a). */
-     (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2))
-      (negate (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))))
-     /* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */
-     (if (INTEGRAL_TYPE_P (type) &&  integer_pow2p (@2))
+     /* a ? 1 : 0 -> a if 0 and 1 are integral types. */
+     (if (integer_onep (@1))
+      (convert (convert:boolean_type_node @0)))
+     /* a ? -1 : 0 -> -a. */
+     (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@1))
+      (negate (convert (convert:boolean_type_node @0))))
+     /* a ? powerof2cst : 0 -> a << (log2(powerof2cst)) */
+     (if (INTEGRAL_TYPE_P (type) && integer_pow2p (@1))
       (with {
-	tree shift = build_int_cst (integer_type_node, tree_log2 (@2));
+        tree shift = build_int_cst (integer_type_node, tree_log2 (@1));
        }
-       (lshift (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))
-        { shift; }))))))))
+       (lshift (convert (convert:boolean_type_node @0)) { shift; })))))
+   (if (integer_zerop (@1))
+    (with {
+       tree booltrue = constant_boolean_node (true, boolean_type_node);
+     }
+     (switch
+      /* a ? 0 : 1 -> !a. */
+      (if (integer_onep (@2))
+       (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )))
+      /* a ? -1 : 0 -> -(!a). */
+      (if (INTEGRAL_TYPE_P (type) && integer_all_onesp (@2))
+       (negate (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))))
+      /* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */
+      (if (INTEGRAL_TYPE_P (type) &&  integer_pow2p (@2))
+       (with {
+	 tree shift = build_int_cst (integer_type_node, tree_log2 (@2));
+        }
+        (lshift (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))
+         { shift; })))))))))
 #endif
 
 /* Simplification moved from fold_cond_expr_with_comparison.  It may also
@@ -4891,7 +4892,8 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* x >= 0 ? ~y : y into ~((x >> (prec-1)) ^ y). */
  (simplify
   (cond (cmp @0 integer_zerop) (bit_not @1) @1)
-   (if (INTEGRAL_TYPE_P (type)
+   (if (!phiopt_earlymode ()
+	&& INTEGRAL_TYPE_P (type)
 	&& INTEGRAL_TYPE_P (TREE_TYPE (@0))
         && !TYPE_UNSIGNED (TREE_TYPE (@0))
         && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type))
@@ -4906,7 +4908,8 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* x >= 0 ? y : ~y into (x >> (prec-1)) ^ y. */
  (simplify
   (cond (cmp @0 integer_zerop) @1 (bit_not @1))
-   (if (INTEGRAL_TYPE_P (type)
+   (if (!phiopt_earlymode ()
+	&& INTEGRAL_TYPE_P (type)
 	&& INTEGRAL_TYPE_P (TREE_TYPE (@0))
         && !TYPE_UNSIGNED (TREE_TYPE (@0))
         && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type))
@@ -4924,7 +4927,8 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (cond
   (ne (bit_and @0 integer_pow2p@1) integer_zerop)
   INTEGER_CST@2 integer_zerop)
- (if (!POINTER_TYPE_P (type) && integer_pow2p (@2))
+ (if (!phiopt_earlymode ()
+      && !POINTER_TYPE_P (type) && integer_pow2p (@2))
   (with {
      int shift = (wi::exact_log2 (wi::to_wide (@2))
 		  - wi::exact_log2 (wi::to_wide (@1)));
@@ -4942,7 +4946,8 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      ncmp (ge lt)
  (simplify
   (cmp (bit_and (convert?@2 @0) integer_pow2p@1) integer_zerop)
-  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+  (if (!phiopt_earlymode ()
+       && INTEGRAL_TYPE_P (TREE_TYPE (@0))
        && type_has_mode_precision_p (TREE_TYPE (@0))
        && element_precision (@2) >= element_precision (@0)
        && wi::only_sign_bit_p (wi::to_wide (@1), element_precision (@0)))
@@ -4955,7 +4960,8 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (cond
   (lt @0 integer_zerop)
   INTEGER_CST@1 integer_zerop)
- (if (integer_pow2p (@1)
+ (if (!phiopt_earlymode ()
+      && integer_pow2p (@1)
       && !TYPE_UNSIGNED (TREE_TYPE (@0)))
   (with {
     int shift = element_precision (@0) - wi::exact_log2 (wi::to_wide (@1)) - 1;
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 15693fe..07ee151 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -222,8 +222,9 @@  protected:
 						   of math functions; the
 						   current choices have
 						   been optimized.  */
-#define PROP_gimple_lomp_dev	(1 << 16)	/* done omp_device_lower */
-#define PROP_rtl_split_insns	(1 << 17)	/* RTL has insns split.  */
+#define PROP_phioptearly	(1 << 16)	/* Sets while phiopt is in early mode. */
+#define PROP_gimple_lomp_dev	(1 << 17)	/* done omp_device_lower */
+#define PROP_rtl_split_insns	(1 << 18)	/* RTL has insns split.  */
 
 #define PROP_gimple \
   (PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_lomp)
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 3b3762a..8b289be 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -175,6 +175,8 @@  tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
   unsigned n, i;
   bool cfgchanged = false;
   hash_set<tree> *nontrap = 0;
+  if (early_p)
+    cfun->curr_properties |= PROP_phioptearly;
 
   calculate_dominance_info (CDI_DOMINATORS);
 
@@ -345,9 +347,8 @@  tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
 	  /* Do the replacement of conditional if it can be done.  */
 	  if (!early_p && two_value_replacement (bb, bb1, e2, phi, arg0, arg1))
 	    cfgchanged = true;
-	  else if (!early_p
-		   && match_simplify_replacement (bb, bb1, e1, e2, phi,
-						  arg0, arg1))
+	  else if (match_simplify_replacement (bb, bb1, e1, e2, phi,
+					       arg0, arg1))
 	    cfgchanged = true;
 	  else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
 	    cfgchanged = true;
@@ -364,6 +365,7 @@  tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
     }
 
   free (bb_order);
+  cfun->curr_properties &= ~PROP_phioptearly;
 
   if (do_store_elim)
     delete nontrap;