aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-propagate.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-08-04 12:29:48 +0000
committerRichard Guenther <rguenther@suse.de>2010-08-04 12:29:48 +0000
commit6fb768c6689acede61558b6f322c7812cf0f8b0f (patch)
tree44d87dd02a78032816f3cb81e0405f29ab9570c6 /gcc/tree-ssa-propagate.c
parent58446664bb013e9499498489376c635e163d4ba9 (diff)
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: https://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.c75
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)