summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jia He <helijia@linux.ibm.com>2019-09-16 14:21:20 +0000
committerMartin Liska <marxin@gcc.gnu.org>2019-09-16 14:21:20 +0000
commit5f487a349de62613d7fa429bcbfbeeafbfc94f3a (patch)
treed63d3e1bb2210eb3e25095d2dc0deab2b5ccf72a
parent10f30ac9cda947d117e50f0cbd4cf94ee70a944f (diff)
Auto-generate maybe_fold_and/or_comparisons from match.pd
2019-09-16 Li Jia He <helijia@linux.ibm.com> Martin Liska <mliska@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. Co-Authored-By: Martin Liska <mliska@suse.cz> From-SVN: r275748
-rw-r--r--gcc/ChangeLog29
-rw-r--r--gcc/gimple-fold.c170
-rw-r--r--gcc/gimple-fold.h4
-rw-r--r--gcc/gimple.c37
-rw-r--r--gcc/gimple.h2
-rw-r--r--gcc/tree-if-conv.c2
-rw-r--r--gcc/tree-ssa-ifcombine.c2
-rw-r--r--gcc/tree-ssa-reassoc.c25
-rw-r--r--gcc/tree-ssanames.c21
-rw-r--r--gcc/tree-ssanames.h1
10 files changed, 218 insertions, 75 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 49b7902e3a8..864da5a3034 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,32 @@
+2019-09-16 Li Jia He <helijia@linux.ibm.com>
+ Martin Liska <mliska@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.
+
2019-09-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/91756
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 *);