aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-forwprop.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2014-01-29 11:08:59 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2014-01-29 11:08:59 +0000
commit4bfb2fa258b5aec3de431eec08288accf0bd5529 (patch)
treee500de9b76caaa9de2e3b1a7441d2929b980d847 /gcc/tree-ssa-forwprop.c
parent09b22f48d435d158761a02117facec4daa7395fb (diff)
downloadgcc-4bfb2fa258b5aec3de431eec08288accf0bd5529.zip
gcc-4bfb2fa258b5aec3de431eec08288accf0bd5529.tar.gz
gcc-4bfb2fa258b5aec3de431eec08288accf0bd5529.tar.bz2
re PR middle-end/58742 (pointer arithmetic simplification)
2014-01-29 Richard Biener <rguenther@suse.de> PR tree-optimization/58742 * tree-ssa-forwprop.c (associate_plusminus): Return true if we changed sth, defer EH cleanup to ... (ssa_forward_propagate_and_combine): ... here. Call simplify_mult. (simplify_mult): New function. From-SVN: r207232
Diffstat (limited to 'gcc/tree-ssa-forwprop.c')
-rw-r--r--gcc/tree-ssa-forwprop.c67
1 files changed, 63 insertions, 4 deletions
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 6389811..41285d3 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2792,9 +2792,7 @@ out:
{
fold_stmt_inplace (gsi);
update_stmt (stmt);
- if (maybe_clean_or_replace_eh_stmt (stmt, stmt)
- && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
- return true;
+ return true;
}
return false;
@@ -3425,6 +3423,53 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
return true;
}
+/* Simplify multiplications.
+ Return true if a transformation applied, otherwise return false. */
+
+static bool
+simplify_mult (gimple_stmt_iterator *gsi)
+{
+ gimple stmt = gsi_stmt (*gsi);
+ tree arg1 = gimple_assign_rhs1 (stmt);
+ tree arg2 = gimple_assign_rhs2 (stmt);
+
+ if (TREE_CODE (arg1) != SSA_NAME)
+ return false;
+
+ gimple def_stmt = SSA_NAME_DEF_STMT (arg1);
+ if (!is_gimple_assign (def_stmt))
+ return false;
+
+ /* Look through a sign-changing conversion. */
+ if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
+ {
+ if (TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (def_stmt)))
+ != TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))
+ || TREE_CODE (gimple_assign_rhs1 (def_stmt)) != SSA_NAME)
+ return false;
+ def_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
+ if (!is_gimple_assign (def_stmt))
+ return false;
+ }
+
+ if (gimple_assign_rhs_code (def_stmt) == EXACT_DIV_EXPR)
+ {
+ if (operand_equal_p (gimple_assign_rhs2 (def_stmt), arg2, 0))
+ {
+ tree res = gimple_assign_rhs1 (def_stmt);
+ if (useless_type_conversion_p (TREE_TYPE (arg1), TREE_TYPE (res)))
+ gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (res), res,
+ NULL_TREE);
+ else
+ gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, res, NULL_TREE);
+ gcc_assert (gsi_stmt (*gsi) == stmt);
+ update_stmt (stmt);
+ return true;
+ }
+ }
+
+ return false;
+}
/* Main entry point for the forward propagation and statement combine
optimizer. */
@@ -3576,9 +3621,23 @@ ssa_forward_propagate_and_combine (void)
|| code == BIT_IOR_EXPR
|| code == BIT_XOR_EXPR)
changed = simplify_bitwise_binary (&gsi);
+ else if (code == MULT_EXPR)
+ {
+ changed = simplify_mult (&gsi);
+ if (changed
+ && maybe_clean_or_replace_eh_stmt (stmt, stmt)
+ && gimple_purge_dead_eh_edges (bb))
+ cfg_changed = true;
+ }
else if (code == PLUS_EXPR
|| code == MINUS_EXPR)
- changed = associate_plusminus (&gsi);
+ {
+ changed = associate_plusminus (&gsi);
+ if (changed
+ && maybe_clean_or_replace_eh_stmt (stmt, stmt)
+ && gimple_purge_dead_eh_edges (bb))
+ cfg_changed = true;
+ }
else if (code == POINTER_PLUS_EXPR)
changed = associate_pointerplus (&gsi);
else if (CONVERT_EXPR_CODE_P (code)