This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[ tree-ssa ] cprop into PHI nodes, avoid optimizing unreachable code
- From: law at redhat dot com
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 17 Jul 2003 13:55:38 -0600
- Subject: [ tree-ssa ] cprop into PHI nodes, avoid optimizing unreachable code
- Reply-to: law at redhat dot com
This doesn't fix any of the failures in the tree-ssa tests, but is a
critical hunk of infrastructure for a following set of changes (which
will fix a half-dozen or so failures).
This patch does basically three things.
1. We copy propagate values into PHI nodes [ This nearly makes
tree-ssa-copyprop useless. ]
2. If a COND_EXPR is proven to always go to the same arm, then we remove
edges which reach the other arm.
3. If a block has no incoming edges, then it is unreachable and we
don't bother optimizing it.
Bootstrapped, regression tested, etc.
* tree-ssa-dom.c (optimize_block): Propagate values into PHI nodes.
Do not optimize a block which has become unreachable.
If a COND_EXPR has a compile-time constant condition, then remove
outgoing from the COND_EXPR which can not execute.
Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dom.c,v
retrieving revision 1.1.2.4
diff -c -3 -p -r1.1.2.4 tree-ssa-dom.c
*** tree-ssa-dom.c 16 Jul 2003 22:02:16 -0000 1.1.2.4
--- tree-ssa-dom.c 17 Jul 2003 18:03:56 -0000
*************** optimize_block (basic_block bb, tree par
*** 168,173 ****
--- 168,175 ----
block_stmt_iterator si;
tree prev_value = NULL_TREE;
tree eq_expr_value = NULL_TREE;
+ edge e;
+ tree phi;
/* Initialize the local stacks.
*************** optimize_block (basic_block bb, tree par
*** 207,212 ****
--- 209,242 ----
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
optimize_stmt (si, &block_avail_exprs);
+ /* Propagate known constants/copies into PHI node alternatives for
+ successors of this block. */
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
+ {
+ int i;
+
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ tree new;
+ if (PHI_ARG_EDGE (phi, i) == e)
+ {
+ tree *orig_p = &PHI_ARG_DEF (phi, i);
+
+ /* FIXME. We should be able to propagate constants into
+ PHI nodes in the not too distant future. */
+ new = get_value_for (*orig_p, const_and_copies);
+ if (new
+ && TREE_CODE (new) == SSA_NAME
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new)
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (*orig_p))
+ *orig_p = new;
+ }
+ }
+ }
+ }
+
/* Recursively optimize the dominator children of BB. */
children = dom_children (bb);
if (children)
*************** optimize_block (basic_block bb, tree par
*** 215,227 ****
{
tree last = last_stmt (bb);
EXECUTE_IF_SET_IN_BITMAP (children, 0, i,
! optimize_block (BASIC_BLOCK (i), last,
! BASIC_BLOCK (i)->pred->flags));
}
else
{
EXECUTE_IF_SET_IN_BITMAP (children, 0, i,
! optimize_block (BASIC_BLOCK (i), NULL_TREE, 0));
}
}
--- 245,270 ----
{
tree last = last_stmt (bb);
EXECUTE_IF_SET_IN_BITMAP (children, 0, i,
! {
! basic_block dest = BASIC_BLOCK (i);
!
! /* The destination block may have become unreachable, in
! which case there's no point in optimizing it. */
! if (dest->pred)
! optimize_block (dest, last, dest->pred->flags);
! });
}
else
{
EXECUTE_IF_SET_IN_BITMAP (children, 0, i,
! {
! basic_block dest = BASIC_BLOCK (i);
!
! /* The destination block may have become unreachable, in
! which case there's no point in optimizing it. */
! if (dest->pred)
! optimize_block (dest, NULL_TREE, 0);
! });
}
}
*************** optimize_stmt (block_stmt_iterator si, v
*** 470,475 ****
--- 513,542 ----
set_value_for (*def_p, rhs, const_and_copies);
}
}
+
+ /* If STMT is a COND_EXPR and it was modified, then we may know
+ where it goes. In which case we can remove some edges, simplify
+ some PHI nodes, maybe even avoid optimizing some blocks completely,
+ etc. */
+ if (TREE_CODE (stmt) == COND_EXPR && ann->modified)
+ {
+ basic_block bb = bb_for_stmt (stmt);
+ edge taken_edge = find_taken_edge (bb, TREE_OPERAND (stmt, 0));
+
+ if (taken_edge)
+ {
+ edge e, next;
+ /* The other edges leaving this block are not executable
+ and can be removed. */
+ for (e = bb_for_stmt (stmt)->succ; e; e = next)
+ {
+ next = e->succ_next;
+ if (e != taken_edge)
+ ssa_remove_edge (e);
+ }
+ }
+ }
+
}
/* Hashing and equality functions for VAR_VALUE_D. */