aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-threadedge.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2006-02-08 19:36:33 -0700
committerJeff Law <law@gcc.gnu.org>2006-02-08 19:36:33 -0700
commitd537b2ebb028550ea757435150937003fa9fe30a (patch)
treeba679982772c0b010e098d2e80744d59576e9883 /gcc/tree-ssa-threadedge.c
parent0a180c0ee8779e656fd59c604a4a4443e242a7f7 (diff)
downloadgcc-d537b2ebb028550ea757435150937003fa9fe30a.zip
gcc-d537b2ebb028550ea757435150937003fa9fe30a.tar.gz
gcc-d537b2ebb028550ea757435150937003fa9fe30a.tar.bz2
re PR tree-optimization/21417 (Missed jump threading opportunity on trees)
PR tree-optimization/21417 * tree-ssa-threadedge.c (thread_across_edge): Reject threading across a backedge if the control statement at the end of the block is data dependent on other statements in the same block. (record_temporary_equivalences_from_stmts): Remove over-conservative test for threading across backedges. * gcc.dg/tree-ssa/pr21417.c: New test. From-SVN: r110785
Diffstat (limited to 'gcc/tree-ssa-threadedge.c')
-rw-r--r--gcc/tree-ssa-threadedge.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index bd78c6b..b8d4b13 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -231,15 +231,6 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
if (IS_EMPTY_STMT (stmt) || TREE_CODE (stmt) == LABEL_EXPR)
continue;
- /* Safely handle threading across loop backedges. Only allowing
- a conditional at the target of the backedge is over conservative,
- but still allows us to capture the majority of the cases where
- we can thread across a loop backedge. */
- if ((e->flags & EDGE_DFS_BACK) != 0
- && TREE_CODE (stmt) != COND_EXPR
- && TREE_CODE (stmt) != SWITCH_EXPR)
- return NULL;
-
/* If the statement has volatile operands, then we assume we
can not thread through this block. This is overly
conservative in some ways. */
@@ -496,6 +487,27 @@ thread_across_edge (tree dummy_cond,
{
tree stmt;
+ /* If E is a backedge, then we want to verify that the COND_EXPR,
+ SWITCH_EXPR or GOTO_EXPR at the end of e->dest is not affected
+ by any statements in e->dest. If it is affected, then it is not
+ safe to thread this edge. */
+ if (e->flags & EDGE_DFS_BACK)
+ {
+ ssa_op_iter iter;
+ use_operand_p use_p;
+ tree last = bsi_stmt (bsi_last (e->dest));
+
+ FOR_EACH_SSA_USE_OPERAND (use_p, last, iter, SSA_OP_USE | SSA_OP_VUSE)
+ {
+ tree use = USE_FROM_PTR (use_p);
+
+ if (TREE_CODE (use) == SSA_NAME
+ && TREE_CODE (SSA_NAME_DEF_STMT (use)) != PHI_NODE
+ && bb_for_stmt (SSA_NAME_DEF_STMT (use)) == e->dest)
+ goto fail;
+ }
+ }
+
stmt_count = 0;
/* PHIs create temporary equivalences. */