aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/gimple-expr.cc47
-rw-r--r--gcc/gimple-expr.h1
-rw-r--r--gcc/gimple-loop-versioning.cc3
-rw-r--r--gcc/gimple.cc42
-rw-r--r--gcc/gimple.h1
-rw-r--r--gcc/tree-parloops.cc2
-rw-r--r--gcc/tree-ssa-ifcombine.cc16
-rw-r--r--gcc/tree-ssa-loop-manip.cc2
-rw-r--r--gcc/tree-vect-loop-manip.cc10
9 files changed, 70 insertions, 54 deletions
diff --git a/gcc/gimple-expr.cc b/gcc/gimple-expr.cc
index 5faaf43..5d10c24 100644
--- a/gcc/gimple-expr.cc
+++ b/gcc/gimple-expr.cc
@@ -614,7 +614,8 @@ is_gimple_condexpr_1 (tree t, bool allow_traps, bool allow_cplx)
&& is_gimple_val (TREE_OPERAND (t, 1))));
}
-/* Return true if T is a GIMPLE condition. */
+/* Return true if T is a condition operand in a GIMPLE assignment
+ with a COND_EXPR RHS. */
bool
is_gimple_condexpr (tree t)
@@ -632,6 +633,50 @@ is_gimple_condexpr_for_cond (tree t)
return is_gimple_condexpr_1 (t, false, true);
}
+/* Canonicalize a tree T for use in a COND_EXPR as conditional. Returns
+ a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
+ we failed to create one. */
+
+tree
+canonicalize_cond_expr_cond (tree t)
+{
+ /* Strip conversions around boolean operations. */
+ if (CONVERT_EXPR_P (t)
+ && (truth_value_p (TREE_CODE (TREE_OPERAND (t, 0)))
+ || TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
+ == BOOLEAN_TYPE))
+ t = TREE_OPERAND (t, 0);
+
+ /* For !x use x == 0. */
+ if (TREE_CODE (t) == TRUTH_NOT_EXPR)
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (EQ_EXPR, TREE_TYPE (t),
+ top0, build_int_cst (TREE_TYPE (top0), 0));
+ }
+ /* For cmp ? 1 : 0 use cmp. */
+ else if (TREE_CODE (t) == COND_EXPR
+ && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
+ && integer_onep (TREE_OPERAND (t, 1))
+ && integer_zerop (TREE_OPERAND (t, 2)))
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (TREE_CODE (top0), TREE_TYPE (t),
+ TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
+ }
+ /* For x ^ y use x != y. */
+ else if (TREE_CODE (t) == BIT_XOR_EXPR)
+ t = build2 (NE_EXPR, TREE_TYPE (t),
+ TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
+
+ /* We don't know where this will be used so allow both traps and
+ _Complex. The caller is responsible for more precise checking. */
+ if (is_gimple_condexpr_1 (t, true, true))
+ return t;
+
+ return NULL_TREE;
+}
+
/* Return true if T is a gimple address. */
bool
diff --git a/gcc/gimple-expr.h b/gcc/gimple-expr.h
index 0697126..ba53b80 100644
--- a/gcc/gimple-expr.h
+++ b/gcc/gimple-expr.h
@@ -56,6 +56,7 @@ extern bool is_gimple_mem_ref_addr (tree);
extern void flush_mark_addressable_queue (void);
extern void mark_addressable (tree);
extern bool is_gimple_reg_rhs (tree);
+extern tree canonicalize_cond_expr_cond (tree);
/* Return true if a conversion from either type of TYPE1 and TYPE2
to the other is not required. Otherwise return false. */
diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
index 3175a1e..5838ce7 100644
--- a/gcc/gimple-loop-versioning.cc
+++ b/gcc/gimple-loop-versioning.cc
@@ -1681,7 +1681,8 @@ loop_versioning::version_loop (class loop *loop)
/* Convert the condition into a suitable gcond. */
gimple_seq stmts = NULL;
- cond = force_gimple_operand_1 (cond, &stmts, is_gimple_condexpr, NULL_TREE);
+ cond = force_gimple_operand_1 (cond, &stmts, is_gimple_condexpr_for_cond,
+ NULL_TREE);
/* Version the loop. */
initialize_original_copy_tables ();
diff --git a/gcc/gimple.cc b/gcc/gimple.cc
index 9e62da4..b70ab4d 100644
--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc
@@ -2380,48 +2380,6 @@ const unsigned char gimple_rhs_class_table[] = {
#undef DEFTREECODE
#undef END_OF_BASE_TREE_CODES
-/* Canonicalize a tree T for use in a COND_EXPR as conditional. Returns
- a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
- we failed to create one. */
-
-tree
-canonicalize_cond_expr_cond (tree t)
-{
- /* Strip conversions around boolean operations. */
- if (CONVERT_EXPR_P (t)
- && (truth_value_p (TREE_CODE (TREE_OPERAND (t, 0)))
- || TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
- == BOOLEAN_TYPE))
- t = TREE_OPERAND (t, 0);
-
- /* For !x use x == 0. */
- if (TREE_CODE (t) == TRUTH_NOT_EXPR)
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (EQ_EXPR, TREE_TYPE (t),
- top0, build_int_cst (TREE_TYPE (top0), 0));
- }
- /* For cmp ? 1 : 0 use cmp. */
- else if (TREE_CODE (t) == COND_EXPR
- && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
- && integer_onep (TREE_OPERAND (t, 1))
- && integer_zerop (TREE_OPERAND (t, 2)))
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (TREE_CODE (top0), TREE_TYPE (t),
- TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
- }
- /* For x ^ y use x != y. */
- else if (TREE_CODE (t) == BIT_XOR_EXPR)
- t = build2 (NE_EXPR, TREE_TYPE (t),
- TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
-
- if (is_gimple_condexpr (t))
- return t;
-
- return NULL_TREE;
-}
-
/* Build a GIMPLE_CALL identical to STMT but skipping the arguments in
the positions marked by the set ARGS_TO_SKIP. */
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 77a5a07..6b1e89a 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1611,7 +1611,6 @@ bool gimple_could_trap_p (const gimple *);
bool gimple_assign_rhs_could_trap_p (gimple *);
extern void dump_gimple_statistics (void);
unsigned get_gimple_rhs_num_ops (enum tree_code);
-extern tree canonicalize_cond_expr_cond (tree);
gcall *gimple_call_copy_skip_args (gcall *, bitmap);
extern bool gimple_compare_field_offset (tree, tree);
extern tree gimple_unsigned_type (tree);
diff --git a/gcc/tree-parloops.cc b/gcc/tree-parloops.cc
index 7fcb0d5..da10696 100644
--- a/gcc/tree-parloops.cc
+++ b/gcc/tree-parloops.cc
@@ -3070,7 +3070,7 @@ gen_parallel_loop (class loop *loop,
= force_gimple_operand (many_iterations_cond, &stmts, false, NULL_TREE);
if (stmts)
gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
- if (!is_gimple_condexpr (many_iterations_cond))
+ if (!is_gimple_condexpr_for_cond (many_iterations_cond))
{
many_iterations_cond
= force_gimple_operand (many_iterations_cond, &stmts,
diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index ce9bbeb..3a4ab69 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -432,6 +432,12 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
t = canonicalize_cond_expr_cond (t);
if (!t)
return false;
+ if (!is_gimple_condexpr_for_cond (t))
+ {
+ gsi = gsi_for_stmt (inner_cond);
+ t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr_for_cond,
+ NULL, true, GSI_SAME_STMT);
+ }
gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
@@ -512,6 +518,12 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
t = canonicalize_cond_expr_cond (t);
if (!t)
return false;
+ if (!is_gimple_condexpr_for_cond (t))
+ {
+ gsi = gsi_for_stmt (inner_cond);
+ t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr_for_cond,
+ NULL, true, GSI_SAME_STMT);
+ }
gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
@@ -593,8 +605,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
result_inv = false;
}
gsi = gsi_for_stmt (inner_cond);
- t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, true,
- GSI_SAME_STMT);
+ t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr_for_cond,
+ NULL, true, GSI_SAME_STMT);
}
if (result_inv)
t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
diff --git a/gcc/tree-ssa-loop-manip.cc b/gcc/tree-ssa-loop-manip.cc
index 770cbd2..6696425 100644
--- a/gcc/tree-ssa-loop-manip.cc
+++ b/gcc/tree-ssa-loop-manip.cc
@@ -1096,7 +1096,7 @@ determine_exit_conditions (class loop *loop, class tree_niter_desc *desc,
/* cond now may be a gimple comparison, which would be OK, but also any
other gimple rhs (say a && b). In this case we need to force it to
operand. */
- if (!is_gimple_condexpr (cond))
+ if (!is_gimple_condexpr_for_cond (cond))
{
cond = force_gimple_operand (cond, &stmts, true, NULL_TREE);
if (stmts)
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 3eddda6..1d4337e 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -1260,8 +1260,8 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond,
enter_e->flags |= EDGE_FALSE_VALUE;
gsi = gsi_last_bb (guard_bb);
- cond = force_gimple_operand_1 (cond, &gimplify_stmt_list, is_gimple_condexpr,
- NULL_TREE);
+ cond = force_gimple_operand_1 (cond, &gimplify_stmt_list,
+ is_gimple_condexpr_for_cond, NULL_TREE);
if (gimplify_stmt_list)
gsi_insert_seq_after (&gsi, gimplify_stmt_list, GSI_NEW_STMT);
@@ -3478,8 +3478,8 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
{
gimple_seq tem = NULL;
cond_expr = force_gimple_operand_1 (unshare_expr (cond_expr),
- &tem,
- is_gimple_condexpr, NULL_TREE);
+ &tem, is_gimple_condexpr_for_cond,
+ NULL_TREE);
gimple_seq_add_seq (&cond_expr_stmt_list, tem);
}
@@ -3521,7 +3521,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
cond_expr = force_gimple_operand_1 (unshare_expr (cond_expr),
&gimplify_stmt_list,
- is_gimple_condexpr, NULL_TREE);
+ is_gimple_condexpr_for_cond, NULL_TREE);
gimple_seq_add_seq (&cond_expr_stmt_list, gimplify_stmt_list);
/* Compute the outermost loop cond_expr and cond_expr_stmt_list are