]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cp/pt.c
gcc/
[thirdparty/gcc.git] / gcc / cp / pt.c
index e3f55a7a9d88013fea780a0753523d77d0cd6222..9e3bd2d261c6a0040d09e2ba203d7c72f700a3f4 100644 (file)
@@ -14419,7 +14419,6 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
            = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
                                      in_decl);
          break;
-       case OMP_CLAUSE_LINEAR:
        case OMP_CLAUSE_ALIGNED:
          OMP_CLAUSE_DECL (nc)
            = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
@@ -14427,12 +14426,25 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
          OMP_CLAUSE_OPERAND (nc, 1)
            = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain,
                           in_decl, /*integral_constant_expression_p=*/false);
-         if (OMP_CLAUSE_CODE (oc) == OMP_CLAUSE_LINEAR
-             && OMP_CLAUSE_LINEAR_STEP (oc) == NULL_TREE)
+         break;
+       case OMP_CLAUSE_LINEAR:
+         OMP_CLAUSE_DECL (nc)
+           = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
+                                     in_decl);
+         if (OMP_CLAUSE_LINEAR_STEP (oc) == NULL_TREE)
            {
              gcc_assert (!linear_no_step);
              linear_no_step = nc;
            }
+         else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (oc))
+           OMP_CLAUSE_LINEAR_STEP (nc)
+             = tsubst_omp_clause_decl (OMP_CLAUSE_LINEAR_STEP (oc), args,
+                                       complain, in_decl);
+         else
+           OMP_CLAUSE_LINEAR_STEP (nc)
+             = tsubst_expr (OMP_CLAUSE_LINEAR_STEP (oc), args, complain,
+                            in_decl,
+                            /*integral_constant_expression_p=*/false);
          break;
        case OMP_CLAUSE_NOWAIT:
        case OMP_CLAUSE_DEFAULT:
@@ -14456,6 +14468,7 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
       if (allow_fields)
        switch (OMP_CLAUSE_CODE (nc))
          {
+         case OMP_CLAUSE_SHARED:
          case OMP_CLAUSE_PRIVATE:
          case OMP_CLAUSE_FIRSTPRIVATE:
          case OMP_CLAUSE_LASTPRIVATE:
@@ -14635,7 +14648,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
                        && DECL_NAME (v) == this_identifier)
                      {
                        decl = TREE_OPERAND (decl, 1);
-                       decl = omp_privatize_field (decl);
+                       decl = omp_privatize_field (decl, false);
                      }
                    /* FALLTHRU */
                  default:
@@ -14816,6 +14829,27 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
 #undef RECUR
 }
 
+/* Helper function of tsubst_expr, find OMP_TEAMS inside
+   of OMP_TARGET's body.  */
+
+static tree
+tsubst_find_omp_teams (tree *tp, int *walk_subtrees, void *)
+{
+  *walk_subtrees = 0;
+  switch (TREE_CODE (*tp))
+    {
+    case OMP_TEAMS:
+      return *tp;
+    case BIND_EXPR:
+    case STATEMENT_LIST:
+      *walk_subtrees = 1;
+      break;
+    default:
+      break;
+    }
+  return NULL_TREE;
+}
+
 /* Like tsubst_copy for expressions, etc. but also does semantic
    processing.  */
 
@@ -15240,7 +15274,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
        if (OMP_FOR_INIT (t) != NULL_TREE)
          {
            declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
-           if (TREE_CODE (t) == OMP_FOR && OMP_FOR_ORIG_DECLS (t))
+           if (OMP_FOR_ORIG_DECLS (t))
              orig_declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
            initv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
            condv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
@@ -15267,7 +15301,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
        if (OMP_FOR_INIT (t) != NULL_TREE)
          t = finish_omp_for (EXPR_LOCATION (t), TREE_CODE (t), declv,
                              orig_declv, initv, condv, incrv, body, pre_body,
-                             clauses);
+                             NULL, clauses);
        else
          {
            t = make_node (TREE_CODE (t));
@@ -15318,6 +15352,36 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       t = copy_node (t);
       OMP_BODY (t) = stmt;
       OMP_CLAUSES (t) = tmp;
+      if (TREE_CODE (t) == OMP_TARGET && OMP_TARGET_COMBINED (t))
+       {
+         tree teams = cp_walk_tree (&stmt, tsubst_find_omp_teams, NULL, NULL);
+         if (teams)
+           {
+             /* For combined target teams, ensure the num_teams and
+                thread_limit clause expressions are evaluated on the host,
+                before entering the target construct.  */
+             tree c;
+             for (c = OMP_TEAMS_CLAUSES (teams);
+                  c; c = OMP_CLAUSE_CHAIN (c))
+               if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
+                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
+                   && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
+                 {
+                   tree expr = OMP_CLAUSE_OPERAND (c, 0);
+                   expr = force_target_expr (TREE_TYPE (expr), expr, tf_none);
+                   if (expr == error_mark_node)
+                     continue;
+                   tmp = TARGET_EXPR_SLOT (expr);
+                   add_stmt (expr);
+                   OMP_CLAUSE_OPERAND (c, 0) = expr;
+                   tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+                                               OMP_CLAUSE_FIRSTPRIVATE);
+                   OMP_CLAUSE_DECL (tc) = tmp;
+                   OMP_CLAUSE_CHAIN (tc) = OMP_TARGET_CLAUSES (t);
+                   OMP_TARGET_CLAUSES (t) = tc;
+                 }
+           }
+       }
       add_stmt (t);
       break;