[PATCH 2/2] [og9] Remove duplicate SESE code in NVPTX backend

Julian Brown julian@codesourcery.com
Fri Sep 6 12:15:00 GMT 2019


This patch fixes a build failure for NVPTX on the
openacc-gcc-9-branch. The algorithm to calculate single-entry,
single-exit (SESE) regions has been moved to generic code so it can
(so far, potentially) be shared with other targets. Some name clashes
have been fixed and other minor cleanups have been done, also.

Tested with offloading to NVPTX. I will apply shortly.

Julian

ChangeLog

	gcc/
	* config/nvptx/nvptx.c (omp-sese.h): Include.
	(bb_pair_t, bb_pair_vec_t, pseudo_node_t, bracket, bracket_vec_t,
	bb_sese, bb_sese::~bb_sese, bb_sese::append, bb_sese::remove,
	BB_SET_SESE, BB_GET_SESE, nvptx_sese_number, nvptx_sese_pseudo,
	nvptx_sese_color, nvptx_find_sese): Remove.
	(nvptx_neuter_pars): Call omp_find_sese instead of nvptx_find_sese.
	* omp-sese.c (omp-sese.h): Include.
	(struct parallel): Rename to...
	(struct parallel_g): This.
	(parallel::parallel, parallel::~parallel): Rename to...
	(parallel_g::parallel_g, parallel_g::~parallel_g): These.
	(omp_sese_dump_pars, omp_sese_find_par, omp_sese_discover_pars,
	populate_single_mode_bitmaps, find_ssa_names_to_propagate,
	find_partitioned_var_uses, find_local_vars_to_propagate,
	neuter_worker_single): Update for parallel_g name change.
	(bb_pair_t, bb_pair_vec_t): Remove.
	(omp_find_sese): Make global.
	* omp-sese.h (bb_pair_t, bb_pair_vec_t): New.
	(omp_find_sese): Add prototype.
---
 gcc/ChangeLog.openacc    |  22 ++
 gcc/config/nvptx/nvptx.c | 622 +--------------------------------------
 gcc/omp-sese.c           |  61 ++--
 gcc/omp-sese.h           |   6 +
 4 files changed, 59 insertions(+), 652 deletions(-)

diff --git a/gcc/ChangeLog.openacc b/gcc/ChangeLog.openacc
index 9e7893aa11e..ffe19bc5809 100644
--- a/gcc/ChangeLog.openacc
+++ b/gcc/ChangeLog.openacc
@@ -1,3 +1,25 @@
+2019-09-06  Julian Brown  <julian@codesourcery.com>
+
+	* config/nvptx/nvptx.c (omp-sese.h): Include.
+	(bb_pair_t, bb_pair_vec_t, pseudo_node_t, bracket, bracket_vec_t,
+	bb_sese, bb_sese::~bb_sese, bb_sese::append, bb_sese::remove,
+	BB_SET_SESE, BB_GET_SESE, nvptx_sese_number, nvptx_sese_pseudo,
+	nvptx_sese_color, nvptx_find_sese): Remove.
+	(nvptx_neuter_pars): Call omp_find_sese instead of nvptx_find_sese.
+	* omp-sese.c (omp-sese.h): Include.
+	(struct parallel): Rename to...
+	(struct parallel_g): This.
+	(parallel::parallel, parallel::~parallel): Rename to...
+	(parallel_g::parallel_g, parallel_g::~parallel_g): These.
+	(omp_sese_dump_pars, omp_sese_find_par, omp_sese_discover_pars,
+	populate_single_mode_bitmaps, find_ssa_names_to_propagate,
+	find_partitioned_var_uses, find_local_vars_to_propagate,
+	neuter_worker_single): Update for parallel_g name change.
+	(bb_pair_t, bb_pair_vec_t): Remove.
+	(omp_find_sese): Make global.
+	* omp-sese.h (bb_pair_t, bb_pair_vec_t): New.
+	(omp_find_sese): Add prototype.
+
 2019-09-06  Julian Brown  <julian@codesourcery.com>
 
 	* gimplify.c (gimplify_omp_workshare): Use OMP_CLAUSES, OMP_BODY
diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c
index 077f6cc145e..d6b2881d110 100644
--- a/gcc/config/nvptx/nvptx.c
+++ b/gcc/config/nvptx/nvptx.c
@@ -75,6 +75,7 @@
 #include "fold-const.h"
 #include "intl.h"
 #include "tree-hash-traits.h"
+#include "omp-sese.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -3380,625 +3381,6 @@ nvptx_discover_pars (bb_insn_map_t *map)
   return par;
 }
 
