Commit 048d9936 by Zdenek Dvorak Committed by Zdenek Dvorak

tree-ssa.c (raise_value): Removed.

	* tree-ssa.c (raise_value): Removed.
	(get_eq_name, check_phi_redundancy): New functions.
	(kill_redundant_phi_nodes): Use standard ssa minimalization algorithm.

From-SVN: r83380
parent ee8db92b
2004-06-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* tree-ssa.c (raise_value): Removed.
(get_eq_name, check_phi_redundancy): New functions.
(kill_redundant_phi_nodes): Use standard ssa minimalization algorithm.
2004-06-18 Roger Sayle <roger@eyesopen.com> 2004-06-18 Roger Sayle <roger@eyesopen.com>
* fold-const.c (fold) <UNORDERED_EXPR, ORDERED_EXPR, UNLT_EXPR, * fold-const.c (fold) <UNORDERED_EXPR, ORDERED_EXPR, UNLT_EXPR,
......
...@@ -831,41 +831,90 @@ replace_immediate_uses (tree var, tree repl) ...@@ -831,41 +831,90 @@ replace_immediate_uses (tree var, tree repl)
} }
} }
/* Raises value of phi node PHI by joining it with VAL. Processes immediate /* Gets the value VAR is equivalent to according to EQ_TO. */
uses of PHI recursively. */
static tree
get_eq_name (tree *eq_to, tree var)
{
unsigned ver;
tree val = var;
while (TREE_CODE (val) == SSA_NAME)
{
ver = SSA_NAME_VERSION (val);
if (!eq_to[ver])
break;
val = eq_to[ver];
}
while (TREE_CODE (var) == SSA_NAME)
{
ver = SSA_NAME_VERSION (var);
if (!eq_to[ver])
break;
var = eq_to[ver];
eq_to[ver] = val;
}
return val;
}
/* Checks whether phi node PHI is redundant and if it is, records the ssa name
its result is redundant to to EQ_TO array. */
static void static void
raise_value (tree phi, tree val, tree *eq_to) check_phi_redundancy (tree phi, tree *eq_to)
{ {
int i, n; tree val = NULL_TREE, def, res = PHI_RESULT (phi), stmt;
tree var = PHI_RESULT (phi), stmt; unsigned i, ver = SSA_NAME_VERSION (res), n;
int ver = SSA_NAME_VERSION (var);
dataflow_t df; dataflow_t df;
if (eq_to[ver] == var) /* It is unlikely that such large phi node would be redundant. */
if (PHI_NUM_ARGS (phi) > 16)
return; return;
if (eq_to[ver]) for (i = 0; i < (unsigned) PHI_NUM_ARGS (phi); i++)
{
def = PHI_ARG_DEF (phi, i);
if (TREE_CODE (def) == SSA_NAME)
{ {
if (operand_equal_p (eq_to[ver], val, 0)) def = get_eq_name (eq_to, def);
if (def == res)
continue;
}
if (val
&& !operand_equal_p (val, def, 0))
return; return;
eq_to[ver] = var; val = def;
} }
else
/* At least one of the arguments should not be equal to the result, or
something strange is happening. */
if (!val)
abort ();
if (get_eq_name (eq_to, res) == val)
return;
if (!may_propagate_copy (res, val))
return;
eq_to[ver] = val; eq_to[ver] = val;
df = get_immediate_uses (SSA_NAME_DEF_STMT (var)); df = get_immediate_uses (SSA_NAME_DEF_STMT (res));
n = num_immediate_uses (df); n = num_immediate_uses (df);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
stmt = immediate_use (df, i); stmt = immediate_use (df, i);
if (TREE_CODE (stmt) != PHI_NODE) if (TREE_CODE (stmt) == PHI_NODE)
continue; check_phi_redundancy (stmt, eq_to);
raise_value (stmt, eq_to[ver], eq_to);
} }
} }
...@@ -890,26 +939,17 @@ static void ...@@ -890,26 +939,17 @@ static void
kill_redundant_phi_nodes (void) kill_redundant_phi_nodes (void)
{ {
tree *eq_to; tree *eq_to;
unsigned i; unsigned i, old_num_ssa_names;
basic_block bb; basic_block bb;
tree phi, t, stmt, var; tree phi, var, repl, stmt;
/* The EQ_TO array holds the current value of the ssa name in the /* The EQ_TO[VER] holds the value by that the ssa name VER should be
lattice: replaced. If EQ_TO[VER] is ssa name and it is decided to replace it by
other value, it may be necessary to follow the chain till the final value.
top We perform path shortening (replacing the entries of the EQ_TO array with
/ | \ heads of these chains) whenever we access the field to prevent quadratic
const variables complexity (probably would not occur in practice anyway, but let us play
\ | / it safe). */
bottom
Bottom is represented by NULL and top by the variable itself.
Once the dataflow stabilizes, we know that the phi nodes we need to keep
are exactly those with top as their result.
The remaining phi nodes have their uses replaced with their value
in the lattice and the phi node itself is removed. */
eq_to = xcalloc (num_ssa_names, sizeof (tree)); eq_to = xcalloc (num_ssa_names, sizeof (tree));
/* We have had cases where computing immediate uses takes a /* We have had cases where computing immediate uses takes a
...@@ -918,68 +958,40 @@ kill_redundant_phi_nodes (void) ...@@ -918,68 +958,40 @@ kill_redundant_phi_nodes (void)
a subset of all the SSA_NAMEs instead of computing it for a subset of all the SSA_NAMEs instead of computing it for
all of the SSA_NAMEs. */ all of the SSA_NAMEs. */
compute_immediate_uses (TDFA_USE_OPS | TDFA_USE_VOPS, NULL); compute_immediate_uses (TDFA_USE_OPS | TDFA_USE_VOPS, NULL);
old_num_ssa_names = num_ssa_names;
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
{ {
var = PHI_RESULT (phi); var = PHI_RESULT (phi);
check_phi_redundancy (phi, eq_to);
/* If the destination of the PHI is associated with an
abnormal edge, then we can not propagate this PHI away. */
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (var))
{
raise_value (phi, var, eq_to);
continue;
} }
for (i = 0; i < (unsigned) PHI_NUM_ARGS (phi); i++)
{
t = PHI_ARG_DEF (phi, i);
if (TREE_CODE (t) != SSA_NAME)
{
raise_value (phi, t, eq_to);
continue;
} }
stmt = SSA_NAME_DEF_STMT (t); /* Now propagate the values. */
for (i = 0; i < old_num_ssa_names; i++)
/* If any particular PHI argument is associated with
an abnormal edge, then we know that we should not
be propagating away this PHI. Go ahead and raise
the result of this PHI to the top of the lattice. */
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (t))
{ {
raise_value (phi, var, eq_to); if (!ssa_name (i))
continue; continue;
}
/* If the defining statement for this argument is not a repl = get_eq_name (eq_to, ssa_name (i));
phi node then we need to recursively start the forward if (repl != ssa_name (i))
dataflow starting with PHI. */ replace_immediate_uses (ssa_name (i), repl);
if (TREE_CODE (stmt) != PHI_NODE)
{
eq_to[SSA_NAME_VERSION (t)] = t;
raise_value (phi, t, eq_to);
}
}
} }
}
/* Now propagate the values. */
for (i = 0; i < num_ssa_names; i++)
if (eq_to[i]
&& eq_to[i] != ssa_name (i))
replace_immediate_uses (ssa_name (i), eq_to[i]);
/* And remove the dead phis. */ /* And remove the dead phis. */
for (i = 0; i < num_ssa_names; i++) for (i = 0; i < old_num_ssa_names; i++)
if (eq_to[i] {
&& eq_to[i] != ssa_name (i)) if (!ssa_name (i))
continue;
repl = get_eq_name (eq_to, ssa_name (i));
if (repl != ssa_name (i))
{ {
stmt = SSA_NAME_DEF_STMT (ssa_name (i)); stmt = SSA_NAME_DEF_STMT (ssa_name (i));
remove_phi_node (stmt, 0, bb_for_stmt (stmt)); remove_phi_node (stmt, NULL_TREE, bb_for_stmt (stmt));
}
} }
free_df (); free_df ();
......
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