]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/omp-low.c
Merge from trunk.
[thirdparty/gcc.git] / gcc / omp-low.c
index 8e4727cac75abac4dd200eeef36e7d307428c551..17bf1dad0b75dba74f84e0d2e033d629762f147a 100644 (file)
@@ -26,8 +26,14 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
+#include "stringpool.h"
+#include "stor-layout.h"
 #include "rtl.h"
 #include "gimple.h"
+#include "gimplify.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "gimple-walk.h"
 #include "tree-iterator.h"
 #include "tree-inline.h"
 #include "langhooks.h"
@@ -39,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ssa-iterators.h"
 #include "tree-ssanames.h"
 #include "tree-into-ssa.h"
+#include "expr.h"
 #include "tree-dfa.h"
 #include "tree-ssa.h"
 #include "flags.h"
@@ -54,6 +61,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "omp-low.h"
 #include "gimple-low.h"
 #include "tree-cfgcleanup.h"
+#include "tree-nested.h"
 
 
 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
@@ -281,7 +289,7 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
   int i;
   struct omp_for_data_loop dummy_loop;
   location_t loc = gimple_location (for_stmt);
-  bool simd = gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_SIMD;
+  bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_KIND_SIMD;
   bool distribute = gimple_omp_for_kind (for_stmt)
                    == GF_OMP_FOR_KIND_DISTRIBUTE;
 
@@ -373,6 +381,10 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
        case LT_EXPR:
        case GT_EXPR:
          break;
+       case NE_EXPR:
+         gcc_assert (gimple_omp_for_kind (for_stmt)
+                     == GF_OMP_FOR_KIND_CILKSIMD);
+         break;
        case LE_EXPR:
          if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
            loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
@@ -999,7 +1011,7 @@ build_outer_var_ref (tree var, omp_context *ctx)
       x = build_receiver_ref (var, by_ref, ctx);
     }
   else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
-          && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+          && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
     {
       /* #pragma omp simd isn't a worksharing construct, and can reference even
         private vars in its linear etc. clauses.  */
@@ -2226,7 +2238,7 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
   if (ctx != NULL)
     {
       if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
-         && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+         && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
        {
          error_at (gimple_location (stmt),
                    "OpenMP constructs may not be nested inside simd region");
@@ -2249,7 +2261,7 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
   switch (gimple_code (stmt))
     {
     case GIMPLE_OMP_FOR:
-      if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
+      if (gimple_omp_for_kind (stmt) & GF_OMP_FOR_KIND_SIMD)
        return true;
       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
        {
@@ -2530,6 +2542,23 @@ scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
   return NULL_TREE;
 }
 
+/* Return true if FNDECL is a setjmp or a longjmp.  */
+
+static bool
+setjmp_or_longjmp_p (const_tree fndecl)
+{
+  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+      && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
+         || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
+    return true;
+
+  tree declname = DECL_NAME (fndecl);
+  if (!declname)
+    return false;
+  const char *name = IDENTIFIER_POINTER (declname);
+  return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
+}
+
 
 /* Helper function for scan_omp.
 
@@ -2553,22 +2582,33 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
   else if (is_gimple_call (stmt))
     {
       tree fndecl = gimple_call_fndecl (stmt);
-      if (fndecl
-         && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
-       switch (DECL_FUNCTION_CODE (fndecl))
-         {
-         case BUILT_IN_GOMP_BARRIER:
-         case BUILT_IN_GOMP_CANCEL:
-         case BUILT_IN_GOMP_CANCELLATION_POINT:
-         case BUILT_IN_GOMP_TASKYIELD:
-         case BUILT_IN_GOMP_TASKWAIT:
-         case BUILT_IN_GOMP_TASKGROUP_START:
-         case BUILT_IN_GOMP_TASKGROUP_END:
-           remove = !check_omp_nesting_restrictions (stmt, ctx);
-           break;
-         default:
-           break;
-         }
+      if (fndecl)
+       {
+         if (setjmp_or_longjmp_p (fndecl)
+             && ctx
+             && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+             && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
+           {
+             remove = true;
+             error_at (gimple_location (stmt),
+                       "setjmp/longjmp inside simd construct");
+           }
+         else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+           switch (DECL_FUNCTION_CODE (fndecl))
+             {
+             case BUILT_IN_GOMP_BARRIER:
+             case BUILT_IN_GOMP_CANCEL:
+             case BUILT_IN_GOMP_CANCELLATION_POINT:
+             case BUILT_IN_GOMP_TASKYIELD:
+             case BUILT_IN_GOMP_TASKWAIT:
+             case BUILT_IN_GOMP_TASKGROUP_START:
+             case BUILT_IN_GOMP_TASKGROUP_END:
+               remove = !check_omp_nesting_restrictions (stmt, ctx);
+               break;
+             default:
+               break;
+             }
+       }
     }
   if (remove)
     {
@@ -2961,7 +3001,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
   bool reduction_omp_orig_ref = false;
   int pass;
   bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
-                 && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
+                 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD);
   int max_vf = 0;
   tree lane = NULL_TREE, idx = NULL_TREE;
   tree ivar = NULL_TREE, lvar = NULL_TREE;
@@ -3581,7 +3621,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
       /* Don't add any barrier for #pragma omp simd or
         #pragma omp distribute.  */
       if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
-         || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR)
+         || gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_FOR)
        gimple_seq_add_stmt (ilist, build_omp_barrier (NULL_TREE));
     }
 
@@ -3660,7 +3700,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
     }
 
   if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
