Commit f8ecf734 by Richard Guenther Committed by Richard Biener

tree-ssa-forwprop.c (remove_prop_source_from_use): Robustify against already removed statements.

2011-07-20  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-forwprop.c (remove_prop_source_from_use): Robustify
	against already removed statements.
	(forward_propagate_into_comparison): Remove dead defining stmts.
	(forward_propagate_into_gimple_cond): Likewise.
	(forward_propagate_into_cond): Simplify.
	(ssa_forward_propagate_and_combine): Handle changed cfg from
	forward_propagate_into_comparison.
	* tree-ssa-phiopt.c (conditional_replacement): Use proper
	locations for newly built statements.

From-SVN: r176517
parent 73451ae7
2011-07-20 Richard Guenther <rguenther@suse.de>
* tree-ssa-forwprop.c (remove_prop_source_from_use): Robustify
against already removed statements.
(forward_propagate_into_comparison): Remove dead defining stmts.
(forward_propagate_into_gimple_cond): Likewise.
(forward_propagate_into_cond): Simplify.
(ssa_forward_propagate_and_combine): Handle changed cfg from
forward_propagate_into_comparison.
* tree-ssa-phiopt.c (conditional_replacement): Use proper
locations for newly built statements.
2011-07-20 Georg-Johann Lay <avr@gjlay.de> 2011-07-20 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr.c (avr_rtx_costs): Set cost of SYMBOL_REF to 0. * config/avr/avr.c (avr_rtx_costs): Set cost of SYMBOL_REF to 0.
......
...@@ -313,8 +313,10 @@ remove_prop_source_from_use (tree name) ...@@ -313,8 +313,10 @@ remove_prop_source_from_use (tree name)
return cfg_changed; return cfg_changed;
stmt = SSA_NAME_DEF_STMT (name); stmt = SSA_NAME_DEF_STMT (name);
gsi = gsi_for_stmt (stmt);
bb = gimple_bb (stmt); bb = gimple_bb (stmt);
if (!bb)
return cfg_changed;
gsi = gsi_for_stmt (stmt);
release_defs (stmt); release_defs (stmt);
gsi_remove (&gsi, true); gsi_remove (&gsi, true);
cfg_changed |= gimple_purge_dead_eh_edges (bb); cfg_changed |= gimple_purge_dead_eh_edges (bb);
...@@ -437,29 +439,36 @@ forward_propagate_into_comparison_1 (location_t loc, ...@@ -437,29 +439,36 @@ forward_propagate_into_comparison_1 (location_t loc,
/* Propagate from the ssa name definition statements of the assignment /* Propagate from the ssa name definition statements of the assignment
from a comparison at *GSI into the conditional if that simplifies it. from a comparison at *GSI into the conditional if that simplifies it.
Returns true if the stmt was modified, false if not. */ Returns 1 if the stmt was modified and 2 if the CFG needs cleanup,
otherwise returns 0. */
static bool static int
forward_propagate_into_comparison (gimple_stmt_iterator *gsi) forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
{ {
gimple stmt = gsi_stmt (*gsi); gimple stmt = gsi_stmt (*gsi);
tree tmp; tree tmp;
bool cfg_changed = false;
tree rhs1 = gimple_assign_rhs1 (stmt);
tree rhs2 = gimple_assign_rhs2 (stmt);
/* Combine the comparison with defining statements. */ /* Combine the comparison with defining statements. */
tmp = forward_propagate_into_comparison_1 (gimple_location (stmt), tmp = forward_propagate_into_comparison_1 (gimple_location (stmt),
gimple_assign_rhs_code (stmt), gimple_assign_rhs_code (stmt),
TREE_TYPE TREE_TYPE
(gimple_assign_lhs (stmt)), (gimple_assign_lhs (stmt)),
gimple_assign_rhs1 (stmt), rhs1, rhs2);
gimple_assign_rhs2 (stmt));
if (tmp) if (tmp)
{ {
gimple_assign_set_rhs_from_tree (gsi, tmp); gimple_assign_set_rhs_from_tree (gsi, tmp);
update_stmt (stmt); update_stmt (stmt);
return true; if (TREE_CODE (rhs1) == SSA_NAME)
cfg_changed |= remove_prop_source_from_use (rhs1);
if (TREE_CODE (rhs2) == SSA_NAME)
cfg_changed |= remove_prop_source_from_use (rhs2);
return cfg_changed ? 2 : 1;
} }
return false; return 0;
} }
/* Propagate from the ssa name definition statements of COND_EXPR /* Propagate from the ssa name definition statements of COND_EXPR
...@@ -472,10 +481,12 @@ forward_propagate_into_comparison (gimple_stmt_iterator *gsi) ...@@ -472,10 +481,12 @@ forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
static int static int
forward_propagate_into_gimple_cond (gimple stmt) forward_propagate_into_gimple_cond (gimple stmt)
{ {
int did_something = 0;
location_t loc = gimple_location (stmt); location_t loc = gimple_location (stmt);
tree tmp; tree tmp;
enum tree_code code = gimple_cond_code (stmt); enum tree_code code = gimple_cond_code (stmt);
bool cfg_changed = false;
tree rhs1 = gimple_cond_lhs (stmt);
tree rhs2 = gimple_cond_rhs (stmt);
/* We can do tree combining on SSA_NAME and comparison expressions. */ /* We can do tree combining on SSA_NAME and comparison expressions. */
if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison) if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
...@@ -483,18 +494,13 @@ forward_propagate_into_gimple_cond (gimple stmt) ...@@ -483,18 +494,13 @@ forward_propagate_into_gimple_cond (gimple stmt)
tmp = forward_propagate_into_comparison_1 (loc, code, tmp = forward_propagate_into_comparison_1 (loc, code,
boolean_type_node, boolean_type_node,
gimple_cond_lhs (stmt), rhs1, rhs2);
gimple_cond_rhs (stmt));
if (tmp) if (tmp)
{ {
if (dump_file && tmp) if (dump_file && tmp)
{ {
tree cond = build2 (gimple_cond_code (stmt),
boolean_type_node,
gimple_cond_lhs (stmt),
gimple_cond_rhs (stmt));
fprintf (dump_file, " Replaced '"); fprintf (dump_file, " Replaced '");
print_generic_expr (dump_file, cond, 0); print_gimple_expr (dump_file, stmt, 0, 0);
fprintf (dump_file, "' with '"); fprintf (dump_file, "' with '");
print_generic_expr (dump_file, tmp, 0); print_generic_expr (dump_file, tmp, 0);
fprintf (dump_file, "'\n"); fprintf (dump_file, "'\n");
...@@ -503,14 +509,14 @@ forward_propagate_into_gimple_cond (gimple stmt) ...@@ -503,14 +509,14 @@ forward_propagate_into_gimple_cond (gimple stmt)
gimple_cond_set_condition_from_tree (stmt, unshare_expr (tmp)); gimple_cond_set_condition_from_tree (stmt, unshare_expr (tmp));
update_stmt (stmt); update_stmt (stmt);
/* Remove defining statements. */ if (TREE_CODE (rhs1) == SSA_NAME)
if (is_gimple_min_invariant (tmp)) cfg_changed |= remove_prop_source_from_use (rhs1);
did_something = 2; if (TREE_CODE (rhs2) == SSA_NAME)
else if (did_something == 0) cfg_changed |= remove_prop_source_from_use (rhs2);
did_something = 1; return (cfg_changed || is_gimple_min_invariant (tmp)) ? 2 : 1;
} }
return did_something; return 0;
} }
...@@ -526,7 +532,6 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) ...@@ -526,7 +532,6 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
{ {
gimple stmt = gsi_stmt (*gsi_p); gimple stmt = gsi_stmt (*gsi_p);
location_t loc = gimple_location (stmt); location_t loc = gimple_location (stmt);
int did_something = 0;
tree tmp = NULL_TREE; tree tmp = NULL_TREE;
tree cond = gimple_assign_rhs1 (stmt); tree cond = gimple_assign_rhs1 (stmt);
...@@ -541,7 +546,7 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) ...@@ -541,7 +546,7 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
tree name = cond, rhs0; tree name = cond, rhs0;
gimple def_stmt = get_prop_source_stmt (name, true, NULL); gimple def_stmt = get_prop_source_stmt (name, true, NULL);
if (!def_stmt || !can_propagate_from (def_stmt)) if (!def_stmt || !can_propagate_from (def_stmt))
return did_something; return 0;
rhs0 = gimple_assign_rhs1 (def_stmt); rhs0 = gimple_assign_rhs1 (def_stmt);
tmp = combine_cond_expr_cond (loc, NE_EXPR, boolean_type_node, rhs0, tmp = combine_cond_expr_cond (loc, NE_EXPR, boolean_type_node, rhs0,
...@@ -564,14 +569,10 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) ...@@ -564,14 +569,10 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
stmt = gsi_stmt (*gsi_p); stmt = gsi_stmt (*gsi_p);
update_stmt (stmt); update_stmt (stmt);
/* Remove defining statements. */ return is_gimple_min_invariant (tmp) ? 2 : 1;
if (is_gimple_min_invariant (tmp))
did_something = 2;
else if (did_something == 0)
did_something = 1;
} }
return did_something; return 0;
} }
/* We've just substituted an ADDR_EXPR into stmt. Update all the /* We've just substituted an ADDR_EXPR into stmt. Update all the
...@@ -2441,11 +2442,15 @@ ssa_forward_propagate_and_combine (void) ...@@ -2441,11 +2442,15 @@ ssa_forward_propagate_and_combine (void)
else if (TREE_CODE_CLASS (code) == tcc_comparison) else if (TREE_CODE_CLASS (code) == tcc_comparison)
{ {
bool no_warning = gimple_no_warning_p (stmt); bool no_warning = gimple_no_warning_p (stmt);
int did_something;
fold_defer_overflow_warnings (); fold_defer_overflow_warnings ();
changed = forward_propagate_into_comparison (&gsi); did_something = forward_propagate_into_comparison (&gsi);
if (did_something == 2)
cfg_changed = true;
fold_undefer_overflow_warnings fold_undefer_overflow_warnings
(!no_warning && changed, (!no_warning && changed,
stmt, WARN_STRICT_OVERFLOW_CONDITIONAL); stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
changed = did_something != 0;
} }
else if (code == BIT_AND_EXPR else if (code == BIT_AND_EXPR
|| code == BIT_IOR_EXPR || code == BIT_IOR_EXPR
......
...@@ -544,8 +544,9 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb, ...@@ -544,8 +544,9 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
/* To handle special cases like floating point comparison, it is easier and /* To handle special cases like floating point comparison, it is easier and
less error-prone to build a tree and gimplify it on the fly though it is less error-prone to build a tree and gimplify it on the fly though it is
less efficient. */ less efficient. */
cond = fold_build2 (gimple_cond_code (stmt), boolean_type_node, cond = fold_build2_loc (gimple_location (stmt),
gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); gimple_cond_code (stmt), boolean_type_node,
gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
/* We need to know which is the true edge and which is the false /* We need to know which is the true edge and which is the false
edge so that we know when to invert the condition below. */ edge so that we know when to invert the condition below. */
...@@ -554,7 +555,8 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb, ...@@ -554,7 +555,8 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
|| (e0 == false_edge && integer_onep (arg0)) || (e0 == false_edge && integer_onep (arg0))
|| (e1 == true_edge && integer_zerop (arg1)) || (e1 == true_edge && integer_zerop (arg1))
|| (e1 == false_edge && integer_onep (arg1))) || (e1 == false_edge && integer_onep (arg1)))
cond = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (cond), cond); cond = fold_build1_loc (gimple_location (stmt),
TRUTH_NOT_EXPR, TREE_TYPE (cond), cond);
/* Insert our new statements at the end of conditional block before the /* Insert our new statements at the end of conditional block before the
COND_STMT. */ COND_STMT. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment