OSDN Git Service

PR middle-end/27328
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 May 2006 10:41:44 +0000 (10:41 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 May 2006 10:41:44 +0000 (10:41 +0000)
* omp-low.c (remove_exit_barrier): Handle NULL exit_bb.
(expand_omp_parallel): Likewise.
* tree-cfg.c (move_sese_region_to_fn): Likewise.

* gcc.dg/gomp/pr27328.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113455 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/gomp/pr27328.c [new file with mode: 0644]
gcc/tree-cfg.c

index 984916d..9a0849a 100644 (file)
@@ -1,5 +1,10 @@
 2006-05-02  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/27328
+       * omp-low.c (remove_exit_barrier): Handle NULL exit_bb.
+       (expand_omp_parallel): Likewise.
+       * tree-cfg.c (move_sese_region_to_fn): Likewise.
+
        PR middle-end/27325
        * omp-low.c (lower_omp_sections): Call maybe_catch_exception
        on statement list containing also constructors and destructors.
index 92d71ae..62b715e 100644 (file)
@@ -2227,6 +2227,11 @@ remove_exit_barrier (struct omp_region *region)
 
   exit_bb = region->exit;
 
+  /* If the parallel region doesn't return, we don't have REGION->EXIT
+     block at all.  */
+  if (! exit_bb)
+    return;
+
   /* The last insn in the block will be the parallel's OMP_RETURN.  The
      workshare's OMP_RETURN will be in a preceding block.  The kinds of
      statements that can appear in between are extremely limited -- no
@@ -2372,15 +2377,20 @@ expand_omp_parallel (struct omp_region *region)
         regions has invalidated it.  */
       free_dominance_info (CDI_DOMINATORS);
       new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb);
-      single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
+      if (exit_bb)
+       single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
       cgraph_add_new_function (child_fn);
 
       /* Convert OMP_RETURN into a RETURN_EXPR.  */
-      si = bsi_last (exit_bb);
-      gcc_assert (!bsi_end_p (si) && TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
-      t = build1 (RETURN_EXPR, void_type_node, NULL);
-      bsi_insert_after (&si, t, TSI_SAME_STMT);
-      bsi_remove (&si, true);
+      if (exit_bb)
+       {
+         si = bsi_last (exit_bb);
+         gcc_assert (!bsi_end_p (si)
+                     && TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
+         t = build1 (RETURN_EXPR, void_type_node, NULL);
+         bsi_insert_after (&si, t, TSI_SAME_STMT);
+         bsi_remove (&si, true);
+       }
     }
 
   /* Emit a library call to launch the children threads.  */
index b0fda63..b890b64 100644 (file)
@@ -1,5 +1,8 @@
 2006-05-02  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/27328
+       * gcc.dg/gomp/pr27328.c: New test.
+
        PR middle-end/27325
        * g++.dg/gomp/pr27325.C: New test.
 
diff --git a/gcc/testsuite/gcc.dg/gomp/pr27328.c b/gcc/testsuite/gcc.dg/gomp/pr27328.c
new file mode 100644 (file)
index 0000000..afde738
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR middle-end/27328 */
+/* { dg-do compile } */
+
+extern void baz (void) __attribute__((noreturn));
+
+void
+foo (void)
+{
+#pragma omp parallel
+  for (;;)
+    ;
+}
+
+void
+bar (void)
+{
+#pragma omp parallel
+  baz ();
+}
index 744a903..4c5aa4b 100644 (file)
@@ -4814,7 +4814,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
   /* If ENTRY does not strictly dominate EXIT, this cannot be an SESE
      region.  */
   gcc_assert (entry_bb != exit_bb
-              && dominated_by_p (CDI_DOMINATORS, exit_bb, entry_bb));
+              && (!exit_bb
+                 || dominated_by_p (CDI_DOMINATORS, exit_bb, entry_bb)));
 
   bbs = NULL;
   VEC_safe_push (basic_block, heap, bbs, entry_bb);
@@ -4835,15 +4836,25 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
       remove_edge (e);
     }
 
-  num_exit_edges = EDGE_COUNT (exit_bb->succs);
-  exit_succ = (basic_block *) xcalloc (num_exit_edges, sizeof (basic_block));
-  exit_flag = (int *) xcalloc (num_exit_edges, sizeof (int));
-  i = 0;
-  for (ei = ei_start (exit_bb->succs); (e = ei_safe_edge (ei)) != NULL;)
+  if (exit_bb)
     {
-      exit_flag[i] = e->flags;
-      exit_succ[i++] = e->dest;
-      remove_edge (e);
+      num_exit_edges = EDGE_COUNT (exit_bb->succs);
+      exit_succ = (basic_block *) xcalloc (num_exit_edges,
+                                          sizeof (basic_block));
+      exit_flag = (int *) xcalloc (num_exit_edges, sizeof (int));
+      i = 0;
+      for (ei = ei_start (exit_bb->succs); (e = ei_safe_edge (ei)) != NULL;)
+       {
+         exit_flag[i] = e->flags;
+         exit_succ[i++] = e->dest;
+         remove_edge (e);
+       }
+    }
+  else
+    {
+      num_exit_edges = 0;
+      exit_succ = NULL;
+      exit_flag = NULL;
     }
 
   /* Switch context to the child function to initialize DEST_FN's CFG.  */
@@ -4923,7 +4934,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
      these helpers.  */
   cfun = dest_cfun;
   make_edge (ENTRY_BLOCK_PTR, entry_bb, EDGE_FALLTHRU);
-  make_edge (exit_bb,  EXIT_BLOCK_PTR, 0);
+  if (exit_bb)
+    make_edge (exit_bb,  EXIT_BLOCK_PTR, 0);
   cfun = saved_cfun;
 
   /* Back in the original function, the SESE region has disappeared,
@@ -4935,10 +4947,13 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
   for (i = 0; i < num_exit_edges; i++)
     make_edge (bb, exit_succ[i], exit_flag[i]);
 
-  free (exit_flag);
+  if (exit_bb)
+    {
+      free (exit_flag);
+      free (exit_succ);
+    }
   free (entry_flag);
   free (entry_pred);
-  free (exit_succ);
   free_dominance_info (CDI_DOMINATORS);
   free_dominance_info (CDI_POST_DOMINATORS);
   VEC_free (basic_block, heap, bbs);