From b9e59e4f11bc85b72167f93d1f356ff77074af01 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 6 Nov 2015 16:26:20 -0700 Subject: [PATCH] [PATCH] Allow vrp to thread across backedges using FSM threader * cfg-flags.def (IGNORE): New edge flag. * tree-vrp.c (identify_jump_threads): Mark and clear edges scheduled for removal with EDGE_IGNORE around call into jump threader. Do no thread across edges with EDGE_IGNORE, but do allow threading across those with EDGE_DFS_BACK. * gcc.dg/tree-ssa/ssa-dom-thread-7.c: Adjust to look for realized jump threads. * gcc.dg/tree-ssa-pr66752-3.c: Look in vrp1 dump for jump threads rather than dom1 dump. From-SVN: r229902 --- gcc/ChangeLog | 8 ++++++++ gcc/cfg-flags.def | 7 ++++++- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c | 4 ++-- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c | 6 ++++-- gcc/tree-vrp.c | 14 +++++++++----- 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e2f588bf666..552c51b2ceb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-11-06 Jeff Law + + * cfg-flags.def (IGNORE): New edge flag. + * tree-vrp.c (identify_jump_threads): Mark and clear edges + scheduled for removal with EDGE_IGNORE around call into + jump threader. Do no thread across edges with EDGE_IGNORE, + but do allow threading across those with EDGE_DFS_BACK. + 2015-11-06 David Wohlferd * doc/md.texi (multi-alternative constraints): Don't document diff --git a/gcc/cfg-flags.def b/gcc/cfg-flags.def index eedcd692724..e2bfbed5ecf 100644 --- a/gcc/cfg-flags.def +++ b/gcc/cfg-flags.def @@ -78,7 +78,7 @@ DEF_BASIC_BLOCK_FLAG(RTL, 9) DEF_BASIC_BLOCK_FLAG(FORWARDER_BLOCK, 10) /* Set on blocks that cannot be threaded through. - Only used in cfgcleanup.c. */ + Only used for jump threading. */ DEF_BASIC_BLOCK_FLAG(NONTHREADABLE_BLOCK, 11) /* Set on blocks that were modified in some way. This bit is set in @@ -177,6 +177,11 @@ DEF_EDGE_FLAG(TM_UNINSTRUMENTED, 15) /* Abort (over) edge out of a GIMPLE_TRANSACTION statement. */ DEF_EDGE_FLAG(TM_ABORT, 16) +/* An edge we should ignore. It should be entirely local to + passes. ie, it is never set on any edge upon the completion + of any pass. */ +DEF_EDGE_FLAG(IGNORE, 17) + #endif /* diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 80221c1e301..af4a7387e82 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-11-06 Jeff Law + + * gcc.dg/tree-ssa/ssa-dom-thread-7.c: Adjust to look for + realized jump threads. + * gcc.dg/tree-ssa-pr66752-3.c: Look in vrp1 dump for jump + threads rather than dom1 dump. + 2015-11-06 Michael Collison diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c index f15b5986166..577a489dd8c 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr66752-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-dom1-details -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-vrp1-details -fdump-tree-optimized" } */ extern int status, pt; extern int count; @@ -33,7 +33,7 @@ foo (int N, int c, int b, int *a) } /* There are 3 FSM jump threading opportunities. */ -/* { dg-final { scan-tree-dump-times "FSM" 3 "dom1"} } */ +/* { dg-final { scan-tree-dump-times "FSM" 3 "vrp1"} } */ /* There should be no assignments or references to FLAG. */ /* { dg-final { scan-tree-dump-not "flag" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c index 445f2509dc3..ac12b6ca714 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c @@ -1,6 +1,8 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-dom1-details" } */ -/* { dg-final { scan-tree-dump-times "FSM" 38 "dom1" } } */ +/* { dg-options "-O2 -fdump-tree-vrp1-stats -fdump-tree-dom1-stats -fdump-tree-dom2-stats" } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 7" "vrp1" } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 12" "dom1" } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 3" "dom2" } } */ enum STATE { S0=0, diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index c0b6cfc1444..87c02654c48 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -10076,9 +10076,9 @@ identify_jump_threads (void) mark_dfs_back_edges (); /* Do not thread across edges we are about to remove. Just marking - them as EDGE_DFS_BACK will do. */ + them as EDGE_IGNORE will do. */ FOR_EACH_VEC_ELT (to_remove_edges, i, e) - e->flags |= EDGE_DFS_BACK; + e->flags |= EDGE_IGNORE; /* Allocate our unwinder stack to unwind any temporary equivalences that might be recorded. */ @@ -10135,9 +10135,9 @@ identify_jump_threads (void) it to a specific successor. */ FOR_EACH_EDGE (e, ei, bb->preds) { - /* Do not thread across back edges or abnormal edges - in the CFG. */ - if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)) + /* Do not thread across edges marked to ignoreor abnormal + edges in the CFG. */ + if (e->flags & (EDGE_IGNORE | EDGE_COMPLEX)) continue; thread_across_edge (dummy, e, true, equiv_stack, NULL, @@ -10146,6 +10146,10 @@ identify_jump_threads (void) } } + /* Clear EDGE_IGNORE. */ + FOR_EACH_VEC_ELT (to_remove_edges, i, e) + e->flags &= ~EDGE_IGNORE; + /* We do not actually update the CFG or SSA graphs at this point as ASSERT_EXPRs are still in the IL and cfg cleanup code does not yet handle ASSERT_EXPRs gracefully. */ -- 2.30.2