]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add support for OpenACC routine nohost clause
authorJulian Brown <julian@codesourcery.com>
Thu, 7 Feb 2019 01:46:25 +0000 (17:46 -0800)
committerThomas Schwinge <thomas@codesourcery.com>
Tue, 3 Mar 2020 11:12:58 +0000 (12:12 +0100)
2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
    Cesar Philippidis  <cesar@codesourcery.com>

gcc/
* tree-core.h (omp_clause_code): Add OMP_CLAUSE_NOHOST.
* tree.c (omp_clause_num_ops, omp_clause_code_name, walk_tree_1):
Update for these.
* tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE_NOHOST.
* gimplify.c (gimplify_scan_omp_clauses)
(gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_NOHOST.
* tree-nested.c (convert_nonlocal_omp_clauses)
(convert_local_omp_clauses): Likewise.
* omp-low.c (scan_sharing_clauses): Likewise.
* omp-offload.c (maybe_discard_oacc_function): New function.
(execute_oacc_device_lower) [!ACCEL_COMPILER]: Handle OpenACC
nohost clauses.

gcc/c-family/
* c-attribs.c (c_common_attribute_table): Set min_len to -1 for
"omp declare target".
* c-pragma.h (pragma_omp_clause): Add PRAGMA_OACC_CLAUSE_NOHST.

gcc/c/
* c-parser.c (c_parser_omp_clause_name): Handle "nohost".
(c_parser_oacc_all_clauses): Handle PRAGMA_OACC_CLAUSE_NOHOST.
(c_parser_oacc_routine, c_finish_oacc_routine): Update.
* c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_NOHOST.

gcc/cp/
* parser.c (cp_parser_omp_clause_name): Handle "nohost".
(cp_parser_oacc_all_clauses): Handle PRAGMA_OACC_CLAUSE_NOHOST,
(cp_parser_oacc_routine, cp_finalize_oacc_routine): Update.
* pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_NOHOST.
* semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_NOHOST.

gcc/fortran/
* gfortran.h (gfc_omp_clauses): Add nohost members.
* openmp.c (omp_mask2): Add OMP_CLAUSE_NOHOST.
(gfc_match_omp_clauses): Handle OMP_CLAUSE_NOHOST.
(gfc_match_oacc_routine): Set oacc_function_nohost when appropriate.
* gfortran.h (symbol_attribute): Add oacc_function_nohost member.
* trans-openmp.c (gfc_add_omp_offload_attributes): Use it to decide
whether to generate an OMP_CLAUSE_NOHOST clause.
(gfc_trans_omp_clauses_1): Unreachable code to generate an
OMP_CLAUSE_NOHOST clause.

gcc/testsuite/
* c-c++-common/goacc/classify-routine.c: Adjust test.
* c-c++-common/goacc/routine-1.c: Likewise.
* c-c++-common/goacc/routine-2.c: Likewise.
* c-c++-common/goacc/routine-nohost-1.c: New test.
* g++.dg/goacc/routine-2.C: Adjust test.
* gfortran.dg/goacc/pr72741.f90: New test.

libgomp/
* testsuite/libgomp.oacc-c-c++-common/routine-3.c: New test.
* testsuite/libgomp.oacc-c-c++-common/routine-nohost-1.c: New test.
* testsuite/libgomp.oacc-c-c++-common/routine-bind-nohost-1.c:
Update test.
* testsuite/libgomp.oacc-fortran/routine-6.f90: Likewise.

(cherry picked from openacc-gcc-9-branch commit
a6ec4f19ff50a91a7b0a8c3663e49c071b506016)

34 files changed:
gcc/ChangeLog.omp
gcc/c-family/ChangeLog.omp
gcc/c-family/c-attribs.c
gcc/c-family/c-pragma.h
gcc/c/ChangeLog.omp
gcc/c/c-parser.c
gcc/c/c-typeck.c
gcc/cp/ChangeLog.omp
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/fortran/ChangeLog.omp
gcc/fortran/gfortran.h
gcc/fortran/openmp.c
gcc/fortran/trans-decl.c
gcc/fortran/trans-openmp.c
gcc/gimplify.c
gcc/omp-low.c
gcc/omp-offload.c
gcc/testsuite/ChangeLog.omp
gcc/testsuite/c-c++-common/goacc/classify-routine.c
gcc/testsuite/c-c++-common/goacc/routine-1.c
gcc/testsuite/c-c++-common/goacc/routine-2.c
gcc/testsuite/c-c++-common/goacc/routine-nohost-1.c [new file with mode: 0644]
gcc/testsuite/g++.dg/goacc/routine-2.C
gcc/testsuite/gfortran.dg/goacc/pr72741.f90 [new file with mode: 0644]
gcc/tree-core.h
gcc/tree-nested.c
gcc/tree-pretty-print.c
gcc/tree.c
libgomp/ChangeLog.omp
libgomp/testsuite/libgomp.oacc-c-c++-common/routine-3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.oacc-c-c++-common/routine-nohost-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.oacc-fortran/routine-6.f90 [new file with mode: 0644]

index 3095c0c79f9993c24a79e51796acfaa2a3082c66..d1e1ab54ea9e417832a6f6c94831939eec2d276f 100644 (file)
@@ -1,3 +1,19 @@
+2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * tree-core.h (omp_clause_code): Add OMP_CLAUSE_NOHOST.
+       * tree.c (omp_clause_num_ops, omp_clause_code_name, walk_tree_1):
+       Update for these.
+       * tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE_NOHOST.
+       * gimplify.c (gimplify_scan_omp_clauses)
+       (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_NOHOST.
+       * tree-nested.c (convert_nonlocal_omp_clauses)
+       (convert_local_omp_clauses): Likewise.
+       * omp-low.c (scan_sharing_clauses): Likewise.
+       * omp-offload.c (maybe_discard_oacc_function): New function.
+       (execute_oacc_device_lower) [!ACCEL_COMPILER]: Handle OpenACC
+       nohost clauses.
+
 2019-02-05  Julian Brown  <julian@codesourcery.com>
 
        * omp-low.c (scan_sharing_clauses): Disallow dynamic (multidimensional)
index 20f26d1bd8a4eceb334bebb88e30624a76d907e8..0f348b2219a8cd2cd71d2f4a62f5317e38db4573 100644 (file)
@@ -1,3 +1,10 @@
+2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * c-attribs.c (c_common_attribute_table): Set min_len to -1 for
+       "omp declare target".
+       * c-pragma.h (pragma_omp_clause): Add PRAGMA_OACC_CLAUSE_NOHST.
+
 2018-12-14  Julian Brown  <julian@codesourcery.com>
 
        * c-pragma.h (pragma_omp_clause): Add PRAGMA_OACC_CLAUSE_ATTACH and
index 93b210eed9ca004a7f9b7fc3e24134bd5c04957a..c4bbdf9d7399fc73a9467f2e996e97d660db316a 100644 (file)
@@ -437,7 +437,7 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_omp_declare_simd_attribute, NULL },
   { "simd",                  0, 1, true,  false, false, false,
                              handle_simd_attribute, NULL },
-  { "omp declare target",     0, 0, true, false, false, false,
+  { "omp declare target",     0, -1, true, false, false, false,
                              handle_omp_declare_target_attribute, NULL },
   { "omp declare target link", 0, 0, true, false, false, false,
                              handle_omp_declare_target_attribute, NULL },
index 4746d41fe4e8ca09c5f252f12249b85d1b29b6de..62bdaee80ebf7ce7b145ebf2ca4706eff3fd4432 100644 (file)
@@ -149,6 +149,7 @@ enum pragma_omp_clause {
   PRAGMA_OACC_CLAUSE_GANG,
   PRAGMA_OACC_CLAUSE_HOST,
   PRAGMA_OACC_CLAUSE_INDEPENDENT,
+  PRAGMA_OACC_CLAUSE_NOHOST,
   PRAGMA_OACC_CLAUSE_NUM_GANGS,
   PRAGMA_OACC_CLAUSE_NUM_WORKERS,
   PRAGMA_OACC_CLAUSE_PRESENT,
index 4909c4595dbc7e364d2113b3a40a631b05e24488..023607f1e4d94a8e833d1675fd640fc5349f7c0d 100644 (file)
@@ -1,3 +1,11 @@
+2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * c-parser.c (c_parser_omp_clause_name): Handle "nohost".
+       (c_parser_oacc_all_clauses): Handle PRAGMA_OACC_CLAUSE_NOHOST.
+       (c_parser_oacc_routine, c_finish_oacc_routine): Update.
+       * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_NOHOST.
+
 2018-10-16  Chung-Lin Tang  <cltang@codesourcery.com>
 
        * c-typeck.c (handle_omp_array_sections_1): Add 'bool &non_contiguous'
index b745e607497ff775f515aefa55b9bb8014072d33..60e4ed5b63b3ba43544711ed5c9ae90993ee1107 100644 (file)
@@ -11749,6 +11749,8 @@ c_parser_omp_clause_name (c_parser *parser)
            result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
          else if (!strcmp ("nowait", p))
            result = PRAGMA_OMP_CLAUSE_NOWAIT;
+         else if (!strcmp ("nohost", p))
+           result = PRAGMA_OACC_CLAUSE_NOHOST;
          else if (!strcmp ("num_gangs", p))
            result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
          else if (!strcmp ("num_tasks", p))
@@ -14920,6 +14922,11 @@ c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
          clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
          c_name = "link";
          break;
+       case PRAGMA_OACC_CLAUSE_NOHOST:
+         clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
+                                                clauses);
+         c_name = "nohost";
+         break;
        case PRAGMA_OACC_CLAUSE_NUM_GANGS:
          clauses = c_parser_oacc_single_int_clause (parser,
                                                     OMP_CLAUSE_NUM_GANGS,
@@ -15767,7 +15774,8 @@ c_parser_oacc_kernels_parallel (location_t loc, c_parser *parser,
        ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)                \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)              \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)              \
-       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)                 \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
 
 /* Parse an OpenACC routine directive.  For named directives, we apply
    immediately to the named function.  For unnamed ones we then parse
@@ -15920,7 +15928,7 @@ c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
   /* Add an "omp declare target" attribute.  */
   DECL_ATTRIBUTES (fndecl)
     = tree_cons (get_identifier ("omp declare target"),
-                NULL_TREE, DECL_ATTRIBUTES (fndecl));
+                data->clauses, DECL_ATTRIBUTES (fndecl));
 
   /* Remember that we've used this "#pragma acc routine".  */
   data->fndecl_seen = true;