-      && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+      && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
     {
       simduid = find_omp_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
       if (simduid)
@@ -3755,7 +3795,7 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
 
   /* SIMD reductions are handled in lower_rec_input_clauses.  */
   if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
-      && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+      && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
     return;
 
   /* First see if there is exactly one reduction clause.  Use OMP_ATOMIC
@@ -6787,7 +6827,7 @@ expand_omp_for (struct omp_region *region, gimple inner_stmt)
        original loops from being detected.  Fix that up.  */
     loops_state_set (LOOPS_NEED_FIXUP);
 
-  if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_SIMD)
+  if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_KIND_SIMD)
     expand_omp_simd (region, &fd);
   else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
           && !fd.have_ordered)
@@ -8193,7 +8233,7 @@ build_omp_regions (void)
 {
   gcc_assert (root_omp_region == NULL);
   calculate_dominance_info (CDI_DOMINATORS);
-  build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
+  build_omp_regions_1 (ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, false);
 }
 
 /* Main entry point for expanding OMP-GIMPLE into runtime calls.  */
@@ -8229,7 +8269,8 @@ execute_expand_omp (void)
 static bool
 gate_expand_omp (void)
 {
-  return ((flag_openmp != 0 || flag_openmp_simd != 0) && !seen_error ());
+  return ((flag_openmp != 0 || flag_openmp_simd != 0
+          || flag_enable_cilkplus != 0) && !seen_error ());
 }
 
 namespace {
@@ -10050,7 +10091,7 @@ execute_lower_omp (void)
 
   /* This pass always runs, to provide PROP_gimple_lomp.
      But there is nothing to do unless -fopenmp is given.  */
-  if (flag_openmp == 0 && flag_openmp_simd == 0)
+  if (flag_openmp == 0 && flag_openmp_simd == 0 && flag_enable_cilkplus == 0)
     return 0;
 
   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
@@ -10170,12 +10211,33 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
     error ("invalid entry to OpenMP structured block");
 #endif
 
+  bool cilkplus_block = false;
+  if (flag_enable_cilkplus)
+    {
+      if ((branch_ctx
+          && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
+          && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
+         || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
+             && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
+       cilkplus_block = true;
+    }
+
   /* If it's obvious we have an invalid entry, be specific about the error.  */
   if (branch_ctx == NULL)
-    error ("invalid entry to OpenMP structured block");
+    {
+      if (cilkplus_block)
+       error ("invalid entry to Cilk Plus structured block");
+      else
+       error ("invalid entry to OpenMP structured block");
+    }
   else
-    /* Otherwise, be vague and lazy, but efficient.  */
-    error ("invalid branch to/from an OpenMP structured block");
+    {
+      /* Otherwise, be vague and lazy, but efficient.  */
+      if (cilkplus_block)
+       error ("invalid branch to/from a Cilk Plus structured block");
+      else
+       error ("invalid branch to/from an OpenMP structured block");
+    }
 
   gsi_replace (gsi_p, gimple_build_nop (), false);
   return true;
@@ -10479,7 +10541,7 @@ diagnose_omp_structured_block_errors (void)
 static bool
 gate_diagnose_omp_blocks (void)
 {
-  return flag_openmp != 0;
+  return flag_openmp || flag_enable_cilkplus;
 }
 
 namespace {