diff mbox

[committed,gomp4] Don't cancel loop tree in parloops

Message ID 55B724EF.1000708@mentor.com
State New
Headers show

Commit Message

Tom de Vries July 28, 2015, 6:45 a.m. UTC
Hi,

I've committed these two patches to gomp-4_0-branch.

The first reverts a conservative fix for PR66846.

The second one fixes the PR in an optimal way.
( trunk submission thread at 
https://gcc.gnu.org/ml/gcc-patches/2015-07/msg01328.html )

Thanks,
- Tom
diff mbox

Patch

Don't cancel loop tree in parloops

2015-07-27  Tom de Vries  <tom@codesourcery.com>

	PR tree-optimization/66846
	* omp-low.c (expand_omp_taskreg) [ENABLE_CHECKING]: Call
	verify_loop_structure for child_cfun if !LOOPS_NEED_FIXUP.
	(expand_omp_target) [ENABLE_CHECKING]: Same.
	(execute_expand_omp): Reinstate LOOPS_HAVE_SIMPLE_LATCHES if in ssa.
	[ENABLE_CHECKING]: Call verify_loop_structure for cfun if
	!LOOPS_NEED_FIXUP.
	(expand_omp_for_static_nochunk): Handle case that omp_for already has
	its own loop struct.
	* tree-parloops.c (create_parallel_loop): Add comment about breaking
	LOOPS_HAVE_SIMPLE_LATCHES.  Record new exit.
	(gen_parallel_loop): Remove call to cancel_loop_tree.
	(parallelize_loops): Skip loops that are inner loops of parallelized
	loops.
	(pass_parallelize_loops::execute): Clear LOOPS_HAVE_SIMPLE_LATCHES on
	loop state.
	[ENABLE_CHECKING]: Call verify_loop_structure.
---
 gcc/omp-low.c       | 28 +++++++++++++++++++++++++++-
 gcc/tree-parloops.c | 32 ++++++++++++++++++++++++++++----
 2 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 5dd99b9..a1481e4 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -5917,6 +5917,10 @@  expand_omp_taskreg (struct omp_region *region)
 	}
       if (gimple_in_ssa_p (cfun))
 	update_ssa (TODO_update_ssa);
+#ifdef ENABLE_CHECKING
+      if (!loops_state_satisfies_p (LOOPS_NEED_FIXUP))
+	verify_loop_structure ();
+#endif
       pop_cfun ();
     }
 
@@ -7206,9 +7210,17 @@  expand_omp_for_static_nochunk (struct omp_region *region,
   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
 			   recompute_dominator (CDI_DOMINATORS, fin_bb));
 
+  struct loop *loop = body_bb->loop_father;
+  if (loop != entry_bb->loop_father)
+    {
+      gcc_assert (loop->header == body_bb);
+      gcc_assert (broken_loop || loop->latch == region->cont);
+      return;
+    }
+
   if (!broken_loop && !gimple_omp_for_combined_p (fd->for_stmt))
     {
-      struct loop *loop = alloc_loop ();
+      loop = alloc_loop ();
       loop->header = body_bb;
       if (collapse_bb == NULL)
 	loop->latch = cont_bb;
@@ -9558,6 +9570,10 @@  expand_omp_target (struct omp_region *region)
 	}
       if (gimple_in_ssa_p (cfun))
 	update_ssa (TODO_update_ssa);
+#ifdef ENABLE_CHECKING
+      if (!loops_state_satisfies_p (LOOPS_NEED_FIXUP))
+	verify_loop_structure ();
+#endif
       pop_cfun ();
     }
 
@@ -10174,6 +10190,16 @@  execute_expand_omp (void)
 
       expand_omp (root_omp_region);
 
+      /* We dropped this property in parloops because of the omp_for.  Now that
+	 the omp_for has been expanded, reinstate it.  */
+      if (gimple_in_ssa_p (cfun)
+	  && !loops_state_satisfies_p (LOOPS_MAY_HAVE_MULTIPLE_LATCHES))
+	loops_state_set (LOOPS_HAVE_SIMPLE_LATCHES);
+
+#ifdef ENABLE_CHECKING
+      if (!loops_state_satisfies_p (LOOPS_NEED_FIXUP))
+	verify_loop_structure ();
+#endif
       cleanup_tree_cfg ();
 
       free_omp_regions ();
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 0904dbf..44a3816 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -2151,7 +2151,14 @@  create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
 
   guard = make_edge (for_bb, ex_bb, 0);
   single_succ_edge (loop->latch)->flags = 0;
+
+  /* After creating this edge, the latch has two successors, so
+     LOOPS_HAVE_SIMPLE_LATCHES is no longer valid.  We'll update the loop state
+     as such at the end of the pass, since it's not needed earlier, and doing it
+     earlier will invalidate info for loops we still need to process.  */
   end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU);
+  rescan_loop_exit (end, true, false);
+
   for (gphi_iterator gpi = gsi_start_phis (ex_bb);
        !gsi_end_p (gpi); gsi_next (&gpi))
     {
@@ -2414,10 +2421,6 @@  gen_parallel_loop (struct loop *loop,
 
   scev_reset ();
 
-  /* Cancel the loop (it is simpler to do it here rather than to teach the
-     expander to do it).  */
-  cancel_loop_tree (loop);
-
   /* Free loop bound estimations that could contain references to
      removed statements.  */
   FOR_EACH_LOOP (loop, 0)
@@ -2709,6 +2712,7 @@  parallelize_loops (bool oacc_kernels_p)
   unsigned n_threads = flag_tree_parallelize_loops;
   bool changed = false;
   struct loop *loop;
+  struct loop *skip_loop = NULL;
   struct tree_niter_desc niter_desc;
   struct obstack parloop_obstack;
   HOST_WIDE_INT estimated;
@@ -2729,6 +2733,19 @@  parallelize_loops (bool oacc_kernels_p)
 
   FOR_EACH_LOOP (loop, 0)
     {
+      if (loop == skip_loop)
+	{
+	  if (dump_file && (dump_flags & TDF_DETAILS))
+	    fprintf (dump_file,
+		     "Skipping loop %d as inner loop of parallelized loop\n",
+		     loop->num);
+
+	  skip_loop = loop->inner;
+	  continue;
+	}
+      else
+	skip_loop = NULL;
+
       reduction_list.empty ();
 
       if (oacc_kernels_p)
@@ -2818,6 +2835,7 @@  parallelize_loops (bool oacc_kernels_p)
 	}
 
       changed = true;
+      skip_loop = loop->inner;
       if (dump_file && (dump_flags & TDF_DETAILS))
       {
 	if (loop->inner)
@@ -2885,6 +2903,12 @@  pass_parallelize_loops::execute (function *fun)
   if (parallelize_loops (false))
     {
       fun->curr_properties &= ~(PROP_gimple_eomp);
+
+      loops_state_clear (LOOPS_HAVE_SIMPLE_LATCHES);
+#ifdef ENABLE_CHECKING
+      verify_loop_structure ();
+#endif
+
       return TODO_update_ssa;
     }
 
-- 
1.9.1