index 0146f06ffcbe2468b0ee809566da57cf8b674058..481b55b065b950c690cdbce44e835f2a2da634ff 100644 (file)
@@ -14729,6 +14729,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
        case OMP_CLAUSE_GANG:
        case OMP_CLAUSE_WORKER:
        case OMP_CLAUSE_VECTOR:
+       case OMP_CLAUSE_NOHOST:
        case OMP_CLAUSE_TILE:
        case OMP_CLAUSE_IF_PRESENT:
        case OMP_CLAUSE_FINALIZE:
index a01ffb4c7302a8479e73bd9bf7302ba6aba4a16a..f9ba662d4aa69a71b07fe21d0956176d61583a24 100644 (file)
@@ -1,3 +1,12 @@
+2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * parser.c (cp_parser_omp_clause_name): Handle "nohost".
+       (cp_parser_oacc_all_clauses): Handle PRAGMA_OACC_CLAUSE_NOHOST,
+       (cp_parser_oacc_routine, cp_finalize_oacc_routine): Update.
+       * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_NOHOST.
+       * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_NOHOST.
+
 2018-10-16  Chung-Lin Tang  <cltang@codesourcery.com>
 
        * semantics.c (handle_omp_array_sections_1): Add 'bool &non_contiguous'
index ed90aa2f5cd8168da2fb35fce8efe457e22e2572..418be26be4b6a1314f9524e786e8f218082bb503 100644 (file)
@@ -32285,6 +32285,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
        case 'n':
          if (!strcmp ("nogroup", p))
            result = PRAGMA_OMP_CLAUSE_NOGROUP;
