diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-04 12:29:48 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-04 12:29:48 +0000 |
commit | 14f101cffa72ffaa29995b1e6a3597c676a7882a (patch) | |
tree | 44d87dd02a78032816f3cb81e0405f29ab9570c6 /gcc/tree-ssa-propagate.c | |
parent | 459a1bdc1386060a2ca9d65c7f03c401001d1ee7 (diff) | |
download | gcc-14f101cffa72ffaa29995b1e6a3597c676a7882a.tar.gz |
2010-08-04 Richard Guenther <rguenther@suse.de>
* tree-ssa-propagate.h (struct prop_value_d, prop_value_t): Move ...
* tree-ssa-ccp.c: ... here.
* tree-ssa-copy.c: ... and here.
* tree-ssa-propagate.h (enum value_range_type, struct value_range_d,
value_range_t): Move ...
* tree-vrp.c: ... here.
* tree-ssa-propagate.h (ssa_prop_get_value_fn): New typedef.
(substitute_and_fold): Adjust prototype.
* tree-ssa-propagate.c (replace_uses_in): Adjust.
(replace_phi_args_in): Likewise.
(substitute_and_fold): Take callback to query lattice instead
of pointer to lattice. Replace SSA name defs with lattice
values first.
* tree-ssa-ccp.c (ccp_finalize): Adjust.
* tree-ssa-copy.c (copy_prop_visit_phi_node): Adjust.
(get_value): New function.
(fini_copy_prop): Adjust.
* tree-vrp.c (vrp_finalize): Adjust.
* gcc.dg/tree-ssa/vrp35.c: Adjust.
* gcc.dg/tree-ssa/vrp36.c: Likewise.
* gcc.dg/tree-ssa/vrp50.c: Likewise.
* gcc.dg/tree-ssa/vrp52.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162864 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-propagate.c')
-rw-r--r-- | gcc/tree-ssa-propagate.c | 75 |
1 files changed, 64 insertions, 11 deletions
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 6f50fc5453a..e08d2e7ae0c 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -872,7 +872,7 @@ static struct prop_stats_d prop_stats; PROP_VALUE. Return true if at least one reference was replaced. */ static bool -replace_uses_in (gimple stmt, prop_value_t *prop_value) +replace_uses_in (gimple stmt, ssa_prop_get_value_fn get_value) { bool replaced = false; use_operand_p use; @@ -881,7 +881,7 @@ replace_uses_in (gimple stmt, prop_value_t *prop_value) FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE) { tree tuse = USE_FROM_PTR (use); - tree val = prop_value[SSA_NAME_VERSION (tuse)].value; + tree val = (*get_value) (tuse); if (val == tuse || val == NULL_TREE) continue; @@ -911,7 +911,7 @@ replace_uses_in (gimple stmt, prop_value_t *prop_value) values from PROP_VALUE. */ static void -replace_phi_args_in (gimple phi, prop_value_t *prop_value) +replace_phi_args_in (gimple phi, ssa_prop_get_value_fn get_value) { size_t i; bool replaced = false; @@ -928,7 +928,7 @@ replace_phi_args_in (gimple phi, prop_value_t *prop_value) if (TREE_CODE (arg) == SSA_NAME) { - tree val = prop_value[SSA_NAME_VERSION (arg)].value; + tree val = (*get_value) (arg); if (val && val != arg && may_propagate_copy (arg, val)) { @@ -978,13 +978,15 @@ replace_phi_args_in (gimple phi, prop_value_t *prop_value) Return TRUE when something changed. */ bool -substitute_and_fold (prop_value_t *prop_value, ssa_prop_fold_stmt_fn fold_fn, +substitute_and_fold (ssa_prop_get_value_fn get_value_fn, + ssa_prop_fold_stmt_fn fold_fn, bool do_dce) { basic_block bb; bool something_changed = false; + unsigned i; - if (prop_value == NULL && !fold_fn) + if (!get_value_fn && !fold_fn) return false; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -992,15 +994,66 @@ substitute_and_fold (prop_value_t *prop_value, ssa_prop_fold_stmt_fn fold_fn, memset (&prop_stats, 0, sizeof (prop_stats)); - /* Substitute values in every statement of every basic block. */ + /* Substitute lattice values at definition sites. */ + if (get_value_fn) + for (i = 1; i < num_ssa_names; ++i) + { + tree name = ssa_name (i); + tree val; + gimple def_stmt; + gimple_stmt_iterator gsi; + + if (!name + || !is_gimple_reg (name)) + continue; + + def_stmt = SSA_NAME_DEF_STMT (name); + if (gimple_nop_p (def_stmt) + /* Do not substitute ASSERT_EXPR rhs, this will confuse VRP. */ + || (gimple_assign_single_p (def_stmt) + && gimple_assign_rhs_code (def_stmt) == ASSERT_EXPR) + || !(val = (*get_value_fn) (name)) + || !may_propagate_copy (name, val)) + continue; + + gsi = gsi_for_stmt (def_stmt); + if (is_gimple_assign (def_stmt)) + { + gimple_assign_set_rhs_with_ops (&gsi, TREE_CODE (val), + val, NULL_TREE); + gcc_assert (gsi_stmt (gsi) == def_stmt); + if (maybe_clean_eh_stmt (def_stmt)) + gimple_purge_dead_eh_edges (gimple_bb (def_stmt)); + update_stmt (def_stmt); + } + else if (is_gimple_call (def_stmt)) + { + if (update_call_from_tree (&gsi, val) + && maybe_clean_or_replace_eh_stmt (def_stmt, gsi_stmt (gsi))) + gimple_purge_dead_eh_edges (gimple_bb (gsi_stmt (gsi))); + } + else if (gimple_code (def_stmt) == GIMPLE_PHI) + { + gimple new_stmt = gimple_build_assign (name, val); + gimple_stmt_iterator gsi2; + SSA_NAME_DEF_STMT (name) = new_stmt; + gsi2 = gsi_after_labels (gimple_bb (def_stmt)); + gsi_insert_before (&gsi2, new_stmt, GSI_SAME_STMT); + remove_phi_node (&gsi, false); + } + + something_changed = true; + } + + /* Propagate into all uses and fold. */ FOR_EACH_BB (bb) { gimple_stmt_iterator i; /* Propagate known values into PHI nodes. */ - if (prop_value) + if (get_value_fn) for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) - replace_phi_args_in (gsi_stmt (i), prop_value); + replace_phi_args_in (gsi_stmt (i), get_value_fn); /* Propagate known values into stmts. Do a backward walk to expose more trivially deletable stmts. */ @@ -1073,9 +1126,9 @@ substitute_and_fold (prop_value_t *prop_value, ssa_prop_fold_stmt_fn fold_fn, /* Only replace real uses if we couldn't fold the statement using value range information. */ - if (prop_value + if (get_value_fn && !did_replace) - did_replace |= replace_uses_in (stmt, prop_value); + did_replace |= replace_uses_in (stmt, get_value_fn); /* If we made a replacement, fold the statement. */ if (did_replace) |