]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Merge remote-tracking branch 'origin/releases/gcc-10' into devel/omp/gcc-10
authorTobias Burnus <tobias@codesourcery.com>
Mon, 15 Jun 2020 15:57:43 +0000 (17:57 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Mon, 15 Jun 2020 15:57:43 +0000 (17:57 +0200)
Merged up to 8a3453786c3c2d6343c5258e564ad139d5ad116f (Jun 15, 2020)

1  2 
gcc/c-family/c-pretty-print.c
gcc/cp/cp-gimplify.c
gcc/cp/decl.c
gcc/fortran/gfortran.h
gcc/gimplify.c
gcc/omp-general.c
gcc/omp-general.h
gcc/omp-offload.c

Simple merge
index 65ed2f5c6b21d541452fc879fa75aa908beb8f95,11b836f7bb976e13be7f57e9d6cbae4e264d46d4..cc6eb2be3afc239965314ae5c77b8ea961b6b402
@@@ -1340,6 -1646,75 +1341,83 @@@ cp_genericize_r (tree *stmt_p, int *wal
        *stmt_p = genericize_spaceship (*stmt_p);
        break;
  
 -      genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
+     case OMP_DISTRIBUTE:
+       /* Need to explicitly instantiate copy ctors on class iterators of
+        composite distribute parallel for.  */
+       if (OMP_FOR_INIT (*stmt_p) == NULL_TREE)
+       {
+         tree *data[4] = { NULL, NULL, NULL, NULL };
+         tree inner = walk_tree (&OMP_FOR_BODY (*stmt_p),
+                                 find_combined_omp_for, data, NULL);
+         if (inner != NULL_TREE
+             && TREE_CODE (inner) == OMP_FOR)
+           {
+             for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner)); i++)
+               if (OMP_FOR_ORIG_DECLS (inner)
+                   && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
+                                 i)) == TREE_LIST
+                   && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
+                                    i)))
+                 {
+                   tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), i);
+                   /* Class iterators aren't allowed on OMP_SIMD, so the only
+                      case we need to solve is distribute parallel for.  */
+                   gcc_assert (TREE_CODE (inner) == OMP_FOR
+                               && data[1]);
+                   tree orig_decl = TREE_PURPOSE (orig);
+                   tree c, cl = NULL_TREE;
+                   for (c = OMP_FOR_CLAUSES (inner);
+                        c; c = OMP_CLAUSE_CHAIN (c))
+                     if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
+                          || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+                         && OMP_CLAUSE_DECL (c) == orig_decl)
+                       {
+                         cl = c;
+                         break;
+                       }
+                   if (cl == NULL_TREE)
+                     {
+                       for (c = OMP_PARALLEL_CLAUSES (*data[1]);
+                            c; c = OMP_CLAUSE_CHAIN (c))
+                         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
+                             && OMP_CLAUSE_DECL (c) == orig_decl)
+                           {
+                             cl = c;
+                             break;
+                           }
+                     }
+                   if (cl)
+                     {
+                       orig_decl = require_complete_type (orig_decl);
+                       tree inner_type = TREE_TYPE (orig_decl);
+                       if (orig_decl == error_mark_node)
+                         continue;
+                       if (TYPE_REF_P (TREE_TYPE (orig_decl)))
+                         inner_type = TREE_TYPE (inner_type);
+                       while (TREE_CODE (inner_type) == ARRAY_TYPE)
+                         inner_type = TREE_TYPE (inner_type);
+                       get_copy_ctor (inner_type, tf_warning_or_error);
+                     }
+               }
+           }
+       }
+       /* FALLTHRU */
++    case FOR_STMT:
++    case WHILE_STMT:
++    case DO_STMT:
++    case SWITCH_STMT:
++    case CONTINUE_STMT:
++    case BREAK_STMT:
+     case OMP_FOR:
+     case OMP_SIMD:
+     case OMP_LOOP:
+     case OACC_LOOP:
++      /* These cases are handled by shared code.  */
++      c_genericize_control_stmt (stmt_p, walk_subtrees, data,
++                               cp_genericize_r, cp_walk_subtrees);
+       break;
      case PTRMEM_CST:
        /* By the time we get here we're handing off to the back end, so we don't
         need or want to preserve PTRMEM_CST anymore.  */
diff --cc gcc/cp/decl.c
Simple merge
Simple merge
diff --cc gcc/gimplify.c
index 3defdb70fa00e447715ea3914cefea2a156894d2,ff40cf1376966f162bc2946d093fc39adeba7e8d..37ea9e0673cb924085d2bb6c8b8da5a6c854124f
@@@ -11219,152 -10987,6 +11219,96 @@@ gimplify_omp_task (tree *expr_p, gimple
    *expr_p = NULL_TREE;
  }
  