+         else if (!strcmp ("nohost", p))
+           result = PRAGMA_OACC_CLAUSE_NOHOST;
          else if (!strcmp ("nontemporal", p))
            result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
          else if (!strcmp ("notinbranch", p))
@@ -35126,6 +35128,11 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
          c_name = "link";
          break;
+       case PRAGMA_OACC_CLAUSE_NOHOST:
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
+                                                 clauses);
+         c_name = "nohost";
+         break;
        case PRAGMA_OACC_CLAUSE_NUM_GANGS:
          code = OMP_CLAUSE_NUM_GANGS;
          c_name = "num_gangs";
@@ -40129,8 +40136,8 @@ cp_parser_omp_taskloop (cp_parser *parser, cp_token *pragma_tok,
        ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)                \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)              \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)              \
-       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ))
-
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)                 \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
 
 /* Parse the OpenACC routine pragma.  This has an optional '( name )'
    component, which must resolve to a declared namespace-scope
@@ -40347,7 +40354,7 @@ cp_finalize_oacc_routine (cp_parser *parser, tree fndecl, bool is_defn)
       /* Add an "omp declare target" attribute.  */
       DECL_ATTRIBUTES (fndecl)
        = tree_cons (get_identifier ("omp declare target"),
-                    NULL_TREE, DECL_ATTRIBUTES (fndecl));
+                    parser->oacc_routine->clauses, DECL_ATTRIBUTES (fndecl));
 
       /* Don't unset parser->oacc_routine here: we may still need it to
         diagnose wrong usage.  But, remember that we've used this "#pragma acc
index e682b6d51be3608dea7b3a9a4d7c54c8158b8873..85f54ee15d96fae8f6b514e6011fd32ba183293d 100644 (file)
@@ -16413,6 +16413,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
        case OMP_CLAUSE_IF_PRESENT:
        case OMP_CLAUSE_FINALIZE:
          break;
+       case OMP_CLAUSE_NOHOST:
        default:
          gcc_unreachable ();
        }
index 0282f86fde9136af560af63fc72954ff0e92c1c5..15519e773e38b535047764f98783444e3cd2602e 100644 (file)
@@ -7643,6 +7643,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
        case OMP_CLAUSE_SEQ:
        case OMP_CLAUSE_IF_PRESENT:
        case OMP_CLAUSE_FINALIZE:
+       case OMP_CLAUSE_NOHOST:
          break;
 
        case OMP_CLAUSE_TILE:
index 86ed18bdad13b18772a40e3f5cf3e2a23eb4536e..933e32e68294358c616ac738749fcc224126f69a 100644 (file)
@@ -1,3 +1,16 @@
+2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * gfortran.h (gfc_omp_clauses): Add nohost members.
+       * openmp.c (omp_mask2): Add OMP_CLAUSE_NOHOST.
+       (gfc_match_omp_clauses): Handle OMP_CLAUSE_NOHOST.
+       (gfc_match_oacc_routine): Set oacc_function_nohost when appropriate.
+       * gfortran.h (symbol_attribute): Add oacc_function_nohost member.
+       * trans-openmp.c (gfc_add_omp_offload_attributes): Use it to decide
+       whether to generate an OMP_CLAUSE_NOHOST clause.
+       (gfc_trans_omp_clauses_1): Unreachable code to generate an
+       OMP_CLAUSE_NOHOST clause.
+
 2018-12-14  Julian Brown  <julian@codesourcery.com>
 
        * gfortran.h (gfc_omp_map_op): Add OMP_MAP_ATTACH, OMP_MAP_DETACH.
index 7e039e50f6c461b11f85693fe0bc4ff687a24bad..5cd16e37fabc1c2d0416d21d42b728e182f494e2 100644 (file)
@@ -916,6 +916,7 @@ typedef struct
 
   /* OpenACC 'routine' directive's level of parallelism.  */
   ENUM_BITFIELD (oacc_routine_lop) oacc_routine_lop:3;
