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][PR tree-optimization/69999] Schedule loop fixups when duplicating certain blocks for path splitting




We've recently started looking at getting loop fixups scheduled when removing edges to address a regression.

This BZ is a closely related problem, namely that duplicating a block can turn an irreducible loop into a natural loop as well. After the problems with tying into the low level CFG manipulation code for the edge removal code, I don't want to go down that path again for gcc-6 in the block duplication code.

Thus this patch targets the specific pass (path splitting) that is duplicating the blocks rather than doing something more general in the block duplication code. Hence this only fixes the one known instance of this problem. I wouldn't be terribly surprised if folks are able to coerce other passes that duplicate blocks into generating similar problems.

I suspect for gcc-7 and beyond we're going to want to look at how the CFG and loop codes need to communicate/cooperate better on this stuff.

Bootstrapped and regression tested on x86_64-linux-gnu. Installing on the trunk momentarily.

Jeff
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 966e06d..653b51e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-02-28  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/69999
+	* gimple-ssa-split-paths.c (split_paths): When duplicating a block
+	with an outgoing edge marked with EDGE_IRREDUCIBLE_LOOP, schedule
+	loop cleanups.
+
 2016-02-29  Richard Biener  <rguenther@suse.de>
 
 	PR tree-optimization/69994
diff --git a/gcc/gimple-ssa-split-paths.c b/gcc/gimple-ssa-split-paths.c
index ac6de81..0a0bef8 100644
--- a/gcc/gimple-ssa-split-paths.c
+++ b/gcc/gimple-ssa-split-paths.c
@@ -294,6 +294,24 @@ split_paths ()
 	  basic_block pred0 = EDGE_PRED (bb, 0)->src;
 	  transform_duplicate (pred0, bb);
 	  changed = true;
+
+	  /* If BB has an outgoing edge marked as IRREDUCIBLE, then
+	     duplicating BB may result in an irreducible region turning
+	     into a natural loop.
+
+	     Long term we might want to hook this into the block
+	     duplication code, but as we've seen with similar changes
+	     for edge removal, that can be somewhat risky.  */
+	  if (EDGE_SUCC (bb, 0)->flags & EDGE_IRREDUCIBLE_LOOP
+	      || EDGE_SUCC (bb, 1)->flags & EDGE_IRREDUCIBLE_LOOP)
+	    {
+	      if (dump_file && (dump_flags & TDF_DETAILS))
+		  fprintf (dump_file,
+			   "Join block %d has EDGE_IRREDUCIBLE_LOOP set.  "
+			   "Scheduling loop fixups.\n",
+			   bb->index);
+	      loops_state_set (LOOPS_NEED_FIXUP);
+	    }
 	}
     }
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a97af64..49577ee 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-02-29  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/69999
+	* gcc.c-torture/compile/pr69999.c: New test.
+
 2016-02-29  Yuri Rumyantsev  <ysrumyan@gmail.com>
 
 	PR tree-optimization/69652
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr69999.c b/gcc/testsuite/gcc.c-torture/compile/pr69999.c
new file mode 100644
index 0000000..5659ce4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr69999.c
@@ -0,0 +1,16 @@
+int uh;
+
+void
+ha(void)
+{
+  while (uh) {
+    for (uh = 0; uh < 1; ++uh) {
+      uh = 0;
+      if (uh != 0)
+ ts:
+        uh %= uh;
+    }
+    ++uh;
+  }
+  goto ts;
+}

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