-/* Analyse a group of BBs within a partitioned region and create N
-   Single-Entry-Single-Exit regions.  Some of those regions will be
-   trivial ones consisting of a single BB.  The blocks of a
-   partitioned region might form a set of disjoint graphs -- because
-   the region encloses a differently partitoned sub region.
-
-   We use the linear time algorithm described in 'Finding Regions Fast:
-   Single Entry Single Exit and control Regions in Linear Time'
-   Johnson, Pearson & Pingali.  That algorithm deals with complete
-   CFGs, where a back edge is inserted from END to START, and thus the
-   problem becomes one of finding equivalent loops.
-
-   In this case we have a partial CFG.  We complete it by redirecting
-   any incoming edge to the graph to be from an arbitrary external BB,
-   and similarly redirecting any outgoing edge to be to  that BB.
-   Thus we end up with a closed graph.
-
-   The algorithm works by building a spanning tree of an undirected
-   graph and keeping track of back edges from nodes further from the
-   root in the tree to nodes nearer to the root in the tree.  In the
-   description below, the root is up and the tree grows downwards.
-
-   We avoid having to deal with degenerate back-edges to the same
-   block, by splitting each BB into 3 -- one for input edges, one for
-   the node itself and one for the output edges.  Such back edges are
-   referred to as 'Brackets'.  Cycle equivalent nodes will have the
-   same set of brackets.
-   
-   Determining bracket equivalency is done by maintaining a list of
-   brackets in such a manner that the list length and final bracket
-   uniquely identify the set.
-
-   We use coloring to mark all BBs with cycle equivalency with the
-   same color.  This is the output of the 'Finding Regions Fast'
-   algorithm.  Notice it doesn't actually find the set of nodes within
-   a particular region, just unorderd sets of nodes that are the
-   entries and exits of SESE regions.
-   
-   After determining cycle equivalency, we need to find the minimal
-   set of SESE regions.  Do this with a DFS coloring walk of the
-   complete graph.  We're either 'looking' or 'coloring'.  When
-   looking, and we're in the subgraph, we start coloring the color of
-   the current node, and remember that node as the start of the
-   current color's SESE region.  Every time we go to a new node, we
-   decrement the count of nodes with thet color.  If it reaches zero,
-   we remember that node as the end of the current color's SESE region
-   and return to 'looking'.  Otherwise we color the node the current
-   color.
-
-   This way we end up with coloring the inside of non-trivial SESE
-   regions with the color of that region.  */
-
-/* A pair of BBs.  We use this to represent SESE regions.  */
-typedef std::pair<basic_block, basic_block> bb_pair_t;
-typedef auto_vec<bb_pair_t> bb_pair_vec_t;
-
-/* A node in the undirected CFG.  The discriminator SECOND indicates just
-   above or just below the BB idicated by FIRST.  */
-typedef std::pair<basic_block, int> pseudo_node_t;
-
-/* A bracket indicates an edge towards the root of the spanning tree of the
-   undirected graph.  Each bracket has a color, determined
-   from the currrent set of brackets.  */
-struct bracket
-{
-  pseudo_node_t back; /* Back target */
-
-  /* Current color and size of set.  */
-  unsigned color;
-  unsigned size;
-
-  bracket (pseudo_node_t back_)
-  : back (back_), color (~0u), size (~0u)
-  {
-  }
-
-  unsigned get_color (auto_vec<unsigned> &color_counts, unsigned length)
-  {
-    if (length != size)
-      {
-	size = length;
-	color = color_counts.length ();
-	color_counts.quick_push (0);
-      }
-    color_counts[color]++;
-    return color;
-  }
-};
-
-typedef auto_vec<bracket> bracket_vec_t;
-
-/* Basic block info for finding SESE regions.    */
-
-struct bb_sese
-{
-  int node;  /* Node number in spanning tree.  */
-  int parent; /* Parent node number.  */
-
-  /* The algorithm splits each node A into Ai, A', Ao. The incoming
-     edges arrive at pseudo-node Ai and the outgoing edges leave at
-     pseudo-node Ao.  We have to remember which way we arrived at a
-     particular node when generating the spanning tree.  dir > 0 means
-     we arrived at Ai, dir < 0 means we arrived at Ao.  */
-  int dir;
-
-  /* Lowest numbered pseudo-node reached via a backedge from thsis
-     node, or any descendant.  */
-  pseudo_node_t high;
-
-  int color;  /* Cycle-equivalence color  */
-
-  /* Stack of brackets for this node.  */
-  bracket_vec_t brackets;
-
-  bb_sese (unsigned node_, unsigned p, int dir_)
-  :node (node_), parent (p), dir (dir_)
-  {
-  }
-  ~bb_sese ();
-
-  /* Push a bracket ending at BACK.  */
-  void push (const pseudo_node_t &back)
-  {
-    if (dump_file)
-      fprintf (dump_file, "Pushing backedge %d:%+d\n",
-	       back.first ? back.first->index : 0, back.second);
-    brackets.safe_push (bracket (back));
-  }
-  
-  void append (bb_sese *child);
-  void remove (const pseudo_node_t &);
-
-  /* Set node's color.  */
-  void set_color (auto_vec<unsigned> &color_counts)
-  {
-    color = brackets.last ().get_color (color_counts, brackets.length ());
-  }
-};
-
-bb_sese::~bb_sese ()
-{
-}
-
-/* Destructively append CHILD's brackets.  */
-
-void
-bb_sese::append (bb_sese *child)
-{
-  if (int len = child->brackets.length ())
-    {
-      int ix;
-
-      if (dump_file)
-	{
-	  for (ix = 0; ix < len; ix++)
-	    {
-	      const pseudo_node_t &pseudo = child->brackets[ix].back;
-	      fprintf (dump_file, "Appending (%d)'s backedge %d:%+d\n",
-		       child->node, pseudo.first ? pseudo.first->index : 0,
-		       pseudo.second);
-	    }
-	}
-      if (!brackets.length ())
-	std::swap (brackets, child->brackets);
-      else
-	{
-	  brackets.reserve (len);
-	  for (ix = 0; ix < len; ix++)
-	    brackets.quick_push (child->brackets[ix]);
-	}
-    }
-}
-
-/* Remove brackets that terminate at PSEUDO.  */
-
-void
-bb_sese::remove (const pseudo_node_t &pseudo)
-{
-  unsigned removed = 0;
-  int len = brackets.length ();
-
-  for (int ix = 0; ix < len; ix++)
-    {
-      if (brackets[ix].back == pseudo)
-	{
-	  if (dump_file)
-	    fprintf (dump_file, "Removing backedge %d:%+d\n",
-		     pseudo.first ? pseudo.first->index : 0, pseudo.second);
-	  removed++;
-	}
-      else if (removed)
-	brackets[ix-removed] = brackets[ix];
-    }
-  while (removed--)
-    brackets.pop ();
-}
-
-/* Accessors for BB's aux pointer.  */
-#define BB_SET_SESE(B, S) ((B)->aux = (S))
-#define BB_GET_SESE(B) ((bb_sese *)(B)->aux)
-
-/* DFS walk creating SESE data structures.  Only cover nodes with
-   BB_VISITED set.  Append discovered blocks to LIST.  We number in
-   increments of 3 so that the above and below pseudo nodes can be
-   implicitly numbered too.  */
-
-static int
-nvptx_sese_number (int n, int p, int dir, basic_block b,
-		   auto_vec<basic_block> *list)
-{
-  if (BB_GET_SESE (b))
-    return n;
-
-  if (dump_file)
-    fprintf (dump_file, "Block %d(%d), parent (%d), orientation %+d\n",
-	     b->index, n, p, dir);
-  
-  BB_SET_SESE (b, new bb_sese (n, p, dir));
-  p = n;
-      
-  n += 3;
-  list->quick_push (b);
-
-  /* First walk the nodes on the 'other side' of this node, then walk
-     the nodes on the same side.  */
-  for (unsigned ix = 2; ix; ix--)
-    {
-      vec<edge, va_gc> *edges = dir > 0 ? b->succs : b->preds;
-      size_t offset = (dir > 0 ? offsetof (edge_def, dest)
-		       : offsetof (edge_def, src));
-      edge e;
-      edge_iterator (ei);
-
-      FOR_EACH_EDGE (e, ei, edges)
-	{
-	  basic_block target = *(basic_block *)((char *)e + offset);
-	  
-	  if (target->flags & BB_VISITED)
-	    n = nvptx_sese_number (n, p, dir, target, list);
-	}
-      dir = -dir;
-    }
-  return n;
-}
-
-/* Process pseudo node above (DIR < 0) or below (DIR > 0) ME.
-   EDGES are the outgoing edges and OFFSET is the offset to the src
-   or dst block on the edges.   */
-
-static void
-nvptx_sese_pseudo (basic_block me, bb_sese *sese, int depth, int dir,
-		   vec<edge, va_gc> *edges, size_t offset)
-{
-  edge e;
-  edge_iterator (ei);
-  int hi_back = depth;
-  pseudo_node_t node_back (0, depth);
-  int hi_child = depth;
-  pseudo_node_t node_child (0, depth);
-  basic_block child = NULL;
-  unsigned num_children = 0;
-  int usd = -dir * sese->dir;
-
-  if (dump_file)
-    fprintf (dump_file, "\nProcessing %d(%d) %+d\n",
-	     me->index, sese->node, dir);
-
-  if (dir < 0)
-    {
-      /* This is the above pseudo-child.  It has the BB itself as an
-	 additional child node.  */
-      node_child = sese->high;
-      hi_child = node_child.second;
-      if (node_child.first)
-	hi_child += BB_GET_SESE (node_child.first)->node;
-      num_children++;
-    }
-
-  /* Examine each edge.
-     - if it is a child (a) append its bracket list and (b) record
-          whether it is the child with the highest reaching bracket.
-     - if it is an edge to ancestor, record whether it's the highest
-          reaching backlink.  */
-  FOR_EACH_EDGE (e, ei, edges)
-    {
-      basic_block target = *(basic_block *)((char *)e + offset);
-
-      if (bb_sese *t_sese = BB_GET_SESE (target))
-	{
-	  if (t_sese->parent == sese->node && !(t_sese->dir + usd))
-	    {
-	      /* Child node.  Append its bracket list. */
-	      num_children++;
-	      sese->append (t_sese);
-
-	      /* Compare it's hi value.  */
-	      int t_hi = t_sese->high.second;
-
-	      if (basic_block child_hi_block = t_sese->high.first)
-		t_hi += BB_GET_SESE (child_hi_block)->node;
-
-	      if (hi_child > t_hi)
-		{
-		  hi_child = t_hi;
-		  node_child = t_sese->high;
-		  child = target;
-		}
-	    }
-	  else if (t_sese->node < sese->node + dir
-		   && !(dir < 0 && sese->parent == t_sese->node))
-	    {
-	      /* Non-parental ancestor node -- a backlink.  */
-	      int d = usd * t_sese->dir;
-	      int back = t_sese->node + d;
-	
-	      if (hi_back > back)
-		{
-		  hi_back = back;
-		  node_back = pseudo_node_t (target, d);
-		}
-	    }
-	}
-      else
-	{ /* Fallen off graph, backlink to entry node.  */
-	  hi_back = 0;
-	  node_back = pseudo_node_t (0, 0);
-	}
-    }
-
-  /* Remove any brackets that terminate at this pseudo node.  */
-  sese->remove (pseudo_node_t (me, dir));
-
-  /* Now push any backlinks from this pseudo node.  */
-  FOR_EACH_EDGE (e, ei, edges)
-    {
-      basic_block target = *(basic_block *)((char *)e + offset);
-      if (bb_sese *t_sese = BB_GET_SESE (target))
-	{
-	  if (t_sese->node < sese->node + dir
-	      && !(dir < 0 && sese->parent == t_sese->node))
-	    /* Non-parental ancestor node - backedge from me.  */
-	    sese->push (pseudo_node_t (target, usd * t_sese->dir));
-	}
-      else
-	{
-	  /* back edge to entry node */
-	  sese->push (pseudo_node_t (0, 0));
-	}
-    }
-  
- /* If this node leads directly or indirectly to a no-return region of
-     the graph, then fake a backedge to entry node.  */
-  if (!sese->brackets.length () || !edges || !edges->length ())
-    {
-      hi_back = 0;
-      node_back = pseudo_node_t (0, 0);
-      sese->push (node_back);
-    }
-
-  /* Record the highest reaching backedge from us or a descendant.  */
-  sese->high = hi_back < hi_child ? node_back : node_child;
-
-  if (num_children > 1)
-    {
-      /* There is more than one child -- this is a Y shaped piece of
-	 spanning tree.  We have to insert a fake backedge from this
-	 node to the highest ancestor reached by not-the-highest
-	 reaching child.  Note that there may be multiple children
-	 with backedges to the same highest node.  That's ok and we
-	 insert the edge to that highest node.  */
-      hi_child = depth;
-      if (dir < 0 && child)
-	{
-	  node_child = sese->high;
-	  hi_child = node_child.second;
-	  if (node_child.first)
-	    hi_child += BB_GET_SESE (node_child.first)->node;
-	}
-
-      FOR_EACH_EDGE (e, ei, edges)
-	{
-	  basic_block target = *(basic_block *)((char *)e + offset);
-
-	  if (target == child)
-	    /* Ignore the highest child. */
-	    continue;
-
-	  bb_sese *t_sese = BB_GET_SESE (target);
-	  if (!t_sese)
-	    continue;
-	  if (t_sese->parent != sese->node)
-	    /* Not a child. */
-	    continue;
-
-	  /* Compare its hi value.  */
-	  int t_hi = t_sese->high.second;
-
-	  if (basic_block child_hi_block = t_sese->high.first)
-	    t_hi += BB_GET_SESE (child_hi_block)->node;
-
-	  if (hi_child > t_hi)
-	    {
-	      hi_child = t_hi;
-	      node_child = t_sese->high;
-	    }
-	}
-      
-      sese->push (node_child);
-    }
-}
-
-
-/* DFS walk of BB graph.  Color node BLOCK according to COLORING then
-   proceed to successors.  Set SESE entry and exit nodes of
-   REGIONS.  */
-
-static void
-nvptx_sese_color (auto_vec<unsigned> &color_counts, bb_pair_vec_t &regions,
-		  basic_block block, int coloring)
-{
-  bb_sese *sese = BB_GET_SESE (block);
-
-  if (block->flags & BB_VISITED)
-    {
-      /* If we've already encountered this block, either we must not
-	 be coloring, or it must have been colored the current color.  */
-      gcc_assert (coloring < 0 || (sese && coloring == sese->color));
-      return;
-    }
-  
-  block->flags |= BB_VISITED;
-
-  if (sese)
-    {
-      if (coloring < 0)
-	{
-	  /* Start coloring a region.  */
-	  regions[sese->color].first = block;
-	  coloring = sese->color;
-	}
-
-      if (!--color_counts[sese->color] && sese->color == coloring)
-	{
-	  /* Found final block of SESE region.  */
-	  regions[sese->color].second = block;
-	  coloring = -1;
-	}
-      else
-	/* Color the node, so we can assert on revisiting the node
-	   that the graph is indeed SESE.  */
-	sese->color = coloring;
-    }
-  else
-    /* Fallen off the subgraph, we cannot be coloring.  */
-    gcc_assert (coloring < 0);
-
-  /* Walk each successor block.  */
-  if (block->succs && block->succs->length ())
-    {
-      edge e;
-      edge_iterator ei;
-      
-      FOR_EACH_EDGE (e, ei, block->succs)
-	nvptx_sese_color (color_counts, regions, e->dest, coloring);
-    }
-  else
-    gcc_assert (coloring < 0);
-}
-
-/* Find minimal set of SESE regions covering BLOCKS.  REGIONS might
-   end up with NULL entries in it.  */
-
-static void
-nvptx_find_sese (auto_vec<basic_block> &blocks, bb_pair_vec_t &regions)
-{
-  basic_block block;
-  int ix;
-
-  /* First clear each BB of the whole function.  */ 
-  FOR_ALL_BB_FN (block, cfun)
-    {
-      block->flags &= ~BB_VISITED;
-      BB_SET_SESE (block, 0);
-    }
-
-  /* Mark blocks in the function that are in this graph.  */
-  for (ix = 0; blocks.iterate (ix, &block); ix++)
-    block->flags |= BB_VISITED;
-
-  /* Counts of nodes assigned to each color.  There cannot be more
-     colors than blocks (and hopefully there will be fewer).  */
-  auto_vec<unsigned> color_counts;
-  color_counts.reserve (blocks.length ());
-
-  /* Worklist of nodes in the spanning tree.  Again, there cannot be
-     more nodes in the tree than blocks (there will be fewer if the
-     CFG of blocks is disjoint).  */
-  auto_vec<basic_block> spanlist;
-  spanlist.reserve (blocks.length ());
-
-  /* Make sure every block has its cycle class determined.  */
-  for (ix = 0; blocks.iterate (ix, &block); ix++)
-    {
-      if (BB_GET_SESE (block))
-	/* We already met this block in an earlier graph solve.  */
-	continue;
-
-      if (dump_file)
-	fprintf (dump_file, "Searching graph starting at %d\n", block->index);
-      
-      /* Number the nodes reachable from block initial DFS order.  */
-      int depth = nvptx_sese_number (2, 0, +1, block, &spanlist);
-
-      /* Now walk in reverse DFS order to find cycle equivalents.  */
-      while (spanlist.length ())
-	{
-	  block = spanlist.pop ();
-	  bb_sese *sese = BB_GET_SESE (block);
-
-	  /* Do the pseudo node below.  */
-	  nvptx_sese_pseudo (block, sese, depth, +1,
-			     sese->dir > 0 ? block->succs : block->preds,
-			     (sese->dir > 0 ? offsetof (edge_def, dest)
-			      : offsetof (edge_def, src)));
-	  sese->set_color (color_counts);
-	  /* Do the pseudo node above.  */
-	  nvptx_sese_pseudo (block, sese, depth, -1,
-			     sese->dir < 0 ? block->succs : block->preds,
-			     (sese->dir < 0 ? offsetof (edge_def, dest)
-			      : offsetof (edge_def, src)));
-	}
-      if (dump_file)
-	fprintf (dump_file, "\n");
-    }
-
-  if (dump_file)
-    {
-      unsigned count;
-      const char *comma = "";
-      
-      fprintf (dump_file, "Found %d cycle equivalents\n",
-	       color_counts.length ());
-      for (ix = 0; color_counts.iterate (ix, &count); ix++)
-	{
-	  fprintf (dump_file, "%s%d[%d]={", comma, ix, count);
-
-	  comma = "";
-	  for (unsigned jx = 0; blocks.iterate (jx, &block); jx++)
-	    if (BB_GET_SESE (block)->color == ix)
-	      {
-		block->flags |= BB_VISITED;
-		fprintf (dump_file, "%s%d", comma, block->index);
-		comma=",";
-	      }
-	  fprintf (dump_file, "}");
-	  comma = ", ";
-	}
-      fprintf (dump_file, "\n");
-   }
-  
-  /* Now we've colored every block in the subgraph.  We now need to
-     determine the minimal set of SESE regions that cover that
-     subgraph.  Do this with a DFS walk of the complete function.
-     During the walk we're either 'looking' or 'coloring'.  When we
-     reach the last node of a particular color, we stop coloring and
-     return to looking.  */
-
-  /* There cannot be more SESE regions than colors.  */
-  regions.reserve (color_counts.length ());
-  for (ix = color_counts.length (); ix--;)
-    regions.quick_push (bb_pair_t (0, 0));
-
-  for (ix = 0; blocks.iterate (ix, &block); ix++)
-    block->flags &= ~BB_VISITED;
-
-  nvptx_sese_color (color_counts, regions, ENTRY_BLOCK_PTR_FOR_FN (cfun), -1);
-
-  if (dump_file)
-    {
-      const char *comma = "";
-      int len = regions.length ();
-      
-      fprintf (dump_file, "SESE regions:");
-      for (ix = 0; ix != len; ix++)
-	{
-	  basic_block from = regions[ix].first;
-	  basic_block to = regions[ix].second;
-
-	  if (from)
-	    {
-	      fprintf (dump_file, "%s %d{%d", comma, ix, from->index);
-	      if (to != from)
-		fprintf (dump_file, "->%d", to->index);
-
-	      int color = BB_GET_SESE (from)->color;
-
-	      /* Print the blocks within the region (excluding ends).  */
-	      FOR_EACH_BB_FN (block, cfun)
-		{
-		  bb_sese *sese = BB_GET_SESE (block);
-
-		  if (sese && sese->color == color
-		      && block != from && block != to)
-		    fprintf (dump_file, ".%d", block->index);
-		}
-	      fprintf (dump_file, "}");
-	    }
-	  comma = ",";
-	}
-      fprintf (dump_file, "\n\n");
-    }
-  
-  for (ix = 0; blocks.iterate (ix, &block); ix++)
-    delete BB_GET_SESE (block);
-}
-
-#undef BB_SET_SESE
-#undef BB_GET_SESE
-
 /* Propagate live state at the start of a partitioned region.  IS_CALL
    indicates whether the propagation is for a (partitioned) call
    instruction.  BLOCK provides the live register information, and
@@ -4821,7 +4203,7 @@ nvptx_neuter_pars (parallel *par, unsigned modes, unsigned outer)
 	  /* Neuter whole SESE regions.  */
 	  bb_pair_vec_t regions;
 