+  unsigned oacc_function_nohost:1;
 
   /* Attributes set by compiler extensions (!GCC$ ATTRIBUTES).  */
   unsigned ext_attr:EXT_ATTR_NUM;
@@ -1360,7 +1361,7 @@ typedef struct gfc_omp_clauses
   gfc_expr_list *tile_list;
   unsigned async:1, gang:1, worker:1, vector:1, seq:1, independent:1;
   unsigned par_auto:1, gang_static:1;
-  unsigned if_present:1, finalize:1;
+  unsigned if_present:1, finalize:1, nohost:1;
   locus loc;
 
 }
index b08593a2317c95718f0b612562806b77356b9e5a..bfceb4010e6434e702983b951587b15a7edc29e5 100644 (file)
@@ -815,6 +815,7 @@ enum omp_mask2
   OMP_CLAUSE_FINALIZE,
   OMP_CLAUSE_ATTACH,
   OMP_CLAUSE_DETACH,
+  OMP_CLAUSE_NOHOST,
   /* This must come last.  */
   OMP_MASK2_LAST
 };
@@ -1464,6 +1465,13 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
              c->nogroup = needs_space = true;
              continue;
            }
+         if ((mask & OMP_CLAUSE_NOHOST)
+             && !c->nohost
+             && gfc_match ("nohost") == MATCH_YES)
+           {
+             c->nohost = true;
+             continue;
+           }
          if ((mask & OMP_CLAUSE_NOTINBRANCH)
              && !c->notinbranch
              && !c->inbranch
@@ -2003,7 +2011,8 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
   omp_mask (OMP_CLAUSE_ASYNC)
 #define OACC_ROUTINE_CLAUSES \
   (omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR        \
-   | OMP_CLAUSE_SEQ)
+   | OMP_CLAUSE_SEQ                                                          \
+   | OMP_CLAUSE_NOHOST)
 
 
 static match
@@ -2445,6 +2454,8 @@ gfc_match_oacc_routine (void)
                                       &old_loc))
        goto cleanup;
       gfc_current_ns->proc_name->attr.oacc_routine_lop = lop;
+      gfc_current_ns->proc_name->attr.oacc_function_nohost
+       = c ? c->nohost : false;
     }
   else
     /* Something has gone wrong, possibly a syntax error.  */
