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] [RFA] [PR tree-optmization/69740] Schedule loop fixups when needed



PR69740 shows two instances where one or more transformations ultimately lead to the removal of a basic block.

In both cases, removal of the basic block removes a path into an irreducible region and turns the irreducible region into a natural loop.

When that occurs we need to be requesting loops to be fixed up.

My first patch was to handle this is was in tree-ssa-dce.c and that fixed the initial problem report. As I was cobbling the patch together, I pondered putting the changes into delete_basic_block because that would capture other instances of this problem.

When I looked at the second instance, it came via a completely different path (tail merging). Again it was a case where we called delete_basic_block which in turn changed an irreducible region into a natural loop. So I tossed my original patch and put the test into delete_basic_block as you see here.

Bootstrapped and regression tested on x86_64-linux-gnu. OK for the trunk and the gcc-5 branch after a suitable soak time?



Jeff
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 913abc8..42e5b4f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-02-24  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/69740
+	* cfghooks.c (delete_basic_block): Request loop fixups if we delete
+	a block with an outgoing edge to a block marked as being in anx
+	irreducible region.
+
 2016-02-24  Jason Merrill  <jason@redhat.com>
 
 	* common.opt (flifetime-dse): Add -flifetime-dse=1.
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index bbb1017..4d31aa9 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -574,6 +574,14 @@ delete_basic_block (basic_block bb)
   if (!cfg_hooks->delete_basic_block)
     internal_error ("%s does not support delete_basic_block", cfg_hooks->name);
 
+  /* Look at BB's successors, if any are marked as BB_IRREDUCIBLE_LOOP, then
+     removing BB (and its outgoing edges) may make the loop a natural
+     loop.  In which case we need to schedule loop fixups.  */
+  if (current_loops)
+    for (edge_iterator ei = ei_start (bb->succs); !ei_end_p (ei); ei_next (&ei))
+      if (ei_edge (ei)->dest->flags & BB_IRREDUCIBLE_LOOP)
+	loops_state_set (LOOPS_NEED_FIXUP);
+
   cfg_hooks->delete_basic_block (bb);
 
   if (current_loops != NULL)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 311232f..b0df819 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2016-02-04  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/69740
+	* gcc.c-torture/compile/pr69740-1.c: New test.
+	* gcc.c-torture/compile/pr69740-2.c: New test.
+
 2016-02-24  Martin Sebor  <msebor@redhat.com>
 
 	PR c++/69912
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr69740-1.c b/gcc/testsuite/gcc.c-torture/compile/pr69740-1.c
new file mode 100644
index 0000000..ac867d8
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr69740-1.c
@@ -0,0 +1,12 @@
+char a;
+short b;
+void fn1() {
+  if (b)
+    ;
+  else {
+    int c[1] = {0};
+  l1:;
+  }
+  if (a)
+    goto l1;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr69740-2.c b/gcc/testsuite/gcc.c-torture/compile/pr69740-2.c
new file mode 100644
index 0000000..a89c9a0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr69740-2.c
@@ -0,0 +1,19 @@
+inline int foo(int *p1, int p2) {
+  int z = *p1;
+  while (z > p2)
+    p2 = 2;
+  return z;
+}
+int main() {
+  int i;
+  for (;;) {
+    int j, k;
+    i = foo(&k, 7);
+    if (k)
+      j = i;
+    else
+      k = j;
+    if (2 != j)
+      __builtin_abort();
+  }
+}

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