-	  nvptx_find_sese (par->blocks, regions);
+	  omp_find_sese (par->blocks, regions);
 	  len = regions.length ();
 	  for (ix = 0; ix != len; ix++)
 	    {
diff --git a/gcc/omp-sese.c b/gcc/omp-sese.c
index cb2389eb55c..d6f1e8edd62 100644
--- a/gcc/omp-sese.c
+++ b/gcc/omp-sese.c
@@ -53,20 +53,21 @@
 #include "tree-cfg.h"
 #include "omp-offload.h"
 #include "attribs.h"
+#include "omp-sese.h"
 
 /* Loop structure of the function.  The entire function is described as
    a NULL loop.  */
 
-struct parallel
+struct parallel_g
 {
   /* Parent parallel.  */
-  parallel *parent;
+  parallel_g *parent;
 
   /* Next sibling parallel.  */
-  parallel *next;
+  parallel_g *next;
 
   /* First child parallel.  */
-  parallel *inner;
+  parallel_g *inner;
 
   /* Partitioning mask of the parallel.  */
   unsigned mask;
@@ -96,14 +97,14 @@ struct parallel
   tree receiver_decl;
 
 public:
-  parallel (parallel *parent, unsigned mode);
-  ~parallel ();
+  parallel_g (parallel_g *parent, unsigned mode);
+  ~parallel_g ();
 };
 
 /* Constructor links the new parallel into it's parent's chain of
    children.  */
 
-parallel::parallel (parallel *parent_, unsigned mask_)
+parallel_g::parallel_g (parallel_g *parent_, unsigned mask_)
   :parent (parent_), next (0), inner (0), mask (mask_), inner_mask (0)
 {
   forked_block = join_block = 0;
@@ -121,7 +122,7 @@ parallel::parallel (parallel *parent_, unsigned mask_)
     }
 }
 