index a0e1f6aeea564b8d1878a0bbc41ac6732286c617..bde3ca3907f8928d6e638411b1fdb7013476f2f8 100644 (file)
@@ -1404,8 +1404,12 @@ add_attributes_to_decl (symbol_attribute sym_attr, tree list)
     list = tree_cons (get_identifier ("omp declare target link"),
                      NULL_TREE, list);
   else if (sym_attr.omp_declare_target)
-    list = tree_cons (get_identifier ("omp declare target"),
-                     NULL_TREE, list);
+    {
+      tree c = NULL_TREE;
+      if (sym_attr.oacc_function_nohost)
+       c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_NOHOST);
+      list = tree_cons (get_identifier ("omp declare target"), c, list);
+    }
 
   if (sym_attr.oacc_routine_lop != OACC_ROUTINE_LOP_NONE)
     {
index 0fe426a4edba756829dd9b015345628151815757..6c30f0620ceb82434f896bda701b5c594190e57b 100644 (file)
@@ -1315,7 +1315,6 @@ gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
     }
 }
 
-
 static inline tree
 gfc_trans_add_clause (tree node, tree tail)
 {
@@ -3088,6 +3087,13 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
          OMP_CLAUSE_GANG_STATIC_EXPR (c) = arg;
        }
     }
+  if (clauses->nohost)
+    {
+      c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOHOST);
+      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
+      //TODO
+      gcc_unreachable();
+    }
 
   return nreverse (omp_clauses);
 }
index dc4531bc2d3064b59a7bf3df8bdb28cf58efab84..ed9ceb633456807703a959aad5e69c06f4eba2c7 100644 (file)
@@ -9461,6 +9461,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
          ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
          break;
 
+       case OMP_CLAUSE_NOHOST:
        default:
          gcc_unreachable ();
        }
@@ -10239,6 +10240,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
        case OMP_CLAUSE_FINALIZE:
          break;
 
+       case OMP_CLAUSE_NOHOST:
        default:
          gcc_unreachable ();
        }
index a6bf2200f37801359006230159f43e275be7e6b8..c105542d265d6adb2fabe73fd1e7462cf3685490 100644 (file)
@@ -1589,6 +1589,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
            install_var_local (decl, ctx);
          break;
 
+       case OMP_CLAUSE_NOHOST:
        case OMP_CLAUSE__CACHE_:
        default:
          gcc_unreachable ();
@@ -1765,6 +1766,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
        case OMP_CLAUSE_FINALIZE:
          break;
 
+       case OMP_CLAUSE_NOHOST:
        case OMP_CLAUSE__CACHE_:
        default:
          gcc_unreachable ();
index 97ae47b313589fd89ac2ece1e66c3c5de208a3d5..51cf7f81caf6595573f9e897646870af0b794d8e 100644 (file)
@@ -1490,6 +1490,25 @@ default_goacc_reduction (gcall *call)
   gsi_replace_with_seq (&gsi, seq, true);
 }
 
+/* Determine whether DECL should be discarded in this offload
+   compilation.  */
+
+static bool
+maybe_discard_oacc_function (tree decl)
+{
+  tree attr = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl));
+
+  if (!attr)
+    return false;
+
+  enum omp_clause_code kind = OMP_CLAUSE_NOHOST;
+
+  if (omp_find_clause (TREE_VALUE (attr), kind))
+    return true;
+
+  return false;
+}
+
 /* Main entry point for oacc transformations which run on the device
    compiler after LTO, so we know what the target device is at this
    point (including the host fallback).  */
