diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-09 02:36:33 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-09 02:36:33 +0000 |
commit | 21db594514d8144d3c96ab97ae4a8737c7967cb7 (patch) | |
tree | ba679982772c0b010e098d2e80744d59576e9883 /gcc/tree-ssa-threadedge.c | |
parent | 39cdc6b4da09003cfc2f546f1802b9ef0311e836 (diff) | |
download | gcc-21db594514d8144d3c96ab97ae4a8737c7967cb7.tar.gz |
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.c | 30 |
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. */ |