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] Check NULL loop->latch in verify_loop_structure


Hi,

In verify_loop_structure, we stop checking the latch once we find that it's NULL.

This patch tries a bit harder:
- if !LOOPS_MAY_HAVE_MULTIPLE_LATCHES, we don't allow a NULL latch
- if LOOPS_MAY_HAVE_MULTIPLE_LATCHES, we check that indeed there's no
  single loop latch.

As a consequence of adding this check, I needed to fix expand_omp_for_generic, which missed an initialization of a loop latch.

Bootstrapped and reg-tested on x86_64.

OK for stage3 trunk?

Thanks,
- Tom
Check NULL loop->latch in verify_loop_structure

2015-11-22  Tom de Vries  <tom@codesourcery.com>

	* cfgloop.c (find_single_latch): New function, factored out of ...
	(flow_loops_find): ... here.
	(verify_loop_structure): Verify validity of a NULL loop->latch.
	* cfgloop.h (find_single_latch): Declare.
	* omp-low.c (expand_omp_for_generic): Initialize latch of orig_loop.

---
 gcc/cfgloop.c | 65 +++++++++++++++++++++++++++++++++++++++++------------------
 gcc/cfgloop.h |  1 +
 gcc/omp-low.c |  1 +
 3 files changed, 47 insertions(+), 20 deletions(-)

diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index bf00e0e..b610860 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -388,6 +388,33 @@ bb_loop_header_p (basic_block header)
   return false;
 }
 
+/* Return the latch block for this header block, if it has just a single one.
+   Otherwise, return NULL.  */
+
+basic_block
+find_single_latch (struct loop* loop)
+{
+  basic_block header = loop->header;
+  edge_iterator ei;
+  edge e;
+  basic_block latch = NULL;
+
+  FOR_EACH_EDGE (e, ei, header->preds)
+    {
+      basic_block cand = e->src;
+      if (!flow_bb_inside_loop_p (loop, cand))
+	continue;
+
+      if (latch != NULL)
+	/* More than one latch edge.  */
+	return NULL;
+
+      latch = cand;
+    }
+
+  return latch;
+}
+
 /* Find all the natural loops in the function and save in LOOPS structure and
    recalculate loop_father information in basic block structures.
    If LOOPS is non-NULL then the loop structures for already recorded loops
@@ -482,29 +509,10 @@ flow_loops_find (struct loops *loops)
     {
       struct loop *loop = larray[i];
       basic_block header = loop->header;
-      edge_iterator ei;
-      edge e;
 
       flow_loop_tree_node_add (header->loop_father, loop);
       loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
-
-      /* Look for the latch for this header block, if it has just a
-	 single one.  */
-      FOR_EACH_EDGE (e, ei, header->preds)
-	{
-	  basic_block latch = e->src;
-
-	  if (flow_bb_inside_loop_p (loop, latch))
-	    {
-	      if (loop->latch != NULL)
-		{
-		  /* More than one latch edge.  */
-		  loop->latch = NULL;
-		  break;
-		}
-	      loop->latch = latch;
-	    }
-	}
+      loop->latch = find_single_latch (loop);
     }
 
   return loops;
@@ -1440,6 +1448,23 @@ verify_loop_structure (void)
 	      err = 1;
 	    }
 	}
+      else
+	{
+	  if (loops_state_satisfies_p (LOOPS_MAY_HAVE_MULTIPLE_LATCHES))
+	    {
+	      if (find_single_latch (loop) != NULL)
+		{
+		  error ("loop %d%'s latch is missing", i);
+		  err = 1;
+		}
+	    }
+	  else
+	    {
+	      error ("loop %d%'s latch is missing, and loops may not have"
+		     " multiple latches", i);
+	      err = 1;
+	    }
+	}
       if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES))
 	{
 	  if (!single_succ_p (loop->latch))
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index ee73bf9..7faf591 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -270,6 +270,7 @@ bool mark_irreducible_loops (void);
 void release_recorded_exits (function *);
 void record_loop_exits (void);
 void rescan_loop_exit (edge, bool, bool);
+basic_block find_single_latch (struct loop*);
 
 /* Loop data structure manipulation/querying.  */
 extern void flow_loop_tree_node_add (struct loop *, struct loop *);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index b47864e..00e314d6 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -8900,6 +8900,7 @@ expand_omp_for_generic (struct omp_region *region,
 	  orig_loop->header = l1_bb;
 	  /* The loop may have multiple latches.  */
 	  add_loop (orig_loop, new_loop);
+	  orig_loop->latch = find_single_latch (orig_loop);
 	}
     }
 }

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