-parallel::~parallel ()
+parallel_g::~parallel_g ()
 {
   delete inner;
   delete next;
@@ -206,7 +207,6 @@ omp_sese_split_blocks (bb_stmt_map_t *map)
 	    {
 	      enum ifn_unique_kind k = ((enum ifn_unique_kind)
 		TREE_INT_CST_LOW (gimple_call_arg (stmt, 0)));
-	      gcall *call = as_a <gcall *> (stmt);
 
 	      if (k == IFN_UNIQUE_OACC_JOIN)
 	        worklist.safe_push (stmt);
@@ -344,7 +344,7 @@ mask_name (unsigned mask)
 /* Dump this parallel and all its inner parallels.  */
 
 static void
-omp_sese_dump_pars (parallel *par, unsigned depth)
+omp_sese_dump_pars (parallel_g *par, unsigned depth)
 {
   fprintf (dump_file, "%u: mask %d (%s) head=%d, tail=%d\n",
 	   depth, par->mask, mask_name (par->mask),
@@ -368,8 +368,8 @@ omp_sese_dump_pars (parallel *par, unsigned depth)
    terminate a loop structure.  Add this block to the current loop,
    and then walk successor blocks.   */
 
-static parallel *
-omp_sese_find_par (bb_stmt_map_t *map, parallel *par, basic_block block)
+static parallel_g *
+omp_sese_find_par (bb_stmt_map_t *map, parallel_g *par, basic_block block)
 {
   if (block->flags & BB_VISITED)
     return par;
@@ -388,7 +388,7 @@ omp_sese_find_par (bb_stmt_map_t *map, parallel *par, basic_block block)
 	{
 	  /* A single block that is forced to be at the maximum partition
 	     level.  Make a singleton par for it.  */
-	  par = new parallel (par, GOMP_DIM_MASK (GOMP_DIM_GANG)
+	  par = new parallel_g (par, GOMP_DIM_MASK (GOMP_DIM_GANG)
 				   | GOMP_DIM_MASK (GOMP_DIM_WORKER)
 				   | GOMP_DIM_MASK (GOMP_DIM_VECTOR));
 	  par->forked_block = block;
@@ -416,7 +416,7 @@ omp_sese_find_par (bb_stmt_map_t *map, parallel *par, basic_block block)
 		    = TREE_INT_CST_LOW (gimple_call_arg (call, 2));
 		  unsigned mask = (dim >= 0) ? GOMP_DIM_MASK (dim) : 0;
 
-		  par = new parallel (par, mask);
+		  par = new parallel_g (par, mask);
 		  par->forked_block = block;
 		  par->forked_stmt = final_stmt;
 		  par->fork_stmt = stmt;
@@ -454,7 +454,7 @@ omp_sese_find_par (bb_stmt_map_t *map, parallel *par, basic_block block)
     par->blocks.safe_push (block);
   else
     /* This must be the entry block.  Create a NULL parallel.  */
-    par = new parallel (0, 0);
+    par = new parallel_g (0, 0);
 
 walk_successors:
   /* Walk successor blocks.  */
@@ -473,7 +473,7 @@ walk_successors:
    speeds up the discovery.  We rely on the BB visited flag having
    been cleared when splitting blocks.  */
 
-static parallel *
+static parallel_g *
 omp_sese_discover_pars (bb_stmt_map_t *map)
 {
   basic_block block;
@@ -486,7 +486,7 @@ omp_sese_discover_pars (bb_stmt_map_t *map)
   block = ENTRY_BLOCK_PTR_FOR_FN (cfun);
   block->flags &= ~BB_VISITED;
 
-  parallel *par = omp_sese_find_par (map, 0, block);
+  parallel_g *par = omp_sese_find_par (map, 0, block);
 
   if (dump_file)
     {
@@ -499,7 +499,7 @@ omp_sese_discover_pars (bb_stmt_map_t *map)
 }
 
 static void
-populate_single_mode_bitmaps (parallel *par, bitmap worker_single,
+populate_single_mode_bitmaps (parallel_g *par, bitmap worker_single,
 			      bitmap vector_single, unsigned outer_mask,
 			      int depth)
 {
@@ -584,7 +584,7 @@ install_var_field (tree var, tree record_type)
 typedef hash_set<tree> propagation_set;
 
 static void
-find_ssa_names_to_propagate (parallel *par, unsigned outer_mask,
+find_ssa_names_to_propagate (parallel_g *par, unsigned outer_mask,
 			     bitmap worker_single, bitmap vector_single,
 			     vec<propagation_set *> *prop_set)
 {
@@ -686,7 +686,7 @@ find_partitioned_var_uses_1 (tree *node, int *, void *data)
 }
 
 static void
-find_partitioned_var_uses (parallel *par, unsigned outer_mask,
+find_partitioned_var_uses (parallel_g *par, unsigned outer_mask,
 			   hash_set<tree> *partitioned_var_uses)
 {
   unsigned mask = outer_mask | par->mask;
@@ -714,7 +714,7 @@ find_partitioned_var_uses (parallel *par, unsigned outer_mask,
 }
 
 static void
-find_local_vars_to_propagate (parallel *par, unsigned outer_mask,
+find_local_vars_to_propagate (parallel_g *par, unsigned outer_mask,
 			      hash_set<tree> *partitioned_var_uses,
 			      vec<propagation_set *> *prop_set)
 {
@@ -853,8 +853,8 @@ worker_single_simple (basic_block from, basic_block to,
 	  if (def_escapes_block->contains (var))
 	    {
 	      gphi *join_phi = create_phi_node (NULL_TREE, skip_block);
-	      tree res = create_new_def_for (var, join_phi,
-					     gimple_phi_result_ptr (join_phi));
+	      create_new_def_for (var, join_phi,
+				  gimple_phi_result_ptr (join_phi));
 	      add_phi_arg (join_phi, var, e, UNKNOWN_LOCATION);
 
 	      tree neutered_def = copy_ssa_name (var, NULL);
@@ -1167,8 +1167,9 @@ worker_single_copy (basic_block from, basic_block to,
 }
 
 static void
-neuter_worker_single (parallel *par, unsigned outer_mask, bitmap worker_single,
-		      bitmap vector_single, vec<propagation_set *> *prop_set,
+neuter_worker_single (parallel_g *par, unsigned outer_mask,
+		      bitmap worker_single, bitmap vector_single,
+		      vec<propagation_set *> *prop_set,
 		      hash_set<tree> *partitioned_var_uses)
 {
   unsigned mask = outer_mask | par->mask;
@@ -1333,7 +1334,7 @@ oacc_do_neutering (void)
 	}
     }
 
-  parallel *par = omp_sese_discover_pars (&bb_stmt_map);
+  parallel_g *par = omp_sese_discover_pars (&bb_stmt_map);
   populate_single_mode_bitmaps (par, worker_single, vector_single, mask, 0);
 
   basic_block bb;
@@ -1462,10 +1463,6 @@ oacc_do_neutering (void)
    This way we end up with coloring the inside of non-trivial SESE
    regions with the color of that region.  */
 
-/* A pair of BBs.  We use this to represent SESE regions.  */
-typedef std::pair<basic_block, basic_block> bb_pair_t;
-typedef auto_vec<bb_pair_t> bb_pair_vec_t;
-
 /* A node in the undirected CFG.  The discriminator SECOND indicates just
    above or just below the BB idicated by FIRST.  */
 typedef std::pair<basic_block, int> pseudo_node_t;
@@ -1828,7 +1825,7 @@ omp_sese_pseudo (basic_block me, bb_sese *sese, int depth, int dir,
 
 static void
 omp_sese_color (auto_vec<unsigned> &color_counts, bb_pair_vec_t &regions,
-		  basic_block block, int coloring)
+		basic_block block, int coloring)
 {
   bb_sese *sese = BB_GET_SESE (block);
 
@@ -1882,7 +1879,7 @@ omp_sese_color (auto_vec<unsigned> &color_counts, bb_pair_vec_t &regions,
 /* Find minimal set of SESE regions covering BLOCKS.  REGIONS might
    end up with NULL entries in it.  */
 
-static void
+void
 omp_find_sese (auto_vec<basic_block> &blocks, bb_pair_vec_t &regions)
 {
   basic_block block;
diff --git a/gcc/omp-sese.h b/gcc/omp-sese.h
index 57290eb9d65..0b82a2417eb 100644
--- a/gcc/omp-sese.h
+++ b/gcc/omp-sese.h
@@ -21,6 +21,12 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_OMP_SESE_H
 #define GCC_OMP_SESE_H
 
+/* A pair of BBs.  We use this to represent SESE regions.  */
+typedef std::pair<basic_block, basic_block> bb_pair_t;
+typedef auto_vec<bb_pair_t> bb_pair_vec_t;
+
+extern void omp_find_sese (auto_vec<basic_block> &blocks,
+			   bb_pair_vec_t &regions);
 extern void oacc_do_neutering (void);
 
 #endif
-- 
2.22.0



More information about the Gcc-patches mailing list