[PATCH 5/7] Allow match-and-simplified phiopt to run in early phiopt
Richard Biener
richard.guenther@gmail.com
Mon Jun 21 09:49:46 GMT 2021
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
>
More information about the Gcc-patches
mailing list