From 21db594514d8144d3c96ab97ae4a8737c7967cb7 Mon Sep 17 00:00:00 2001 From: law Date: Thu, 9 Feb 2006 02:36:33 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 +++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/tree-ssa/pr21417.c | 54 +++++++++++++++++++++++++++++++++ gcc/tree-ssa-threadedge.c | 30 ++++++++++++------ 4 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr21417.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5f7e20ca1e2..9aef9b8a009 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2006-02-08 Jeff Law + 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. + * tree-ssa-dce.c (remove_dead_statement): When removing a dead control statement, handle all three special cases in the same manner as they all have the same desired solution. No longer diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4d6908f71a3..ad136b3aeb1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2006-02-08 Jeff Law + + * gcc.dg/tree-ssa/pr21417.c: New test. + 2006-02-08 Paolo Bonzini * lib/scantree.exp (scan-tree-dump, scan-tree-dump-times, diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c new file mode 100644 index 00000000000..e6320071daf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom3-details" } */ + +struct tree_common +{ + int code; +}; +union tree_node +{ + struct tree_common common; +}; +typedef union tree_node *tree; + +extern tree test (tree, int, int); +extern tree foo (void); +extern void abort (void) __attribute__ ((__noreturn__)); + +tree +test (tree expr, int t, int D17630) +{ + int __i; + +L0: + if (expr->common.code != 142) goto L23; else goto L2; + +L2: + __i = 0; + goto L10; + +L10: + __i = __i + 1; + if (D17630 != __i) goto L8; else goto L19; + +L8: + if (t) goto L15; else goto L10; + +L15: + expr = foo (); + if (expr->common.code != 142) goto L23; else goto L0; + +L19: + abort (); + +L23: + return expr; +} + + +/* We should thread the backedge to the top of the loop; ie we only + execute the if (expr->common.code != 142) test once per loop + iteration. */ +/* { dg-final { scan-tree-dump-times "Threaded jump" 1 "dom3" } } */ +/* { dg-final { cleanup-tree-dump "dom3" } } */ + 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. */ -- 2.11.0