aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-forwprop.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-04-16 09:25:14 +0000
committerRichard Guenther <rguenther@suse.de>2012-04-16 09:25:14 +0000
commitc6ffa29bbc39236237c61bc66d5cb968bb130812 (patch)
tree49b6bc580d6294485fb21f111c49282f11b8efdd /gcc/tree-ssa-forwprop.c
parent5ac448504aa4c6cf2847e0744fb7521ba800953a (diff)
2012-04-16 Richard Guenther <rguenther@suse.de>
PR tree-optimization/52975 * tree-ssa-forwprop.c (combine_cond_exprs): New function. (ssa_forward_propagate_and_combine): Call it for COND_EXPRs and VEC_COND_EXPRs. Also combine into VEC_COND_EXPRs condition. * fold-const.c (operand_equal_p): Handle TARGET_MEM_REF. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@186488 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-forwprop.c')
-rw-r--r--gcc/tree-ssa-forwprop.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 57b93cee7f1..3e2371bc83c 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -632,6 +632,58 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
return 0;
}
+/* Propagate from the ssa name definition statements of COND_EXPR
+ values in the rhs of statement STMT into the conditional arms
+ if that simplifies it.
+ Returns true if the stmt was changed. */
+
+static bool
+combine_cond_exprs (gimple_stmt_iterator *gsi_p)
+{
+ gimple stmt = gsi_stmt (*gsi_p);
+ tree cond, val1, val2;
+ bool changed = false;
+
+ cond = gimple_assign_rhs1 (stmt);
+ val1 = gimple_assign_rhs2 (stmt);
+ if (TREE_CODE (val1) == SSA_NAME)
+ {
+ gimple def_stmt = SSA_NAME_DEF_STMT (val1);
+ if (is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == gimple_assign_rhs_code (stmt)
+ && operand_equal_p (gimple_assign_rhs1 (def_stmt), cond, 0))
+ {
+ val1 = unshare_expr (gimple_assign_rhs2 (def_stmt));
+ gimple_assign_set_rhs2 (stmt, val1);
+ changed = true;
+ }
+ }
+ val2 = gimple_assign_rhs3 (stmt);
+ if (TREE_CODE (val2) == SSA_NAME)
+ {
+ gimple def_stmt = SSA_NAME_DEF_STMT (val2);
+ if (is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == gimple_assign_rhs_code (stmt)
+ && operand_equal_p (gimple_assign_rhs1 (def_stmt), cond, 0))
+ {
+ val2 = unshare_expr (gimple_assign_rhs3 (def_stmt));
+ gimple_assign_set_rhs3 (stmt, val2);
+ changed = true;
+ }
+ }
+ if (operand_equal_p (val1, val2, 0))
+ {
+ gimple_assign_set_rhs_from_tree (gsi_p, val1);
+ stmt = gsi_stmt (*gsi_p);
+ changed = true;
+ }
+
+ if (changed)
+ update_stmt (stmt);
+
+ return changed;
+}
+
/* We've just substituted an ADDR_EXPR into stmt. Update all the
relevant data structures to match. */
@@ -2480,10 +2532,12 @@ ssa_forward_propagate_and_combine (void)
|| code == NEGATE_EXPR)
&& TREE_CODE (rhs1) == SSA_NAME)
changed = simplify_not_neg_expr (&gsi);
- else if (code == COND_EXPR)
+ else if (code == COND_EXPR
+ || code == VEC_COND_EXPR)
{
/* In this case the entire COND_EXPR is in rhs1. */
changed |= forward_propagate_into_cond (&gsi);
+ changed |= combine_cond_exprs (&gsi);
stmt = gsi_stmt (gsi);
}
else if (TREE_CODE_CLASS (code) == tcc_comparison)