summaryrefslogtreecommitdiff
path: root/gcc/tree-if-conv.c
diff options
context:
space:
mode:
authorpinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-03 20:31:52 +0000
committerpinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-03 20:31:52 +0000
commited0124a2ae6a42565a495a619aecf752d49682ef (patch)
tree5fbe5db82a98ffa2d46d0d28b36eb77d91279460 /gcc/tree-if-conv.c
parentfe1dba6dac26261f1f8b72ca185aa156d13f94d3 (diff)
downloadgcc-ed0124a2ae6a42565a495a619aecf752d49682ef.tar.gz
2012-09-03 Andrew Pinski <apinski@cavium.com>
PR tree-opt/53395 * tree-if-conv.c (constant_or_ssa_name): New function. (fold_build_cond_expr): New function. (predicate_scalar_phi): Use fold_build_cond_expr instead of build3. (predicate_mem_writes): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190904 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-if-conv.c')
-rw-r--r--gcc/tree-if-conv.c65
1 files changed, 62 insertions, 3 deletions
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 1086004d3fb..e9f65adddbd 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -307,6 +307,65 @@ fold_or_predicates (location_t loc, tree c1, tree c2)
return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2);
}
+/* Returns true if N is either a constant or a SSA_NAME. */
+
+static bool
+constant_or_ssa_name (tree n)
+{
+ switch (TREE_CODE (n))
+ {
+ case SSA_NAME:
+ case INTEGER_CST:
+ case REAL_CST:
+ case COMPLEX_CST:
+ case VECTOR_CST:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* Returns either a COND_EXPR or the folded expression if the folded
+ expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR,
+ a constant or a SSA_NAME. */
+
+static tree
+fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs)
+{
+ tree rhs1, lhs1, cond_expr;
+ cond_expr = fold_ternary (COND_EXPR, type, cond,
+ rhs, lhs);
+
+ if (cond_expr == NULL_TREE)
+ return build3 (COND_EXPR, type, cond, rhs, lhs);
+
+ STRIP_USELESS_TYPE_CONVERSION (cond_expr);
+
+ if (constant_or_ssa_name (cond_expr))
+ return cond_expr;
+
+ if (TREE_CODE (cond_expr) == ABS_EXPR)
+ {
+ rhs1 = TREE_OPERAND (cond_expr, 1);
+ STRIP_USELESS_TYPE_CONVERSION (rhs1);
+ if (constant_or_ssa_name (rhs1))
+ return build1 (ABS_EXPR, type, rhs1);
+ }
+
+ if (TREE_CODE (cond_expr) == MIN_EXPR
+ || TREE_CODE (cond_expr) == MAX_EXPR)
+ {
+ lhs1 = TREE_OPERAND (cond_expr, 0);
+ STRIP_USELESS_TYPE_CONVERSION (lhs1);
+ rhs1 = TREE_OPERAND (cond_expr, 1);
+ STRIP_USELESS_TYPE_CONVERSION (rhs1);
+ if (constant_or_ssa_name (rhs1)
+ && constant_or_ssa_name (lhs1))
+ return build2 (TREE_CODE (cond_expr), type, lhs1, rhs1);
+ }
+ return build3 (COND_EXPR, type, cond, rhs, lhs);
+}
+
/* Add condition NC to the predicate list of basic block BB. */
static inline void
@@ -1293,8 +1352,8 @@ predicate_scalar_phi (gimple phi, tree cond,
|| bb_postdominates_preds (bb));
/* Build new RHS using selected condition and arguments. */
- rhs = build3 (COND_EXPR, TREE_TYPE (res),
- unshare_expr (cond), arg_0, arg_1);
+ rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
+ arg_0, arg_1);
}
new_stmt = gimple_build_assign (res, rhs);
@@ -1554,7 +1613,7 @@ predicate_mem_writes (loop_p loop)
cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
is_gimple_condexpr, NULL_TREE,
true, GSI_SAME_STMT);
- rhs = build3 (COND_EXPR, type, unshare_expr (cond), rhs, lhs);
+ rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
update_stmt (stmt);
}