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
This commit is contained in:
Jeff Law 2006-02-08 19:36:33 -07:00 committed by Jeff Law
parent 0a180c0ee8
commit d537b2ebb0
4 changed files with 86 additions and 9 deletions

View File

@ -1,5 +1,12 @@
2006-02-08 Jeff Law <law@redhat.com>
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

View File

@ -1,3 +1,7 @@
2006-02-08 Jeff Law <law@redhat.com>
* gcc.dg/tree-ssa/pr21417.c: New test.
2006-02-08 Paolo Bonzini <bonzini@gnu.org>
* lib/scantree.exp (scan-tree-dump, scan-tree-dump-times,

View File

@ -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" } } */

View File

@ -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. */