diff options
author | Richard Biener <rguenther@suse.de> | 2014-01-29 11:08:59 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2014-01-29 11:08:59 +0000 |
commit | 4bfb2fa258b5aec3de431eec08288accf0bd5529 (patch) | |
tree | e500de9b76caaa9de2e3b1a7441d2929b980d847 /gcc/tree-ssa-forwprop.c | |
parent | 09b22f48d435d158761a02117facec4daa7395fb (diff) | |
download | gcc-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.c | 67 |
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) |