@@ -1497,12 +1516,19 @@ default_goacc_reduction (gcall *call)
 static unsigned int
 execute_oacc_device_lower ()
 {
-  tree attrs = oacc_get_fn_attrib (current_function_decl);
-
-  if (!attrs)
+  tree attr = oacc_get_fn_attrib (current_function_decl);
+  if (!attr)
     /* Not an offloaded function.  */
     return 0;
 
+  if (maybe_discard_oacc_function (current_function_decl))
+    {
+      if (dump_file)
+       fprintf (dump_file, "Discarding function\n");
+      TREE_ASM_WRITTEN (current_function_decl) = 1;
+      return TODO_discard_function;
+    }
+
   /* Parse the default dim argument exactly once.  */
   if ((const void *)flag_openacc_dims != &flag_openacc_dims)
     {
@@ -1523,12 +1549,12 @@ execute_oacc_device_lower ()
   if (is_oacc_kernels && !is_oacc_kernels_parallelized)
     {
       oacc_set_fn_attrib (current_function_decl, NULL, NULL);
-      attrs = oacc_get_fn_attrib (current_function_decl);
+      attr = oacc_get_fn_attrib (current_function_decl);
     }
 
   /* Discover, partition and process the loops.  */
   oacc_loop *loops = oacc_loop_discovery ();
-  int fn_level = oacc_fn_attrib_level (attrs);
+  int fn_level = oacc_fn_attrib_level (attr);
 
   if (dump_file)
     {
@@ -1555,7 +1581,7 @@ execute_oacc_device_lower ()
     }
 
   int dims[GOMP_DIM_MAX];
-  oacc_validate_dims (current_function_decl, attrs, dims, fn_level, used_mask);
+  oacc_validate_dims (current_function_decl, attr, dims, fn_level, used_mask);
 
   if (dump_file)
     {
index 7e5117da871f494d1dc23d30f25a0d9f9a15dcf5..2a0d2f4615800213f9df4fcab918c8a50dd0f6fa 100644 (file)
@@ -1,3 +1,13 @@
+2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * c-c++-common/goacc/classify-routine.c: Adjust test.
+       * c-c++-common/goacc/routine-1.c: Likewise.
+       * c-c++-common/goacc/routine-2.c: Likewise.
+       * c-c++-common/goacc/routine-nohost-1.c: New test.
+       * g++.dg/goacc/routine-2.C: Adjust test.
+       * gfortran.dg/goacc/pr72741.f90: New test.
+
 2019-02-05  Julian Brown  <julian@codesourcery.com>
 
        * c-c++-common/goacc/deep-copy-multidim.c: Add test.
index a723d2cdf513b6a3c3e808cc7d1caf467ba1cd5b..0b9ba6ea69fc31f1313372bb9fd7118dc0b6920d 100644 (file)
@@ -22,10 +22,10 @@ void ROUTINE ()
 }
 
 /* Check the offloaded function's attributes.
-   { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(omp declare target, oacc function \\(0 1, 1 0, 1 0\\)\\)\\)" 1 "ompexp" } } */
+   { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(omp declare target \\(worker\\), oacc function \\(0 1, 1 0, 1 0\\)\\)\\)" 1 "ompexp" } } */
 
 /* Check the offloaded function's classification and compute dimensions (will
    always be 1 x 1 x 1 for non-offloading compilation).
    { dg-final { scan-tree-dump-times "(?n)Function is OpenACC routine level 1" 1 "oaccdevlow" } }
    { dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
-   { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(0 1, 1 1, 1 1\\), omp declare target, oacc function \\(0 1, 1 0, 1 0\\)\\)\\)" 1 "oaccdevlow" } } */
+   { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(0 1, 1 1, 1 1\\), omp declare target \\(worker\\), oacc function \\(0 1, 1 0, 1 0\\)\\)\\)" 1 "oaccdevlow" } } */
index a75692246b64c7fdd6a79cc33c409cddc21a0a3c..db1322e11ca8676b25e2a963cd360c7e03611e7b 100644 (file)
@@ -1,3 +1,4 @@
+/* Test valid use of clauses with routine.  */
 
 #pragma acc routine gang
 void gang (void)
@@ -19,6 +20,11 @@ void seq (void)
 {
 }
 
+#pragma acc routine nohost
+void nohost (void)
+{
+}
+
 int main ()
 {
 #pragma acc kernels num_gangs (32) num_workers (32) vector_length (32)
@@ -27,6 +33,7 @@ int main ()
     worker ();
     vector ();
     seq ();
+    nohost ();
   }
 
 #pragma acc parallel num_gangs (32) num_workers (32) vector_length (32)
@@ -35,6 +42,7 @@ int main ()
     worker ();
     vector ();
     seq ();
+    nohost ();
   }
 
   return 0;
index fc5eb11bb54d0f03c96ce1bcd050f8ea3b9072cd..d1ea61e33105afe07654f65e160d477e9a3d38b7 100644 (file)
@@ -1,19 +1,19 @@
-#pragma acc routine gang worker /* { dg-error "multiple loop axes" } */
+#pragma acc routine gang worker /* { dg-error "conflicting level" } */
 void gang (void)
 {
 }
 
-#pragma acc routine worker vector /* { dg-error "multiple loop axes" } */
+#pragma acc routine worker vector /* { dg-error "conflicting level" } */
 void worker (void)
 {
 }
 
-#pragma acc routine vector seq /* { dg-error "multiple loop axes" } */
+#pragma acc routine vector seq /* { dg-error "conflicting level" } */
 void vector (void)
 {
 }
 
