On 9/11/19 2:23 PM, Richard Biener wrote: > On Wed, 11 Sep 2019, Martin Liška wrote: > >> Hello. >> >> One another updated version of the patch. >> Changes from the previous version: >> - I fixed: >> gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, >> 2)); >> into gimple_size (GIMPLE_ASSIGN, 3) >> - I simplified condition in gimple_simplified_result_is_gimple_val >> - optimize_vec_cond_expr is using build_same_sized_truth_vector_type > > Can you here instead amend ovce_extract_ops to return the type of > 'cond' which should be the type you want?
Sure, updated in the tested attached patch. I'm going to install the patch after the Cauldron. Martin > > Otherwise OK. > > Richard. > >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. >> >> Ready to be installed? >> Thanks, >> Martin
>From 8ad0d2e59350b9410543571059c0d24bcda52db3 Mon Sep 17 00:00:00 2001 From: Li Jia He <heli...@linux.ibm.com> Date: Mon, 15 Jul 2019 00:30:25 -0500 Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd gcc/ChangeLog 2019-07-16 Li Jia He <heli...@linux.ibm.com> Martin Liska <mli...@suse.cz> * gimple-fold.c (and_comparisons_1): Add type as first argument. (and_var_with_comparison): Likewise. (and_var_with_comparison_1): Likewise. (or_comparisons_1): Likewise. (or_var_with_comparison): Likewise. (or_var_with_comparison_1): Likewise. (maybe_fold_and_comparisons): Call maybe_fold_comparisons_from_match_pd. (maybe_fold_or_comparisons): Likewise. (maybe_fold_comparisons_from_match_pd): New. * gimple-fold.h (maybe_fold_and_comparisons): Add type argument. (maybe_fold_or_comparisons): Likewise. * gimple.c (gimple_size): Make it public and add num_ops argument. (gimple_init): New function. (gimple_alloc): Call gimple_init. * gimple.h (gimple_size): New. (gimple_init): Likewise. * tree-if-conv.c (fold_or_predicates): Pass type. * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. * tree-ssa-reassoc.c (eliminate_redundant_comparison): Likewise. (optimize_vec_cond_expr): Likewise. (ovce_extract_ops): Return type of conditional expression. * tree-ssanames.c (init_ssa_name_imm_use): New. (make_ssa_name_fn): Use init_ssa_name_imm_use. * tree-ssanames.h (init_ssa_name_imm_use): New. --- gcc/gimple-fold.c | 170 +++++++++++++++++++++++++++++---------- gcc/gimple-fold.h | 4 +- gcc/gimple.c | 37 +++++---- gcc/gimple.h | 2 + gcc/tree-if-conv.c | 2 +- gcc/tree-ssa-ifcombine.c | 2 +- gcc/tree-ssa-reassoc.c | 25 ++++-- gcc/tree-ssanames.c | 21 +++-- gcc/tree-ssanames.h | 1 + 9 files changed, 189 insertions(+), 75 deletions(-) diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fcffb9802b7..6d9ba367839 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5371,22 +5371,22 @@ same_bool_result_p (const_tree op1, const_tree op2) /* Forward declarations for some mutually recursive functions. */ static tree -and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison (tree var, bool invert, +and_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison_1 (gimple *stmt, +and_var_with_comparison_1 (tree type, gimple *stmt, enum tree_code code2, tree op2a, tree op2b); static tree -or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison (tree var, bool invert, +or_var_with_comparison (tree, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison_1 (gimple *stmt, +or_var_with_comparison_1 (tree, gimple *stmt, enum tree_code code2, tree op2a, tree op2b); /* Helper function for and_comparisons_1: try to simplify the AND of the @@ -5395,7 +5395,7 @@ or_var_with_comparison_1 (gimple *stmt, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -and_var_with_comparison (tree var, bool invert, +and_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b) { tree t; @@ -5409,11 +5409,11 @@ and_var_with_comparison (tree var, bool invert, !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b)) Then we only have to consider the simpler non-inverted cases. */ if (invert) - t = or_var_with_comparison_1 (stmt, + t = or_var_with_comparison_1 (type, stmt, invert_tree_comparison (code2, false), op2a, op2b); else - t = and_var_with_comparison_1 (stmt, code2, op2a, op2b); + t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b); return canonicalize_bool (t, invert); } @@ -5422,7 +5422,7 @@ and_var_with_comparison (tree var, bool invert, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -and_var_with_comparison_1 (gimple *stmt, +and_var_with_comparison_1 (tree type, gimple *stmt, enum tree_code code2, tree op2a, tree op2b) { tree var = gimple_assign_lhs (stmt); @@ -5453,7 +5453,7 @@ and_var_with_comparison_1 (gimple *stmt, /* If the definition is a comparison, recurse on it. */ if (TREE_CODE_CLASS (innercode) == tcc_comparison) { - tree t = and_comparisons_1 (innercode, + tree t = and_comparisons_1 (type, innercode, gimple_assign_rhs1 (stmt), gimple_assign_rhs2 (stmt), code2, @@ -5489,18 +5489,20 @@ and_var_with_comparison_1 (gimple *stmt, else if (inner1 == false_test_var) return (is_and ? boolean_false_node - : and_var_with_comparison (inner2, false, code2, op2a, op2b)); + : and_var_with_comparison (type, inner2, false, code2, op2a, + op2b)); else if (inner2 == false_test_var) return (is_and ? boolean_false_node - : and_var_with_comparison (inner1, false, code2, op2a, op2b)); + : and_var_with_comparison (type, inner1, false, code2, op2a, + op2b)); /* Next, redistribute/reassociate the AND across the inner tests. Compute the first partial result, (inner1 AND (op2a code op2b)) */ if (TREE_CODE (inner1) == SSA_NAME && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1)) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison - && (t = maybe_fold_and_comparisons (gimple_assign_rhs_code (s), + && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), gimple_assign_rhs2 (s), code2, op2a, op2b))) @@ -5532,7 +5534,7 @@ and_var_with_comparison_1 (gimple *stmt, if (TREE_CODE (inner2) == SSA_NAME && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2)) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison - && (t = maybe_fold_and_comparisons (gimple_assign_rhs_code (s), + && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), gimple_assign_rhs2 (s), code2, op2a, op2b))) @@ -5588,7 +5590,7 @@ and_var_with_comparison_1 (gimple *stmt, in the first comparison but not the second. */ static tree -and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { tree truth_type = truth_type_for (TREE_TYPE (op1a)); @@ -5762,7 +5764,8 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, { case GIMPLE_ASSIGN: /* Try to simplify by copy-propagating the definition. */ - return and_var_with_comparison (op1a, invert, code2, op2a, op2b); + return and_var_with_comparison (type, op1a, invert, code2, op2a, + op2b); case GIMPLE_PHI: /* If every argument to the PHI produces the same result when @@ -5812,7 +5815,7 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, gimple_bb (def_stmt), gimple_bb (stmt))) return NULL_TREE; - temp = and_var_with_comparison (arg, invert, code2, + temp = and_var_with_comparison (type, arg, invert, code2, op2a, op2b); if (!temp) return NULL_TREE; @@ -5834,6 +5837,73 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, return NULL_TREE; } +/* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons + : try to simplify the AND/OR of the ssa variable VAR with the comparison + specified by (OP2A CODE2 OP2B) from match.pd. Return NULL_EXPR if we can't + simplify this to a single expression. As we are going to lower the cost + of building SSA names / gimple stmts significantly, we need to allocate + them ont the stack. This will cause the code to be a bit ugly. */ + +static tree +maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code, + enum tree_code code1, + tree op1a, tree op1b, + enum tree_code code2, tree op2a, + tree op2b) +{ + /* Allocate gimple stmt1 on the stack. */ + gassign *stmt1 + = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3)); + gimple_init (stmt1, GIMPLE_ASSIGN, 3); + gimple_assign_set_rhs_code (stmt1, code1); + gimple_assign_set_rhs1 (stmt1, op1a); + gimple_assign_set_rhs2 (stmt1, op1b); + + /* Allocate gimple stmt2 on the stack. */ + gassign *stmt2 + = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3)); + gimple_init (stmt2, GIMPLE_ASSIGN, 3); + gimple_assign_set_rhs_code (stmt2, code2); + gimple_assign_set_rhs1 (stmt2, op2a); + gimple_assign_set_rhs2 (stmt2, op2b); + + /* Allocate SSA names(lhs1) on the stack. */ + tree lhs1 = (tree)XALLOCA (tree_ssa_name); + memset (lhs1, 0, sizeof (tree_ssa_name)); + TREE_SET_CODE (lhs1, SSA_NAME); + TREE_TYPE (lhs1) = type; + init_ssa_name_imm_use (lhs1); + + /* Allocate SSA names(lhs2) on the stack. */ + tree lhs2 = (tree)XALLOCA (tree_ssa_name); + memset (lhs2, 0, sizeof (tree_ssa_name)); + TREE_SET_CODE (lhs2, SSA_NAME); + TREE_TYPE (lhs2) = type; + init_ssa_name_imm_use (lhs2); + + gimple_assign_set_lhs (stmt1, lhs1); + gimple_assign_set_lhs (stmt2, lhs2); + + gimple_match_op op (gimple_match_cond::UNCOND, code, + type, gimple_assign_lhs (stmt1), + gimple_assign_lhs (stmt2)); + if (op.resimplify (NULL, follow_all_ssa_edges)) + { + if (gimple_simplified_result_is_gimple_val (&op)) + { + tree res = op.ops[0]; + if (res == lhs1) + return build2 (code1, type, op1a, op1b); + else if (res == lhs2) + return build2 (code2, type, op2a, op2b); + else + return res; + } + } + + return NULL_TREE; +} + /* Try to simplify the AND of two comparisons, specified by (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively. If this can be simplified to a single expression (without requiring @@ -5842,14 +5912,22 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, If the result expression is non-null, it has boolean type. */ tree -maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b, +maybe_fold_and_comparisons (tree type, + enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { - tree t = and_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b); - if (t) + if (tree t = and_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b)) return t; - else - return and_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b); + + if (tree t = and_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b)) + return t; + + if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_AND_EXPR, code1, + op1a, op1b, code2, op2a, + op2b)) + return t; + + return NULL_TREE; } /* Helper function for or_comparisons_1: try to simplify the OR of the @@ -5858,7 +5936,7 @@ maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -or_var_with_comparison (tree var, bool invert, +or_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b) { tree t; @@ -5872,11 +5950,11 @@ or_var_with_comparison (tree var, bool invert, !var OR (op2a code2 op2b) => !(var AND !(op2a code2 op2b)) Then we only have to consider the simpler non-inverted cases. */ if (invert) - t = and_var_with_comparison_1 (stmt, + t = and_var_with_comparison_1 (type, stmt, invert_tree_comparison (code2, false), op2a, op2b); else - t = or_var_with_comparison_1 (stmt, code2, op2a, op2b); + t = or_var_with_comparison_1 (type, stmt, code2, op2a, op2b); return canonicalize_bool (t, invert); } @@ -5885,7 +5963,7 @@ or_var_with_comparison (tree var, bool invert, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -or_var_with_comparison_1 (gimple *stmt, +or_var_with_comparison_1 (tree type, gimple *stmt, enum tree_code code2, tree op2a, tree op2b) { tree var = gimple_assign_lhs (stmt); @@ -5916,7 +5994,7 @@ or_var_with_comparison_1 (gimple *stmt, /* If the definition is a comparison, recurse on it. */ if (TREE_CODE_CLASS (innercode) == tcc_comparison) { - tree t = or_comparisons_1 (innercode, + tree t = or_comparisons_1 (type, innercode, gimple_assign_rhs1 (stmt), gimple_assign_rhs2 (stmt), code2, @@ -5952,18 +6030,20 @@ or_var_with_comparison_1 (gimple *stmt, else if (inner1 == false_test_var) return (is_or ? boolean_true_node - : or_var_with_comparison (inner2, false, code2, op2a, op2b)); + : or_var_with_comparison (type, inner2, false, code2, op2a, + op2b)); else if (inner2 == false_test_var) return (is_or ? boolean_true_node - : or_var_with_comparison (inner1, false, code2, op2a, op2b)); + : or_var_with_comparison (type, inner1, false, code2, op2a, + op2b)); /* Next, redistribute/reassociate the OR across the inner tests. Compute the first partial result, (inner1 OR (op2a code op2b)) */ if (TREE_CODE (inner1) == SSA_NAME && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1)) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison - && (t = maybe_fold_or_comparisons (gimple_assign_rhs_code (s), + && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), gimple_assign_rhs2 (s), code2, op2a, op2b))) @@ -5995,7 +6075,7 @@ or_var_with_comparison_1 (gimple *stmt, if (TREE_CODE (inner2) == SSA_NAME && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2)) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison - && (t = maybe_fold_or_comparisons (gimple_assign_rhs_code (s), + && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), gimple_assign_rhs2 (s), code2, op2a, op2b))) @@ -6052,7 +6132,7 @@ or_var_with_comparison_1 (gimple *stmt, in the first comparison but not the second. */ static tree -or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { tree truth_type = truth_type_for (TREE_TYPE (op1a)); @@ -6226,7 +6306,8 @@ or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, { case GIMPLE_ASSIGN: /* Try to simplify by copy-propagating the definition. */ - return or_var_with_comparison (op1a, invert, code2, op2a, op2b); + return or_var_with_comparison (type, op1a, invert, code2, op2a, + op2b); case GIMPLE_PHI: /* If every argument to the PHI produces the same result when @@ -6276,7 +6357,7 @@ or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, gimple_bb (def_stmt), gimple_bb (stmt))) return NULL_TREE; - temp = or_var_with_comparison (arg, invert, code2, + temp = or_var_with_comparison (type, arg, invert, code2, op2a, op2b); if (!temp) return NULL_TREE; @@ -6306,16 +6387,23 @@ or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, If the result expression is non-null, it has boolean type. */ tree -maybe_fold_or_comparisons (enum tree_code code1, tree op1a, tree op1b, +maybe_fold_or_comparisons (tree type, + enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { - tree t = or_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b); - if (t) + if (tree t = or_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b)) return t; - else - return or_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b); -} + if (tree t = or_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b)) + return t; + + if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_IOR_EXPR, code1, + op1a, op1b, code2, op2a, + op2b)) + return t; + + return NULL_TREE; +} /* Fold STMT to a constant using VALUEIZE to valueize SSA names. diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h index 673d484ff52..f9d1d54daf4 100644 --- a/gcc/gimple-fold.h +++ b/gcc/gimple-fold.h @@ -31,9 +31,9 @@ extern void gimplify_and_update_call_from_tree (gimple_stmt_iterator *, tree); extern bool fold_stmt (gimple_stmt_iterator *); extern bool fold_stmt (gimple_stmt_iterator *, tree (*) (tree)); extern bool fold_stmt_inplace (gimple_stmt_iterator *); -extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, +extern tree maybe_fold_and_comparisons (tree, enum tree_code, tree, tree, enum tree_code, tree, tree); -extern tree maybe_fold_or_comparisons (enum tree_code, tree, tree, +extern tree maybe_fold_or_comparisons (tree, enum tree_code, tree, tree, enum tree_code, tree, tree); extern bool optimize_atomic_compare_exchange_p (gimple *); extern void fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *); diff --git a/gcc/gimple.c b/gcc/gimple.c index 633ef512a19..88250cad16b 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -110,10 +110,27 @@ gimple_set_code (gimple *g, enum gimple_code code) /* Return the number of bytes needed to hold a GIMPLE statement with code CODE. */ -static inline size_t -gimple_size (enum gimple_code code) +size_t +gimple_size (enum gimple_code code, unsigned num_ops) { - return gsstruct_code_size[gss_for_code (code)]; + size_t size = gsstruct_code_size[gss_for_code (code)]; + if (num_ops > 0) + size += (sizeof (tree) * (num_ops - 1)); + return size; +} + +/* Initialize GIMPLE statement G with CODE and NUM_OPS. */ + +void +gimple_init (gimple *g, enum gimple_code code, unsigned num_ops) +{ + gimple_set_code (g, code); + gimple_set_num_ops (g, num_ops); + + /* Do not call gimple_set_modified here as it has other side + effects and this tuple is still not completely built. */ + g->modified = 1; + gimple_init_singleton (g); } /* Allocate memory for a GIMPLE statement with code CODE and NUM_OPS @@ -125,10 +142,7 @@ gimple_alloc (enum gimple_code code, unsigned num_ops MEM_STAT_DECL) size_t size; gimple *stmt; - size = gimple_size (code); - if (num_ops > 0) - size += sizeof (tree) * (num_ops - 1); - + size = gimple_size (code, num_ops); if (GATHER_STATISTICS) { enum gimple_alloc_kind kind = gimple_alloc_kind (code); @@ -137,14 +151,7 @@ gimple_alloc (enum gimple_code code, unsigned num_ops MEM_STAT_DECL) } stmt = ggc_alloc_cleared_gimple_statement_stat (size PASS_MEM_STAT); - gimple_set_code (stmt, code); - gimple_set_num_ops (stmt, num_ops); - - /* Do not call gimple_set_modified here as it has other side - effects and this tuple is still not completely built. */ - stmt->modified = 1; - gimple_init_singleton (stmt); - + gimple_init (stmt, code, num_ops); return stmt; } diff --git a/gcc/gimple.h b/gcc/gimple.h index 55f5d0d33d9..cf1f8da5ae2 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1445,6 +1445,8 @@ extern enum gimple_statement_structure_enum const gss_for_code_[]; of comminucating the profile info to the builtin expanders. */ extern gimple *currently_expanding_gimple_stmt; +size_t gimple_size (enum gimple_code code, unsigned num_ops = 0); +void gimple_init (gimple *g, enum gimple_code code, unsigned num_ops); gimple *gimple_alloc (enum gimple_code, unsigned CXX_MEM_STAT_INFO); greturn *gimple_build_return (tree); void gimple_call_reset_alias_info (gcall *); diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index da67e39e03a..40ad4c5947a 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -436,7 +436,7 @@ fold_or_predicates (location_t loc, tree c1, tree c2) if (code1 != ERROR_MARK && code2 != ERROR_MARK) { - tree t = maybe_fold_or_comparisons (code1, op1a, op1b, + tree t = maybe_fold_or_comparisons (boolean_type_node, code1, op1a, op1b, code2, op2a, op2b); if (t) return t; diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index f30816ace7b..90d8bb5e9e7 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -555,7 +555,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, return false; /* Don't return false so fast, try maybe_fold_or_comparisons? */ - if (!(t = maybe_fold_and_comparisons (inner_cond_code, + if (!(t = maybe_fold_and_comparisons (boolean_type_node, inner_cond_code, gimple_cond_lhs (inner_cond), gimple_cond_rhs (inner_cond), outer_cond_code, diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index df76e66bccf..510dfd1e188 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -2088,12 +2088,15 @@ eliminate_redundant_comparison (enum tree_code opcode, /* If we got here, we have a match. See if we can combine the two comparisons. */ + tree type = TREE_TYPE (gimple_assign_lhs (def1)); if (opcode == BIT_IOR_EXPR) - t = maybe_fold_or_comparisons (lcode, op1, op2, + t = maybe_fold_or_comparisons (type, + lcode, op1, op2, rcode, gimple_assign_rhs1 (def2), gimple_assign_rhs2 (def2)); else - t = maybe_fold_and_comparisons (lcode, op1, op2, + t = maybe_fold_and_comparisons (type, + lcode, op1, op2, rcode, gimple_assign_rhs1 (def2), gimple_assign_rhs2 (def2)); if (!t) @@ -3745,10 +3748,11 @@ optimize_range_tests (enum tree_code opcode, /* A subroutine of optimize_vec_cond_expr to extract and canonicalize the operands of the VEC_COND_EXPR. Returns ERROR_MARK on failure, - otherwise the comparison code. */ + otherwise the comparison code. TYPE is a return value that is set + to type of comparison. */ static tree_code -ovce_extract_ops (tree var, gassign **rets, bool *reti) +ovce_extract_ops (tree var, gassign **rets, bool *reti, tree *type) { if (TREE_CODE (var) != SSA_NAME) return ERROR_MARK; @@ -3790,6 +3794,8 @@ ovce_extract_ops (tree var, gassign **rets, bool *reti) *rets = stmt; if (reti) *reti = inv; + if (type) + *type = TREE_TYPE (cond); return cmp; } @@ -3811,7 +3817,8 @@ optimize_vec_cond_expr (tree_code opcode, vec<operand_entry *> *ops) gassign *stmt0; bool invert; - tree_code cmp0 = ovce_extract_ops (elt0, &stmt0, &invert); + tree type; + tree_code cmp0 = ovce_extract_ops (elt0, &stmt0, &invert, &type); if (cmp0 == ERROR_MARK) continue; @@ -3820,7 +3827,7 @@ optimize_vec_cond_expr (tree_code opcode, vec<operand_entry *> *ops) tree &elt1 = (*ops)[j]->op; gassign *stmt1; - tree_code cmp1 = ovce_extract_ops (elt1, &stmt1, NULL); + tree_code cmp1 = ovce_extract_ops (elt1, &stmt1, NULL, NULL); if (cmp1 == ERROR_MARK) continue; @@ -3834,9 +3841,11 @@ optimize_vec_cond_expr (tree_code opcode, vec<operand_entry *> *ops) tree comb; if (opcode == BIT_AND_EXPR) - comb = maybe_fold_and_comparisons (cmp0, x0, y0, cmp1, x1, y1); + comb = maybe_fold_and_comparisons (type, cmp0, x0, y0, cmp1, x1, + y1); else if (opcode == BIT_IOR_EXPR) - comb = maybe_fold_or_comparisons (cmp0, x0, y0, cmp1, x1, y1); + comb = maybe_fold_or_comparisons (type, cmp0, x0, y0, cmp1, x1, + y1); else gcc_unreachable (); if (comb == NULL) diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 3911db9c26e..f7b638dba11 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -252,6 +252,19 @@ flush_ssaname_freelist (void) vec_safe_truncate (FREE_SSANAMES_QUEUE (cfun), 0); } +/* Initialize SSA_NAME_IMM_USE_NODE of a SSA NAME. */ + +void +init_ssa_name_imm_use (tree name) +{ + use_operand_p imm; + imm = &(SSA_NAME_IMM_USE_NODE (name)); + imm->use = NULL; + imm->prev = imm; + imm->next = imm; + imm->loc.ssa_name = name; +} + /* Return an SSA_NAME node for variable VAR defined in statement STMT in function FN. STMT may be an empty statement for artificial references (e.g., default definitions created when a variable is @@ -263,8 +276,6 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, unsigned int version) { tree t; - use_operand_p imm; - gcc_assert (VAR_P (var) || TREE_CODE (var) == PARM_DECL || TREE_CODE (var) == RESULT_DECL @@ -318,11 +329,7 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, SSA_NAME_IN_FREE_LIST (t) = 0; SSA_NAME_IS_DEFAULT_DEF (t) = 0; - imm = &(SSA_NAME_IMM_USE_NODE (t)); - imm->use = NULL; - imm->prev = imm; - imm->next = imm; - imm->loc.ssa_name = t; + init_ssa_name_imm_use (t); return t; } diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index 6e6cffbce6a..1a7d0bccdf8 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -82,6 +82,7 @@ extern void fini_ssanames (struct function *); extern void ssanames_print_statistics (void); extern tree make_ssa_name_fn (struct function *, tree, gimple *, unsigned int version = 0); +extern void init_ssa_name_imm_use (tree); extern void release_ssa_name_fn (struct function *, tree); extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *, unsigned int *); -- 2.23.0