- /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
-    with non-NULL OMP_FOR_INIT.  Also, fill in pdata array,
-    pdata[0] non-NULL if there is anything non-trivial in between, pdata[1]
-    is address of OMP_PARALLEL in between if any, pdata[2] is address of
-    OMP_FOR in between if any and pdata[3] is address of the inner
-    OMP_FOR/OMP_SIMD.  */
- static tree
- find_combined_omp_for (tree *tp, int *walk_subtrees, void *data)
- {
-   tree **pdata = (tree **) data;
-   *walk_subtrees = 0;
-   switch (TREE_CODE (*tp))
-     {
-     case OMP_FOR:
-       if (OMP_FOR_INIT (*tp) != NULL_TREE)
-       {
-         pdata[3] = tp;
-         return *tp;
-       }
-       pdata[2] = tp;
-       *walk_subtrees = 1;
-       break;
-     case OMP_SIMD:
-       if (OMP_FOR_INIT (*tp) != NULL_TREE)
-       {
-         pdata[3] = tp;
-         return *tp;
-       }
-       break;
-     case BIND_EXPR:
-       if (BIND_EXPR_VARS (*tp)
-         || (BIND_EXPR_BLOCK (*tp)
-             && BLOCK_VARS (BIND_EXPR_BLOCK (*tp))))
-       pdata[0] = tp;
-       *walk_subtrees = 1;
-       break;
-     case STATEMENT_LIST:
-       if (!tsi_one_before_end_p (tsi_start (*tp)))
-       pdata[0] = tp;
-       *walk_subtrees = 1;
-       break;
-     case TRY_FINALLY_EXPR:
-       pdata[0] = tp;
-       *walk_subtrees = 1;
-       break;
-     case OMP_PARALLEL:
-       pdata[1] = tp;
-       *walk_subtrees = 1;
-       break;
-     default:
-       break;
-     }
-   return NULL_TREE;
- }
 +/* Helper function for localize_reductions.  Replace all uses of REF_VAR with
 +   LOCAL_VAR.  */
 +
 +static tree
 +localize_reductions_r (tree *tp, int *walk_subtrees, void *data)
 +{
 +  enum tree_code tc = TREE_CODE (*tp);
 +  struct privatize_reduction *pr = (struct privatize_reduction *) data;
 +
 +  if (TYPE_P (*tp))
 +    *walk_subtrees = 0;
 +
 +  switch (tc)
 +    {
 +    case INDIRECT_REF:
 +    case MEM_REF:
 +      if (TREE_OPERAND (*tp, 0) == pr->ref_var)
 +      *tp = pr->local_var;
 +
 +      *walk_subtrees = 0;
 +      break;
 +
 +    case VAR_DECL:
 +    case PARM_DECL:
 +    case RESULT_DECL:
 +      if (*tp == pr->ref_var)
 +      *tp = pr->local_var;
 +
 +      *walk_subtrees = 0;
 +      break;
 +
 +    default:
 +      break;
 +    }
 +
 +  return NULL_TREE;
 +}
 +
 +/* OpenACC worker and vector loop state propagation requires reductions
 +   to be inside local variables.  This function replaces all reference-type
 +   reductions variables associated with the loop with a local copy.  It is
 +   also used to create private copies of reduction variables for those
 +   which are not associated with acc loops.  */
 +
 +static void
 +localize_reductions (tree clauses, tree body)
 +{
 +  tree c, var, type, new_var;
 +  struct privatize_reduction pr;
 +
 +  for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
 +    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
 +      {
 +      var = OMP_CLAUSE_DECL (c);
 +
 +      if (!lang_hooks.decls.omp_privatize_by_reference (var))
 +        {
 +          OMP_CLAUSE_REDUCTION_PRIVATE_DECL (c) = NULL;
 +          continue;
 +        }
 +
 +      type = TREE_TYPE (TREE_TYPE (var));
 +      new_var = create_tmp_var (type, IDENTIFIER_POINTER (DECL_NAME (var)));
 +
 +      pr.ref_var = var;
 +      pr.local_var = new_var;
 +
 +      walk_tree (&body, localize_reductions_r, &pr, NULL);
 +
 +      OMP_CLAUSE_REDUCTION_PRIVATE_DECL (c) = new_var;
 +      }
 +    else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE)
 +      {
 +      var = OMP_CLAUSE_DECL (c);
 +
 +      if (!lang_hooks.decls.omp_privatize_by_reference (var))
 +        continue;
 +      type = TREE_TYPE (TREE_TYPE (var));
 +      if (TREE_CODE (type) == ARRAY_TYPE)
 +        continue;
 +      new_var = create_tmp_var (type, IDENTIFIER_POINTER (DECL_NAME (var)));
 +
 +      pr.ref_var = var;
 +      pr.local_var = new_var;
 +
 +      walk_tree (&body, localize_reductions_r, &pr, NULL);
 +      }
 +}
 +
 +
  /* Gimplify the gross structure of an OMP_FOR statement.  */
  
  static enum gimplify_status
Simple merge
Simple merge
Simple merge