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] Fix PR71595


The following fixes PR71595, the failure to update loop-closed SSA
when unrolling.  We fail to make remove_path note which blocks we
have to re-scan -- everything is in place, we just don't use it...

This also makes irred recompution more efficient from # removed path
times to a single time per function.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2016-11-24  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/71595
	* cfgloopmanip.h (remove_path): Add irred_invalidated and
	loop_closed_ssa_invalidated parameters, defaulted to NULL.
	* cfgloopmanip.c (remove_path): Likewise, pass them along to
	called functions.  Only fix irred flags if the caller didn't
	request state.
	* tree-ssa-loop-ivcanon.c (unloop_loops): Use add_bb_to_loop.
	(unloop_loops): Pass irred_invalidated and loop_closed_ssa_invalidated
	to remove_path.

	* gcc.dg/torture/pr71595.c: New testcase.

diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index eb86839..84b6b01 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -298,16 +298,20 @@ fix_bb_placements (basic_block from,
    and update loop structures and dominators.  Return true if we were able
    to remove the path, false otherwise (and nothing is affected then).  */
 bool
-remove_path (edge e)
+remove_path (edge e, bool *irred_invalidated,
+	     bitmap loop_closed_ssa_invalidated)
 {
   edge ae;
   basic_block *rem_bbs, *bord_bbs, from, bb;
   vec<basic_block> dom_bbs;
   int i, nrem, n_bord_bbs;
-  bool irred_invalidated = false;
+  bool local_irred_invalidated = false;
   edge_iterator ei;
   struct loop *l, *f;
 
+  if (! irred_invalidated)
+    irred_invalidated = &local_irred_invalidated;
+
   if (!can_remove_branch_p (e))
     return false;
 
@@ -317,7 +321,7 @@ remove_path (edge e)
      that is inside an irreducible region is changed, or if such a loop is
      removed.  */
   if (e->flags & EDGE_IRREDUCIBLE_LOOP)
-    irred_invalidated = true;
+    *irred_invalidated = true;
 
   /* We need to check whether basic blocks are dominated by the edge
      e, but we only have basic block dominators.  This is easy to
@@ -334,7 +338,7 @@ remove_path (edge e)
     {
       f = loop_outer (l);
       if (dominated_by_p (CDI_DOMINATORS, l->latch, e->dest))
-        unloop (l, &irred_invalidated, NULL);
+        unloop (l, irred_invalidated, loop_closed_ssa_invalidated);
     }
 
   /* Identify the path.  */
@@ -348,13 +352,13 @@ remove_path (edge e)
   /* Find "border" hexes -- i.e. those with predecessor in removed path.  */
   for (i = 0; i < nrem; i++)
     bitmap_set_bit (seen, rem_bbs[i]->index);
-  if (!irred_invalidated)
+  if (!*irred_invalidated)
     FOR_EACH_EDGE (ae, ei, e->src->succs)
       if (ae != e && ae->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
 	  && !bitmap_bit_p (seen, ae->dest->index)
 	  && ae->flags & EDGE_IRREDUCIBLE_LOOP)
 	{
-	  irred_invalidated = true;
+	  *irred_invalidated = true;
 	  break;
 	}
 
@@ -369,7 +373,7 @@ remove_path (edge e)
 	    bord_bbs[n_bord_bbs++] = ae->dest;
 
 	    if (ae->flags & EDGE_IRREDUCIBLE_LOOP)
-	      irred_invalidated = true;
+	      *irred_invalidated = true;
 	  }
     }
 
@@ -411,10 +415,10 @@ remove_path (edge e)
 
   /* Fix placements of basic blocks inside loops and the placement of
      loops in the loop tree.  */
-  fix_bb_placements (from, &irred_invalidated, NULL);
-  fix_loop_placements (from->loop_father, &irred_invalidated);
+  fix_bb_placements (from, irred_invalidated, loop_closed_ssa_invalidated);
+  fix_loop_placements (from->loop_father, irred_invalidated);
 
-  if (irred_invalidated
+  if (local_irred_invalidated
       && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
     mark_irreducible_loops ();
 
diff --git a/gcc/cfgloopmanip.h b/gcc/cfgloopmanip.h
index 0e7dc7a..5c4552c 100644
--- a/gcc/cfgloopmanip.h
+++ b/gcc/cfgloopmanip.h
@@ -34,7 +34,7 @@ enum
 					   a complete peeling.  */
 extern edge mfb_kj_edge;
 
-extern bool remove_path (edge);
+extern bool remove_path (edge, bool * = NULL, bitmap = NULL);
 extern void place_new_loop (struct function *, struct loop *);
 extern void add_loop (struct loop *, struct loop *);
 extern void scale_loop_frequencies (struct loop *, int, int);
diff --git a/gcc/testsuite/gcc.dg/torture/pr71595.c b/gcc/testsuite/gcc.dg/torture/pr71595.c
new file mode 100644
index 0000000..4202ad3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr71595.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+int a, d, e, f, g, h;
+static int b[][6] = { {0}, {0}, {1, 1}, {1} };
+
+void
+fn1 ()
+{
+  for (; f; f++)
+    if (g)
+      {
+	for (e = 0; e < 5; e++)
+	  if (b[e + 2][1])
+	    {
+	      h = b[2][e] ? 0 : a;
+	      d |= 4;
+	    }
+	  else
+	    return;
+      }
+}
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index beb65b0..82e2237 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -647,7 +647,7 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,
       latch_edge->flags |= flags;
       latch_edge->goto_locus = locus;
 
-      latch_edge->dest->loop_father = current_loops->tree_root;
+      add_bb_to_loop (latch_edge->dest, current_loops->tree_root);
       latch_edge->dest->count = 0;
       latch_edge->dest->frequency = 0;
       set_immediate_dominator (CDI_DOMINATORS, latch_edge->dest, latch_edge->src);
@@ -663,7 +663,7 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,
   edge e;
   FOR_EACH_VEC_ELT (edges_to_remove, i, e)
     {
-      bool ok = remove_path (e);
+      bool ok = remove_path (e, irred_invalidated, loop_closed_ssa_invalidated);
       gcc_assert (ok);
     }
   edges_to_remove.release ();


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