OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / omp-low.c
index 1e9150a..e5e128c 100644 (file)
@@ -758,12 +758,20 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx)
       if (TREE_ADDRESSABLE (decl))
        return true;
 
+      /* lower_send_shared_vars only uses copy-in, but not copy-out
+        for these.  */
+      if (TREE_READONLY (decl)
+         || ((TREE_CODE (decl) == RESULT_DECL
+              || TREE_CODE (decl) == PARM_DECL)
+             && DECL_BY_REFERENCE (decl)))
+       return false;
+
       /* Disallow copy-in/out in nested parallel if
         decl is shared in outer parallel, otherwise
         each thread could store the shared variable
         in its own copy-in location, making the
         variable no longer really shared.  */
-      if (!TREE_READONLY (decl) && shared_ctx->is_nested)
+      if (shared_ctx->is_nested)
        {
          omp_context *up;
 
@@ -786,11 +794,10 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx)
            }
        }
 
-      /* For tasks avoid using copy-in/out, unless they are readonly
-        (in which case just copy-in is used).  As tasks can be
+      /* For tasks avoid using copy-in/out.  As tasks can be
         deferred or executed in different thread, when GOMP_task
         returns, the task hasn't necessarily terminated.  */
-      if (!TREE_READONLY (decl) && is_task_ctx (shared_ctx))
+      if (is_task_ctx (shared_ctx))
        {
          tree outer;
        maybe_mark_addressable_and_ret:
@@ -1823,8 +1830,8 @@ scan_omp_single (gimple stmt, omp_context *outer_ctx)
 
 
 /* Check OpenMP nesting restrictions.  */
-static void
-check_omp_nesting_restrictions (gimple  stmt, omp_context *ctx)
+static bool
+check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
 {
   switch (gimple_code (stmt))
     {
@@ -1843,17 +1850,19 @@ check_omp_nesting_restrictions (gimple  stmt, omp_context *ctx)
          case GIMPLE_OMP_TASK:
            if (is_gimple_call (stmt))
              {
-               warning (0, "barrier region may not be closely nested inside "
-                           "of work-sharing, critical, ordered, master or "
-                           "explicit task region");
-               return;
+               error_at (gimple_location (stmt),
+                         "barrier region may not be closely nested inside "
+                         "of work-sharing, critical, ordered, master or "
+                         "explicit task region");
+               return false;
              }
-           warning (0, "work-sharing region may not be closely nested inside "
-                       "of work-sharing, critical, ordered, master or explicit "
-                       "task region");
-           return;
+           error_at (gimple_location (stmt),
+                     "work-sharing region may not be closely nested inside "
+                     "of work-sharing, critical, ordered, master or explicit "
+                     "task region");
+           return false;
          case GIMPLE_OMP_PARALLEL:
-           return;
+           return true;
          default:
            break;
          }
@@ -1866,11 +1875,12 @@ check_omp_nesting_restrictions (gimple  stmt, omp_context *ctx)
          case GIMPLE_OMP_SECTIONS:
          case GIMPLE_OMP_SINGLE:
          case GIMPLE_OMP_TASK:
-           warning (0, "master region may not be closely nested inside "
-                       "of work-sharing or explicit task region");
-           return;
+           error_at (gimple_location (stmt),
+                     "master region may not be closely nested inside "
+                     "of work-sharing or explicit task region");
+           return false;
          case GIMPLE_OMP_PARALLEL:
-           return;
+           return true;
          default:
            break;
          }
@@ -1881,17 +1891,22 @@ check_omp_nesting_restrictions (gimple  stmt, omp_context *ctx)
          {
          case GIMPLE_OMP_CRITICAL:
          case GIMPLE_OMP_TASK:
-           warning (0, "ordered region may not be closely nested inside "
-                       "of critical or explicit task region");
-           return;
+           error_at (gimple_location (stmt),
+                     "ordered region may not be closely nested inside "
+                     "of critical or explicit task region");
+           return false;
          case GIMPLE_OMP_FOR:
            if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
                                 OMP_CLAUSE_ORDERED) == NULL)
-             warning (0, "ordered region must be closely nested inside "
+             {
+               error_at (gimple_location (stmt),
+                         "ordered region must be closely nested inside "
                          "a loop region with an ordered clause");
-           return;
+               return false;
+             }
+           return true;
          case GIMPLE_OMP_PARALLEL:
-           return;
+           return true;
          default:
            break;
          }
@@ -1902,14 +1917,16 @@ check_omp_nesting_restrictions (gimple  stmt, omp_context *ctx)
            && (gimple_omp_critical_name (stmt)
                == gimple_omp_critical_name (ctx->stmt)))
          {
-           warning (0, "critical region may not be nested inside a critical "
-                       "region with the same name");
-           return;
+           error_at (gimple_location (stmt),
+                     "critical region may not be nested inside a critical "
+                     "region with the same name");
+           return false;
          }
       break;
     default:
       break;
     }
+  return true;
 }
 
 
@@ -1980,14 +1997,20 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
   /* Check the OpenMP nesting restrictions.  */
   if (ctx != NULL)
     {
+      bool remove = false;
       if (is_gimple_omp (stmt))
-       check_omp_nesting_restrictions (stmt, ctx);
+       remove = !check_omp_nesting_restrictions (stmt, ctx);
       else if (is_gimple_call (stmt))
        {
          tree fndecl = gimple_call_fndecl (stmt);
          if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
              && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
-           check_omp_nesting_restrictions (stmt, ctx);
+           remove = !check_omp_nesting_restrictions (stmt, ctx);
+       }
+      if (remove)
+       {
+         stmt = gimple_build_nop ();
+         gsi_replace (gsi, stmt, false);
        }
     }
 
@@ -4742,45 +4765,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
@@ -4833,13 +4851,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;
@@ -4909,18 +4923,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);
 }
 
@@ -6852,6 +6866,9 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
       lower_omp (gimple_try_eval (stmt), ctx);
       lower_omp (gimple_try_cleanup (stmt), ctx);
       break;
+    case GIMPLE_TRANSACTION:
+      lower_omp (gimple_transaction_body (stmt), ctx);
+      break;
     case GIMPLE_BIND:
       lower_omp (gimple_bind_body (stmt), ctx);
       break;