summaryrefslogtreecommitdiffstats
path: root/gcc/tree-ssa-threadedge.c
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-09 02:36:33 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-09 02:36:33 +0000
commit21db594514d8144d3c96ab97ae4a8737c7967cb7 (patch)
treeba679982772c0b010e098d2e80744d59576e9883 /gcc/tree-ssa-threadedge.c
parent39cdc6b4da09003cfc2f546f1802b9ef0311e836 (diff)
downloadppe42-gcc-21db594514d8144d3c96ab97ae4a8737c7967cb7.tar.gz
ppe42-gcc-21db594514d8144d3c96ab97ae4a8737c7967cb7.zip
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@110785 138bc75d-0d04-0410-961f-82ee72b054a4
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 bd78c6b6864..b8d4b1301c6 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. */
OpenPOWER on IntegriCloud