OSDN Git Service

PR middle-end/54017
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Jul 2012 14:05:54 +0000 (14:05 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Jul 2012 14:05:54 +0000 (14:05 +0000)
* tree-cfgcleanup.c (cleanup_omp_return): Remove.
(cleanup_tree_cfg_bb): Don't call it.
* omp-low.c (expand_omp_sections): Fix up the !exit_reachable case
handling.

* c-c++-common/gomp/pr54017.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@189659 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/gomp/pr54017.c [new file with mode: 0644]
gcc/tree-cfgcleanup.c

index 6c5b08f..eae42d7 100644 (file)
@@ -1,3 +1,11 @@
+2012-07-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/54017
+       * tree-cfgcleanup.c (cleanup_omp_return): Remove.
+       (cleanup_tree_cfg_bb): Don't call it.
+       * omp-low.c (expand_omp_sections): Fix up the !exit_reachable case
+       handling.
+
 2012-07-19  Christian Bruel  <christian.bruel@st.com>
 
        PR target/54029
index 8a9f387..4247a80 100644 (file)
@@ -4758,45 +4758,40 @@ expand_omp_sections (struct omp_region *region)
   unsigned i, casei;
   bool exit_reachable = region->cont != NULL;
 
-  gcc_assert (exit_reachable == (region->exit != NULL));
+  gcc_assert (region->exit != NULL);
   entry_bb = region->entry;
   l0_bb = single_succ (entry_bb);
   l1_bb = region->cont;
   l2_bb = region->exit;
-  if (exit_reachable)
+  if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
+    l2 = gimple_block_label (l2_bb);
+  else
     {
-      if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
-       l2 = gimple_block_label (l2_bb);
+      /* This can happen if there are reductions.  */
+      len = EDGE_COUNT (l0_bb->succs);
+      gcc_assert (len > 0);
+      e = EDGE_SUCC (l0_bb, len - 1);
+      si = gsi_last_bb (e->dest);
+      l2 = NULL_TREE;
+      if (gsi_end_p (si)
+          || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
+       l2 = gimple_block_label (e->dest);
       else
-       {
-         /* This can happen if there are reductions.  */
-         len = EDGE_COUNT (l0_bb->succs);
-         gcc_assert (len > 0);
-         e = EDGE_SUCC (l0_bb, len - 1);
-         si = gsi_last_bb (e->dest);
-         l2 = NULL_TREE;
-         if (gsi_end_p (si)
-             || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
-           l2 = gimple_block_label (e->dest);
-         else
-           FOR_EACH_EDGE (e, ei, l0_bb->succs)
+       FOR_EACH_EDGE (e, ei, l0_bb->succs)
+         {
+           si = gsi_last_bb (e->dest);
+           if (gsi_end_p (si)
+               || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
              {
-               si = gsi_last_bb (e->dest);
-               if (gsi_end_p (si)
-                   || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
-                 {
-                   l2 = gimple_block_label (e->dest);
-                   break;
-                 }
+               l2 = gimple_block_label (e->dest);
+               break;
              }
-       }
-      default_bb = create_empty_bb (l1_bb->prev_bb);
+         }
     }
+  if (exit_reachable)
+    default_bb = create_empty_bb (l1_bb->prev_bb);
   else
-    {
-      default_bb = create_empty_bb (l0_bb);
-      l2 = gimple_block_label (default_bb);
-    }
+    default_bb = create_empty_bb (l0_bb);
 
   /* We will build a switch() with enough cases for all the
      GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
@@ -4849,13 +4844,9 @@ expand_omp_sections (struct omp_region *region)
       vnext = NULL_TREE;
     }
 
-  i = 0;
-  if (exit_reachable)
-    {
-      t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
-      VEC_quick_push (tree, label_vec, t);
-      i++;
-    }
+  t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
+  VEC_quick_push (tree, label_vec, t);
+  i = 1;
 
   /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR.  */
   for (inner = region->inner, casei = 1;
@@ -4925,18 +4916,18 @@ expand_omp_sections (struct omp_region *region)
       gsi_remove (&si, true);
 
       single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
-
-      /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB.  */
-      si = gsi_last_bb (l2_bb);
-      if (gimple_omp_return_nowait_p (gsi_stmt (si)))
-       t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
-      else
-       t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
-      stmt = gimple_build_call (t, 0);
-      gsi_insert_after (&si, stmt, GSI_SAME_STMT);
-      gsi_remove (&si, true);
     }
 
+  /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB.  */
+  si = gsi_last_bb (l2_bb);
+  if (gimple_omp_return_nowait_p (gsi_stmt (si)))
+    t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
+  else
+    t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
+  stmt = gimple_build_call (t, 0);
+  gsi_insert_after (&si, stmt, GSI_SAME_STMT);
+  gsi_remove (&si, true);
+
   set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
 }
 
index f165daf..a59572d 100644 (file)
@@ -1,3 +1,8 @@
+2012-07-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/54017
+       * c-c++-common/gomp/pr54017.c: New test.
+
 2012-07-18  Richard Guenther  <rguenther@suse.de>
 
        Backport from mainline
diff --git a/gcc/testsuite/c-c++-common/gomp/pr54017.c b/gcc/testsuite/c-c++-common/gomp/pr54017.c
new file mode 100644 (file)
index 0000000..724efe1
--- /dev/null
@@ -0,0 +1,65 @@
+/* PR middle-end/54017 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+void
+f1 (void)
+{
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+      for (;;)
+       ;
+    }
+  }
+}
+
+int
+f2 (void)
+{
+  int i = 0;
+#pragma omp parallel
+#pragma omp sections reduction(+:i)
+  {
+#pragma omp section
+    {
+      for (;;)
+       ;
+    }
+  }
+  return i;
+}
+
+void
+f3 (void)
+{
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+      for (;;)
+       ;
+    }
+#pragma omp section
+    ;
+  }
+}
+
+int
+f4 (void)
+{
+  int i = 0;
+#pragma omp parallel
+#pragma omp sections reduction(+:i)
+  {
+#pragma omp section
+    {
+      for (;;)
+       ;
+    }
+#pragma omp section
+    ;
+  }
+  return i;
+}
index 0c8c085..8348d25 100644 (file)
@@ -610,48 +610,13 @@ split_bbs_on_noreturn_calls (void)
   return changed;
 }
 
-/* If GIMPLE_OMP_RETURN in basic block BB is unreachable, remove it.  */
-
-static bool
-cleanup_omp_return (basic_block bb)
-{
-  gimple stmt = last_stmt (bb);
-  basic_block control_bb;
-
-  if (stmt == NULL
-      || gimple_code (stmt) != GIMPLE_OMP_RETURN
-      || !single_pred_p (bb))
-    return false;
-
-  control_bb = single_pred (bb);
-  stmt = last_stmt (control_bb);
-
-  if (stmt == NULL || gimple_code (stmt) != GIMPLE_OMP_SECTIONS_SWITCH)
-    return false;
-
-  /* The block with the control statement normally has two entry edges -- one
-     from entry, one from continue.  If continue is removed, return is
-     unreachable, so we remove it here as well.  */
-  if (EDGE_COUNT (control_bb->preds) == 2)
-    return false;
-
-  gcc_assert (EDGE_COUNT (control_bb->preds) == 1);
-  remove_edge_and_dominated_blocks (single_pred_edge (bb));
-  return true;
-}
-
 /* Tries to cleanup cfg in basic block BB.  Returns true if anything
    changes.  */
 
 static bool
 cleanup_tree_cfg_bb (basic_block bb)
 {
-  bool retval = false;
-
-  if (cleanup_omp_return (bb))
-    return true;
-
-  retval = cleanup_control_flow_bb (bb);
+  bool retval = cleanup_control_flow_bb (bb);
 
   if (tree_forwarder_block_p (bb, false)
       && remove_forwarder_block (bb))