On Sun, Sep 8, 2024 at 6:20 PM Andrew Pinski <quic_apin...@quicinc.com> wrote: > > This small cleanup removes a redundant check for gimple_assign_cast_p and > reformats > based on that. Also changes the if statement that checks if the integral type > and the > check to see if the constant fits into the new type such that it returns null > and reformats based on that. > > Also moves the check for has_single_use earlier so it is less complex still a > cheaper > check than some of the others (like the check on the integer side). > > This was noticed when adding a few new things to > factor_out_conditional_operation > but those are not ready to submit yet. > > Note there are no functional difference with this change. > > Bootstrapped and tested on x86_64-linux-gnu.
OK > gcc/ChangeLog: > > * tree-ssa-phiopt.cc (factor_out_conditional_operation): Move the > has_single_use > checks much earlier. Remove redundant check for gimple_assign_cast_p. > Change around the check if the integral consts fits into the new type. > > Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> > --- > gcc/tree-ssa-phiopt.cc | 122 ++++++++++++++++++++--------------------- > 1 file changed, 60 insertions(+), 62 deletions(-) > > diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc > index 271a5d51f09..06ec5875722 100644 > --- a/gcc/tree-ssa-phiopt.cc > +++ b/gcc/tree-ssa-phiopt.cc > @@ -265,6 +265,11 @@ factor_out_conditional_operation (edge e0, edge e1, gphi > *phi, > tree new_arg0 = arg0_op.ops[0]; > tree new_arg1; > > + /* If arg0 have > 1 use, then this transformation actually increases > + the number of expressions evaluated at runtime. */ > + if (!has_single_use (arg0)) > + return NULL; > + > if (TREE_CODE (arg1) == SSA_NAME) > { > /* Check if arg1 is an SSA_NAME. */ > @@ -278,6 +283,11 @@ factor_out_conditional_operation (edge e0, edge e1, gphi > *phi, > if (arg1_op.operands_occurs_in_abnormal_phi ()) > return NULL; > > + /* If arg1 have > 1 use, then this transformation actually increases > + the number of expressions evaluated at runtime. */ > + if (!has_single_use (arg1)) > + return NULL; > + > /* Either arg1_def_stmt or arg0_def_stmt should be conditional. */ > if (dominated_by_p (CDI_DOMINATORS, gimple_bb (phi), gimple_bb > (arg0_def_stmt)) > && dominated_by_p (CDI_DOMINATORS, > @@ -295,80 +305,68 @@ factor_out_conditional_operation (edge e0, edge e1, > gphi *phi, > if (dominated_by_p (CDI_DOMINATORS, gimple_bb (phi), gimple_bb > (arg0_def_stmt))) > return NULL; > > - /* If arg1 is an INTEGER_CST, fold it to new type. */ > - if (INTEGRAL_TYPE_P (TREE_TYPE (new_arg0)) > - && (int_fits_type_p (arg1, TREE_TYPE (new_arg0)) > - || (TYPE_PRECISION (TREE_TYPE (new_arg0)) > + /* Only handle if arg1 is a INTEGER_CST and one that fits > + into the new type or if it is the same precision. */ > + if (!INTEGRAL_TYPE_P (TREE_TYPE (new_arg0)) > + || !(int_fits_type_p (arg1, TREE_TYPE (new_arg0)) > + || (TYPE_PRECISION (TREE_TYPE (new_arg0)) > == TYPE_PRECISION (TREE_TYPE (arg1))))) > + return NULL; > + > + /* For the INTEGER_CST case, we are just moving the > + conversion from one place to another, which can often > + hurt as the conversion moves further away from the > + statement that computes the value. So, perform this > + only if new_arg0 is an operand of COND_STMT, or > + if arg0_def_stmt is the only non-debug stmt in > + its basic block, because then it is possible this > + could enable further optimizations (minmax replacement > + etc.). See PR71016. > + Note no-op conversions don't have this issue as > + it will not generate any zero/sign extend in that case. */ > + if ((TYPE_PRECISION (TREE_TYPE (new_arg0)) > + != TYPE_PRECISION (TREE_TYPE (arg1))) > + && new_arg0 != gimple_cond_lhs (cond_stmt) > + && new_arg0 != gimple_cond_rhs (cond_stmt) > + && gimple_bb (arg0_def_stmt) == e0->src) > { > - if (gimple_assign_cast_p (arg0_def_stmt)) > + gsi = gsi_for_stmt (arg0_def_stmt); > + gsi_prev_nondebug (&gsi); > + if (!gsi_end_p (gsi)) > { > - /* For the INTEGER_CST case, we are just moving the > - conversion from one place to another, which can often > - hurt as the conversion moves further away from the > - statement that computes the value. So, perform this > - only if new_arg0 is an operand of COND_STMT, or > - if arg0_def_stmt is the only non-debug stmt in > - its basic block, because then it is possible this > - could enable further optimizations (minmax replacement > - etc.). See PR71016. > - Note no-op conversions don't have this issue as > - it will not generate any zero/sign extend in that case. */ > - if ((TYPE_PRECISION (TREE_TYPE (new_arg0)) > - != TYPE_PRECISION (TREE_TYPE (arg1))) > - && new_arg0 != gimple_cond_lhs (cond_stmt) > - && new_arg0 != gimple_cond_rhs (cond_stmt) > - && gimple_bb (arg0_def_stmt) == e0->src) > + gimple *stmt = gsi_stmt (gsi); > + /* Ignore nops, predicates and labels. */ > + if (gimple_code (stmt) == GIMPLE_NOP > + || gimple_code (stmt) == GIMPLE_PREDICT > + || gimple_code (stmt) == GIMPLE_LABEL) > + ; > + else if (gassign *assign = dyn_cast <gassign *> (stmt)) > { > - gsi = gsi_for_stmt (arg0_def_stmt); > + tree lhs = gimple_assign_lhs (assign); > + enum tree_code ass_code > + = gimple_assign_rhs_code (assign); > + if (ass_code != MAX_EXPR && ass_code != MIN_EXPR) > + return NULL; > + if (lhs != gimple_assign_rhs1 (arg0_def_stmt)) > + return NULL; > gsi_prev_nondebug (&gsi); > if (!gsi_end_p (gsi)) > - { > - gimple *stmt = gsi_stmt (gsi); > - /* Ignore nops, predicates and labels. */ > - if (gimple_code (stmt) == GIMPLE_NOP > - || gimple_code (stmt) == GIMPLE_PREDICT > - || gimple_code (stmt) == GIMPLE_LABEL) > - ; > - else if (gassign *assign = dyn_cast <gassign *> (stmt)) > - { > - tree lhs = gimple_assign_lhs (assign); > - enum tree_code ass_code > - = gimple_assign_rhs_code (assign); > - if (ass_code != MAX_EXPR && ass_code != MIN_EXPR) > - return NULL; > - if (lhs != gimple_assign_rhs1 (arg0_def_stmt)) > - return NULL; > - gsi_prev_nondebug (&gsi); > - if (!gsi_end_p (gsi)) > - return NULL; > - } > - else > return NULL; > - } > - gsi = gsi_for_stmt (arg0_def_stmt); > - gsi_next_nondebug (&gsi); > - if (!gsi_end_p (gsi)) > - return NULL; > } > - new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1); > - > - /* Drop the overlow that fold_convert might add. */ > - if (TREE_OVERFLOW (new_arg1)) > - new_arg1 = drop_tree_overflow (new_arg1); > + else > + return NULL; > } > - else > + gsi = gsi_for_stmt (arg0_def_stmt); > + gsi_next_nondebug (&gsi); > + if (!gsi_end_p (gsi)) > return NULL; > } > - else > - return NULL; > - } > + new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1); > > - /* If arg0/arg1 have > 1 use, then this transformation actually increases > - the number of expressions evaluated at runtime. */ > - if (!has_single_use (arg0) > - || (arg1_def_stmt && !has_single_use (arg1))) > - return NULL; > + /* Drop the overlow that fold_convert might add. */ > + if (TREE_OVERFLOW (new_arg1)) > + new_arg1 = drop_tree_overflow (new_arg1); > + } > > /* If types of new_arg0 and new_arg1 are different bailout. */ > if (!types_compatible_p (TREE_TYPE (new_arg0), TREE_TYPE (new_arg1))) > -- > 2.43.0 >