This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, PR69468] Ignore EDGE_{DFS_BACK,EXECUTABLE} in tail-merge


[ was: Re: [PATCH, PR81192] Don't tail-merge blocks from different loops ]

On 07/03/2017 12:49 AM, Tom de Vries wrote:
[ was: Re: [PATCH, PR81192] Fix sigsegv in find_same_succ_bb ]

On 07/03/2017 12:26 AM, Tom de Vries wrote:
[ Trying again with before.svg instead of before.pdf ]

Hi,

consider this test-case:
...
unsigned a;
int b, c;

static int
fn1 (int p1, int p2)
{
   return p1 > 2147483647 - p2 ? p1 : p1 + p2;
}

void
fn2 (void)
{
   int j;
   a = 30;
   for (; a;)
     for (; c; b = fn1 (j, 1))
       ;
}
...

When compiling the test-case with -Os, just before tail-merge it looks as in before.svg.

During tail-merge, it runs into a sigsegv.

What happens is the following:
- tail-merge decides to merge blocks 4 and 6, and removes block 6.

As pointed out in the PR, blocks 4 and 6 belong to different loops, and shouldn't be merged.


While working on this PR, I used print_graph_cfg in tail-merge, which I noticed changes the choice in merging blocks. I tracked this down to:
- mark_dfs_back_edges changing the EDGE_DFS_BACK flag on some edges, and
- tail-merge requiring identical edge flags (apart from the true/false
  flags, which are dealt with explicitly).

This is similar to PR69468 which notices the same about EDGE_EXECUTABLE.

This patch allows more tail-merging by ignoring both EDGE_DFS_BACK and EDGE_EXECUTABLE. Consequently, in this example the two latch bbs (of the same loop) bb4 and bb7 are merged.

Bootstrapped and reg-tested on x86_64.

OK for trunk?

Thanks,
- Tom
Ignore EDGE_{DFS_BACK,EXECUTABLE} in tail-merge

2017-06-30  Tom de Vries  <tom@codesourcery.com>

	PR tree-optimization/69468
	* tree-ssa-tail-merge.c (ignore_edge_flags): New constant.
	(find_same_succ_bb): Handle ignore_edge_flags.

	* gcc.dg/pr81192.c: Update.

---
 gcc/testsuite/gcc.dg/pr81192.c | 2 +-
 gcc/tree-ssa-tail-merge.c      | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr81192.c b/gcc/testsuite/gcc.dg/pr81192.c
index 8b3a77a..57eb478 100644
--- a/gcc/testsuite/gcc.dg/pr81192.c
+++ b/gcc/testsuite/gcc.dg/pr81192.c
@@ -19,4 +19,4 @@ fn2 (void)
       ;
 }
 
-/* { dg-final { scan-tree-dump-not "(?n)find_duplicates: <bb .*> duplicate of <bb .*>" "pre" } } */
+/* { dg-final { scan-tree-dump-times "(?n)find_duplicates: <bb .*> duplicate of <bb .*>" 1 "pre" } } */
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index 0865e86..6f199de 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -207,6 +207,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-eh.h"
 #include "tree-cfgcleanup.h"
 
+const int ignore_edge_flags = EDGE_DFS_BACK | EDGE_EXECUTABLE;
+
 /* Describes a group of bbs with the same successors.  The successor bbs are
    cached in succs, and the successor edge flags are cached in succ_flags.
    If a bb has the EDGE_TRUE/FALSE_VALUE flags swapped compared to succ_flags,
@@ -707,7 +709,7 @@ find_same_succ_bb (basic_block bb, same_succ **same_p)
     {
       int index = e->dest->index;
       bitmap_set_bit (same->succs, index);
-      same_succ_edge_flags[index] = e->flags;
+      same_succ_edge_flags[index] = (e->flags & ~ignore_edge_flags);
     }
   EXECUTE_IF_SET_IN_BITMAP (same->succs, 0, j, bj)
     same->succ_flags.safe_push (same_succ_edge_flags[j]);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]