-#pragma acc routine seq gang /* { dg-error "multiple loop axes" } */
+#pragma acc routine seq gang /* { dg-error "conflicting level" } */
 void seq (void)
 {
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/routine-nohost-1.c b/gcc/testsuite/c-c++-common/goacc/routine-nohost-1.c
new file mode 100644 (file)
index 0000000..9baa56c
--- /dev/null
@@ -0,0 +1,28 @@
+/* Test the nohost clause for OpenACC routine directive.  Exercising different
+   variants for declaring routines.  */
+
+/* { dg-additional-options "-fdump-tree-oaccdevlow" } */
+
+#pragma acc routine nohost
+int THREE(void)
+{
+  return 3;
+}
+
+#pragma acc routine nohost
+extern void NOTHING(void);
+
+void NOTHING(void)
+{
+}
+
+extern float ADD(float, float);
+
+#pragma acc routine (ADD) nohost
+
+float ADD(float x, float y)
+{
+  return x + y;
+}
+
+/* { dg-final { scan-tree-dump-times "Discarding function" 3 "oaccdevlow" } } */
index ea7c9bf73939f44ef2d4bbf2f6d48d37121e8bff..c82493321cb67cf75ef6c461a35a041e7f73adc2 100644 (file)
@@ -2,15 +2,8 @@
 
 template <typename T>
 extern T one_d();
-#pragma acc routine (one_d) /* { dg-error "names a set of overloads" } */
+#pragma acc routine (one_d) nohost /* { dg-error "names a set of overloads" } */
 
-template <typename T>
-T
-one()
-{
-  return 1;
-}
-#pragma acc routine (one) /* { dg-error "names a set of overloads" } */
 
 int incr (int);
 float incr (float);
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr72741.f90 b/gcc/testsuite/gfortran.dg/goacc/pr72741.f90
new file mode 100644 (file)
index 0000000..b295a4f
--- /dev/null
@@ -0,0 +1,30 @@
+SUBROUTINE v_1
+  !$ACC ROUTINE VECTOR WORKER ! { dg-error "Multiple loop axes" }
+END SUBROUTINE v_1
+
+SUBROUTINE sub_1
+  IMPLICIT NONE
+  EXTERNAL :: g_1
+  !$ACC ROUTINE (g_1) GANG WORKER ! { dg-error "Multiple loop axes" }
+  !$ACC ROUTINE (ABORT) SEQ VECTOR ! { dg-error "Multiple loop axes" "" { xfail *-*-* } }
+! { dg-bogus "invalid function name abort" "" { xfail *-*-* } .-1 }
+
+  CALL v_1
+  CALL g_1
+  CALL ABORT
+END SUBROUTINE sub_1
+
+MODULE m_w_1
+  IMPLICIT NONE
+  EXTERNAL :: w_1
+  !$ACC ROUTINE (w_1) WORKER SEQ ! { dg-error "Multiple loop axes" }
+  !$ACC ROUTINE (ABORT) VECTOR GANG ! { dg-error "Multiple loop axes" "" { xfail *-*-* } }
+! { dg-bogus "invalid function name abort" "" { xfail *-*-* } .-1 }
+
+CONTAINS
+  SUBROUTINE sub_2
+    CALL v_1
+    CALL w_1
+    CALL ABORT
+  END SUBROUTINE sub_2
+END MODULE m_w_1
index 552196b1b4264b167dc87bd8f545002126f31da6..5bcecc160bc0d66b4f3adc7543f4010874e9d951 100644 (file)
@@ -461,6 +461,9 @@ enum omp_clause_code {
   /* OpenACC clause: vector_length (integer-expression).  */
   OMP_CLAUSE_VECTOR_LENGTH,
 
+  /* OpenACC clause: nohost.  */
+  OMP_CLAUSE_NOHOST,
+
   /* OpenACC clause: tile ( size-expr-list ).  */
   OMP_CLAUSE_TILE,
 
index 3fe23cc2b22a00ff629c9da0a13456bbccf14f4e..76071cc3c201e36788dfe6cb46fcb302ed3a87f8 100644 (file)
@@ -1350,6 +1350,8 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
        case OMP_CLAUSE_FINALIZE:
          break;
 
+         /* OpenACC nohost clause is not yet handled here.  */
+       case OMP_CLAUSE_NOHOST:
          /* The following clause belongs to the OpenACC cache directive, which
             is discarded during gimplification.  */
        case OMP_CLAUSE__CACHE_:
@@ -2077,6 +2079,8 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
        case OMP_CLAUSE_FINALIZE:
          break;
 
+         /* OpenACC nohost clauses is not yet handled here.  */
+       case OMP_CLAUSE_NOHOST:
          /* The following clause belongs to the OpenACC cache directive, which
             is discarded during gimplification.  */
        case OMP_CLAUSE__CACHE_:
index 589972ed90d62159a68e1c22d2506dd8be56effd..415b523a0f416c3ebd7f7a39861907be5a46a2cd 100644 (file)
@@ -1200,6 +1200,9 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
                         spc, flags, false);
       pp_right_paren (pp);
       break;
+    case OMP_CLAUSE_NOHOST:
+      pp_string (pp, "nohost");
+      break;
 
     case OMP_CLAUSE__GRIDDIM_:
       pp_string (pp, "_griddim_(");
index 73102c4e75bd3bf21815023d93bbef698a724d0d..7c891dcbf9148e1fbb193c674b20eb103c968141 100644 (file)
@@ -347,6 +347,7 @@ unsigned const char omp_clause_num_ops[] =
   1, /* OMP_CLAUSE_NUM_GANGS  */
   1, /* OMP_CLAUSE_NUM_WORKERS  */
   1, /* OMP_CLAUSE_VECTOR_LENGTH  */
+  0, /* OMP_CLAUSE_NOHOST  */
   3, /* OMP_CLAUSE_TILE  */
   2, /* OMP_CLAUSE__GRIDDIM_  */
   0, /* OMP_CLAUSE_IF_PRESENT */
@@ -424,6 +425,7 @@ const char * const omp_clause_code_name[] =
   "num_gangs",
   "num_workers",
   "vector_length",
+  "nohost",
   "tile",
   "_griddim_",
   "if_present",
@@ -12323,6 +12325,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
        case OMP_CLAUSE_DEFAULTMAP:
        case OMP_CLAUSE_AUTO:
        case OMP_CLAUSE_SEQ:
+       case OMP_CLAUSE_NOHOST:
        case OMP_CLAUSE_TILE:
        case OMP_CLAUSE__SIMT_:
        case OMP_CLAUSE_IF_PRESENT:
index 990199a30bf8256fb9e11b219b2f2c1753a2a840..f5c8a47a9c55a9836ae99aa9edfda00f3a3f138a 100644 (file)
@@ -1,3 +1,12 @@
+2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       * testsuite/libgomp.oacc-c-c++-common/routine-3.c: New test.
+       * testsuite/libgomp.oacc-c-c++-common/routine-nohost-1.c: New test.
+       * testsuite/libgomp.oacc-c-c++-common/routine-bind-nohost-1.c:
+       Update test.
+       * testsuite/libgomp.oacc-fortran/routine-6.f90: Likewise.
+
 2018-10-16  Chung-Lin Tang  <cltang@codesourcery.com>
 
        * testsuite/libgomp.oacc-c-c++-common/da-1.c: New test.
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-3.c
new file mode 100644 (file)
index 0000000..2cdd6bf
--- /dev/null
@@ -0,0 +1,33 @@
+/* At -O0, we do get the expected "undefined reference to `foo'" link-time
+   error message (but the check needs to be done differently; compare to
+   routine-nohost-1.c), but for -O2 we don't; presumably because the function
+   gets inlined.
+   { dg-xfail-if "TODO" { *-*-* } { "-O0" } { "" } } */
+
+#include <stdlib.h>
+
+#pragma acc routine nohost
+int
+foo (int n)
+{
+  if (n == 0 || n == 1)
+    return 1;
+
+  return n * n;
+}
+
+int
+main()
+{
+  int a, n = 10;
+
+#pragma acc parallel copy (a, n)
+  {
+    a = foo (n);
+  }
+
+  if (a != n * n)
+    abort ();
+
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-nohost-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-nohost-1.c
new file mode 100644 (file)
index 0000000..365af93
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do link } */
+
+extern int three (void);
+
+#pragma acc routine (three) nohost
+__attribute__((noinline))
+int three(void)
+{
+  return 3;
+}
+
+int main(void)
+{
+  return (three() == 3) ? 0 : 1;
+}
+
+/* Expecting link to fail; "undefined reference to `three'" (or similar).
+   { dg-excess-errors "" } */
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/routine-6.f90 b/libgomp/testsuite/libgomp.oacc-fortran/routine-6.f90
new file mode 100644 (file)
index 0000000..1bae09c
--- /dev/null
@@ -0,0 +1,28 @@
+! { dg-do run }
+! { dg-xfail-if "TODO" { *-*-* } }
+
+program main
+  integer :: a, n
+  
+  n = 10
+
+  !$acc parallel copy (a, n)
+     a = foo (n)
+  !$acc end parallel 
+
+  if (a .ne. n * n) call abort
+
+contains
+
+function foo (n) result (rc)
+  !$acc routine nohost
+
+  integer, intent (in) :: n
+  integer :: rc
+
+  rc = n * n
+
+end function
+
+end program main
+