]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add OpenACC 2.6 `no_create' clause support
authorMaciej W. Rozycki <macro@codesourcery.com>
Thu, 20 Dec 2018 14:10:19 +0000 (14:10 +0000)
committerThomas Schwinge <thomas@codesourcery.com>
Tue, 3 Mar 2020 11:16:12 +0000 (12:16 +0100)
The clause makes any device code use the local memory address for each
of the variables specified unless the given variable is already present
on the current device.

2018-12-19  Julian Brown  <julian@codesourcery.com>
            Maciej W. Rozycki  <macro@codesourcery.com>

gcc/
* omp-low.c (lower_omp_target): Support GOMP_MAP_NO_ALLOC.
* tree-pretty-print.c (dump_omp_clause): Likewise.

gcc/c-family/
* c-pragma.h (pragma_omp_clause): Add
PRAGMA_OACC_CLAUSE_NO_CREATE.

gcc/c/
* c-parser.c (c_parser_omp_clause_name): Support no_create.
(c_parser_oacc_data_clause): Likewise.
(c_parser_oacc_all_clauses): Likewise.
(OACC_DATA_CLAUSE_MASK, OACC_KERNELS_CLAUSE_MASK)
(OACC_PARALLEL_CLAUSE_MASK, OACC_SERIAL_CLAUSE_MASK): Add
PRAGMA_OACC_CLAUSE_NO_CREATE.
* c-typeck.c (handle_omp_array_sections): Support
GOMP_MAP_NO_ALLOC.

gcc/cp/
* parser.c (cp_parser_omp_clause_name): Support no_create.
(cp_parser_oacc_data_clause): Likewise.
(cp_parser_oacc_all_clauses): Likewise.
(OACC_DATA_CLAUSE_MASK, OACC_KERNELS_CLAUSE_MASK)
(OACC_PARALLEL_CLAUSE_MASK, OACC_SERIAL_CLAUSE_MASK): Add
PRAGMA_OACC_CLAUSE_NO_CREATE.
* semantics.c (handle_omp_array_sections): Support no_create.

gcc/fortran/
* gfortran.h (gfc_omp_map_op): Add OMP_MAP_NO_ALLOC.
* openmp.c (omp_mask2): Add OMP_CLAUSE_NO_CREATE.
(gfc_match_omp_clauses): Support no_create.
(OACC_PARALLEL_CLAUSES, OACC_KERNELS_CLAUSES)
(OACC_SERIAL_CLAUSES, OACC_DATA_CLAUSES): Add
OMP_CLAUSE_NO_CREATE.
* trans-openmp.c (gfc_trans_omp_clauses_1): Support
OMP_MAP_NO_ALLOC.

include/
* gomp-constants.h (gomp_map_kind): Support GOMP_MAP_NO_ALLOC.

libgomp/
* target.c (gomp_map_vars_async): Support GOMP_MAP_NO_ALLOC.

* testsuite/libgomp.oacc-c-c++-common/nocreate-1.c: New test.
* testsuite/libgomp.oacc-c-c++-common/nocreate-2.c: New test.
* testsuite/libgomp.oacc-c-c++-common/nocreate-3.c: New test.
* testsuite/libgomp.oacc-c-c++-common/nocreate-4.c: New test.
* testsuite/libgomp.oacc-fortran/nocreate-1.f90: New test.
* testsuite/libgomp.oacc-fortran/nocreate-2.f90: New test.

(cherry picked from openacc-gcc-9-branch commit
8e74c2ec2b90819c995444370e742864a685209f)

25 files changed:
gcc/ChangeLog.omp
gcc/c-family/ChangeLog.omp
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/semantics.c
gcc/fortran/ChangeLog.omp
gcc/fortran/gfortran.h
gcc/fortran/openmp.c
gcc/fortran/trans-openmp.c
gcc/omp-low.c
gcc/tree-pretty-print.c
include/ChangeLog.omp
include/gomp-constants.h
libgomp/ChangeLog.omp
libgomp/target.c
libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-4.c [new file with mode: 0644]
libgomp/testsuite/libgomp.oacc-fortran/nocreate-1.f90 [new file with mode: 0644]
libgomp/testsuite/libgomp.oacc-fortran/nocreate-2.f90 [new file with mode: 0644]

index 43370cf90f6259ccd88054574419d0e3739f512b..8477373c1c6f33ea286d0029ed169e2f7764988b 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-19  Julian Brown  <julian@codesourcery.com>
+            Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * omp-low.c (lower_omp_target): Support GOMP_MAP_NO_ALLOC.
+       * tree-pretty-print.c (dump_omp_clause): Likewise.
+
 2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * gimple.h (gf_mask): Add GF_OMP_TARGET_KIND_OACC_SERIAL
index f0ea8c5ce3f96376b24f01ede47c3cae13bf3fde..40b8e3b9dff21fec787dc4727e9e626bdc26b309 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-19  Julian Brown  <julian@codesourcery.com>
+            Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * c-pragma.h (pragma_omp_clause): Add
+       PRAGMA_OACC_CLAUSE_NO_CREATE.
+
 2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * c-pragma.h (pragma_kind): Add PRAGMA_OACC_SERIAL enumeration
index d9a75fc80ca63dab10874005b573ca90fe954746..a6bae05995ff054c787dbcc38e4d6e0d1b4182bb 100644 (file)
@@ -150,6 +150,7 @@ enum pragma_omp_clause {
   PRAGMA_OACC_CLAUSE_GANG,
   PRAGMA_OACC_CLAUSE_HOST,
   PRAGMA_OACC_CLAUSE_INDEPENDENT,
+  PRAGMA_OACC_CLAUSE_NO_CREATE,
   PRAGMA_OACC_CLAUSE_NOHOST,
   PRAGMA_OACC_CLAUSE_NUM_GANGS,
   PRAGMA_OACC_CLAUSE_NUM_WORKERS,
index 68a1d77c0105032313e51c9ea133862a0c848f02..c9341355d1a926649f9eaf9e25e906394f767d58 100644 (file)
@@ -1,3 +1,15 @@
+2018-12-19  Julian Brown  <julian@codesourcery.com>
+            Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * c-parser.c (c_parser_omp_clause_name): Support no_create.
+       (c_parser_oacc_data_clause): Likewise.
+       (c_parser_oacc_all_clauses): Likewise.
+       (OACC_DATA_CLAUSE_MASK, OACC_KERNELS_CLAUSE_MASK)
+       (OACC_PARALLEL_CLAUSE_MASK, OACC_SERIAL_CLAUSE_MASK): Add
+       PRAGMA_OACC_CLAUSE_NO_CREATE.
+       * c-typeck.c (handle_omp_array_sections): Support
+       GOMP_MAP_NO_ALLOC.
+
 2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * c-parser.c (OACC_SERIAL_CLAUSE_MASK): New macro.
index 2baddd0e4648b49550a717486c96fd0deea12778..54fc6b32aa80a5d82b6a02f946eab5c0a6e5d467 100644 (file)
@@ -11741,7 +11741,9 @@ c_parser_omp_clause_name (c_parser *parser)
            result = PRAGMA_OMP_CLAUSE_MERGEABLE;
          break;
        case 'n':
-         if (!strcmp ("nogroup", p))
+         if (!strcmp ("no_create", p))
+           result = PRAGMA_OACC_CLAUSE_NO_CREATE;
+         else if (!strcmp ("nogroup", p))
            result = PRAGMA_OMP_CLAUSE_NOGROUP;
          else if (!strcmp ("nontemporal", p))
            result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
@@ -12210,7 +12212,10 @@ c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
    create ( variable-list )
    delete ( variable-list )
    detach ( variable-list )
-   present ( variable-list ) */
+   present ( variable-list )
+
+   OpenACC 2.6:
+   no_create ( variable-list ) */
 
 static tree
 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
@@ -12252,6 +12257,9 @@ c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
     case PRAGMA_OACC_CLAUSE_LINK:
       kind = GOMP_MAP_LINK;
       break;
+    case PRAGMA_OACC_CLAUSE_NO_CREATE:
+      kind = GOMP_MAP_NO_ALLOC;
+      break;
     case PRAGMA_OACC_CLAUSE_PRESENT:
       kind = GOMP_MAP_FORCE_PRESENT;
       break;
@@ -14930,6 +14938,10 @@ 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_NO_CREATE:
+         clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
+         c_name = "no_create";
+         break;
        case PRAGMA_OACC_CLAUSE_NOHOST:
          clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
                                                 clauses);
@@ -15373,6 +15385,7 @@ c_parser_oacc_cache (location_t loc, c_parser *parser)
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)              \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
 
 static tree
@@ -15710,6 +15723,7 @@ c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)             \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)         \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)             \
@@ -15726,6 +15740,7 @@ c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)             \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)             \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)        \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)           \
@@ -15745,6 +15760,7 @@ c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)             \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)             \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)        \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)             \
index a4a78cf8f36b539a35b1a14dcabeacba167453a9..2acd12d849f71b0c363401a1dcb47a32d8e64421 100644 (file)
@@ -13429,6 +13429,7 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort)
        switch (OMP_CLAUSE_MAP_KIND (c))
          {
          case GOMP_MAP_ALLOC:
+         case GOMP_MAP_NO_ALLOC:
          case GOMP_MAP_TO:
          case GOMP_MAP_FROM:
          case GOMP_MAP_TOFROM:
index 10484632cca772b7f7a1821eb12769fafa1c279d..9d16175e1f27755c7b6ac1440899b3864c0bdc83 100644 (file)
@@ -1,3 +1,14 @@
+2018-12-19  Julian Brown  <julian@codesourcery.com>
+            Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * parser.c (cp_parser_omp_clause_name): Support no_create.
+       (cp_parser_oacc_data_clause): Likewise.
+       (cp_parser_oacc_all_clauses): Likewise.
+       (OACC_DATA_CLAUSE_MASK, OACC_KERNELS_CLAUSE_MASK)
+       (OACC_PARALLEL_CLAUSE_MASK, OACC_SERIAL_CLAUSE_MASK): Add
+       PRAGMA_OACC_CLAUSE_NO_CREATE.
+       * semantics.c (handle_omp_array_sections): Support no_create.
+
 2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * constexpr.c (potential_constant_expression_1): Handle
index bd278ee0cbd9460faf772567341d4699d153c7cf..143ad7144fa6f5df62d39b57cd6e9f37f88799d4 100644 (file)
@@ -32283,7 +32283,9 @@ cp_parser_omp_clause_name (cp_parser *parser)
            result = PRAGMA_OMP_CLAUSE_MERGEABLE;
          break;
        case 'n':
-         if (!strcmp ("nogroup", p))
+         if (!strcmp ("no_create", p))
+           result = PRAGMA_OACC_CLAUSE_NO_CREATE;
+         else if (!strcmp ("nogroup", p))
            result = PRAGMA_OMP_CLAUSE_NOGROUP;
          else if (!strcmp ("nohost", p))
            result = PRAGMA_OACC_CLAUSE_NOHOST;
@@ -32661,7 +32663,10 @@ cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list,
    create ( variable-list )
    delete ( variable-list )
    detach ( variable-list )
-   present ( variable-list ) */
+   present ( variable-list )
+
+   OpenACC 2.6:
+   no_create ( variable-list ) */
 
 static tree
 cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind,
@@ -32703,6 +32708,9 @@ cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind,
     case PRAGMA_OACC_CLAUSE_LINK:
       kind = GOMP_MAP_LINK;
       break;
+    case PRAGMA_OACC_CLAUSE_NO_CREATE:
+      kind = GOMP_MAP_NO_ALLOC;
+      break;
     case PRAGMA_OACC_CLAUSE_PRESENT:
       kind = GOMP_MAP_FORCE_PRESENT;
       break;
@@ -35130,6 +35138,10 @@ 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_NO_CREATE:
+         clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
+         c_name = "no_create";
+         break;
        case PRAGMA_OACC_CLAUSE_NOHOST:
          clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
                                                  clauses);
@@ -38743,6 +38755,7 @@ cp_parser_oacc_cache (cp_parser *parser, cp_token *pragma_tok)
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH)              \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) )
 
 static tree
@@ -39069,6 +39082,7 @@ cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)             \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)         \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)             \
@@ -39086,6 +39100,7 @@ cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)        \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)         \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)             \
@@ -39104,6 +39119,7 @@ cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)             \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)           \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)             \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)        \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)             \
index 12ab7ceed9d24e77f76a2b93e41e1533b70842f6..657f23c6a582a06dbfc3ca5bc273caeae71345f6 100644 (file)
@@ -5238,6 +5238,7 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort)
            switch (OMP_CLAUSE_MAP_KIND (c))
              {
              case GOMP_MAP_ALLOC:
+             case GOMP_MAP_NO_ALLOC:
              case GOMP_MAP_TO:
              case GOMP_MAP_FROM:
              case GOMP_MAP_TOFROM:
index 9e83b6228792f9b646be15eeeb9d11abcb20cf90..bb948709d8ac6a3005d278a3d44ac07d101c31f4 100644 (file)
@@ -1,3 +1,15 @@
+2018-12-19  Julian Brown  <julian@codesourcery.com>
+            Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * gfortran.h (gfc_omp_map_op): Add OMP_MAP_NO_ALLOC.
+       * openmp.c (omp_mask2): Add OMP_CLAUSE_NO_CREATE.
+       (gfc_match_omp_clauses): Support no_create.
+       (OACC_PARALLEL_CLAUSES, OACC_KERNELS_CLAUSES)
+       (OACC_SERIAL_CLAUSES, OACC_DATA_CLAUSES): Add
+       OMP_CLAUSE_NO_CREATE.
+       * trans-openmp.c (gfc_trans_omp_clauses_1): Support
+       OMP_MAP_NO_ALLOC.
+
 2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * gfortran.h (gfc_statement): Add ST_OACC_SERIAL_LOOP,
index b47b98133d5a7295c9841bf1dcbb89d636b4ef68..0c3eb1e29293690dc74a7721b91859c5ec960569 100644 (file)
@@ -1189,6 +1189,7 @@ enum gfc_omp_depend_op
 enum gfc_omp_map_op
 {
   OMP_MAP_ALLOC,
+  OMP_MAP_NO_ALLOC,
   OMP_MAP_ATTACH,
   OMP_MAP_TO,
   OMP_MAP_FROM,
index 82ac0fa8523a89f1354c94e09d2d71af8f7a4f14..679f99714b01032d832036547b4af3a75eb1463a 100644 (file)
@@ -797,6 +797,7 @@ enum omp_mask2
   OMP_CLAUSE_COPY,
   OMP_CLAUSE_COPYOUT,
   OMP_CLAUSE_CREATE,
+  OMP_CLAUSE_NO_CREATE,
   OMP_CLAUSE_PRESENT,
   OMP_CLAUSE_DEVICEPTR,
   OMP_CLAUSE_GANG,
@@ -1465,6 +1466,12 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
            }
          break;
        case 'n':
+         if ((mask & OMP_CLAUSE_NO_CREATE)
+             && gfc_match ("no_create ( ") == MATCH_YES
+             && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+                                          OMP_MAP_NO_ALLOC, true,
+                                          allow_derived))
+           continue;
          if ((mask & OMP_CLAUSE_NOGROUP)
              && !c->nogroup
              && gfc_match ("nogroup") == MATCH_YES)
@@ -1979,28 +1986,28 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS        \
    | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION \
    | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT                \
-   | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEVICEPTR           \
-   | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULT       \
-   | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
+   | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT           \
+   | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE      \
+   | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
 #define OACC_KERNELS_CLAUSES \
   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS        \
    | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR \
    | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT                \
-   | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEFAULT             \
-   | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
+   | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT           \
+   | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
 #define OACC_SERIAL_CLAUSES \
   (omp_mask (OMP_CLAUSE_ASYNC) | OMP_CLAUSE_WAIT                             \
    | OMP_CLAUSE_IF                                                           \
    | OMP_CLAUSE_REDUCTION                                                    \
    | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT                \
-   | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT                                  \
+   | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT           \
    | OMP_CLAUSE_DEVICEPTR                                                    \
    | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE                            \
    | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_ATTACH)
 #define OACC_DATA_CLAUSES \
   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR  | OMP_CLAUSE_COPY        \
    | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE                      \
-   | OMP_CLAUSE_PRESENT | OMP_CLAUSE_ATTACH)
+   | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_ATTACH)
 #define OACC_LOOP_CLAUSES \
   (omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER              \
    | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT             \
index ed132ac7fa6d8d43cbb825d9cd89720215f43050..f2d8997124b789a8f3fea951ad1ec00bf836edd3 100644 (file)
@@ -2491,6 +2491,9 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
                case OMP_MAP_ALLOC:
                  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALLOC);
                  break;
+               case OMP_MAP_NO_ALLOC:
+                 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_NO_ALLOC);
+                 break;
                case OMP_MAP_ATTACH:
                  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ATTACH);
                  break;
index 92d118a3c512ece55cb54ac1181703b7ef0f9e0e..7cdbfbb2ed40ccae4f419279d596601d5e334f2c 100644 (file)
@@ -9944,6 +9944,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
          case GOMP_MAP_STRUCT:
          case GOMP_MAP_ALWAYS_POINTER:
            break;
+         case GOMP_MAP_NO_ALLOC:
          case GOMP_MAP_FORCE_ALLOC:
          case GOMP_MAP_FORCE_TO:
          case GOMP_MAP_FORCE_FROM:
@@ -10431,6 +10432,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
                  switch (tkind)
                    {
                    case GOMP_MAP_ALLOC:
+                   case GOMP_MAP_NO_ALLOC:
                    case GOMP_MAP_TO:
                    case GOMP_MAP_FROM:
                    case GOMP_MAP_TOFROM:
index 5e1483f77cbee64d1f599f2393509c81112c3af8..d6171f09f0ea15c9d4a041404c8027b0ae8e097d 100644 (file)
@@ -765,6 +765,9 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
        case GOMP_MAP_POINTER:
          pp_string (pp, "alloc");
          break;
+       case GOMP_MAP_NO_ALLOC:
+         pp_string (pp, "no_alloc");
+         break;
        case GOMP_MAP_TO:
        case GOMP_MAP_TO_PSET:
          pp_string (pp, "to");
index e632fdb4ebf9fbe648f7df3c51a18ec4c9b2f0d3..bd8dba0544c6af3fd2a54bfb9be712e38aef0090 100644 (file)
@@ -1,3 +1,8 @@
+2018-12-19  Julian Brown  <julian@codesourcery.com>
+            Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * gomp-constants.h (gomp_map_kind): Support GOMP_MAP_NO_ALLOC.
+
 2018-12-21  Gergö Barany  <gergo@codesourcery.com>
 
        * gomp-constants.h (GOACC_FLAG_HOST_DATA_IF_PRESENT): New constant.
index 90b18091a13553daedcb719c994efd5848eab925..dae4eea66de2f2b858af04cdc5ac80fa78f4dee5 100644 (file)
@@ -80,6 +80,8 @@ enum gomp_map_kind
     GOMP_MAP_DEVICE_RESIDENT =         (GOMP_MAP_FLAG_SPECIAL_1 | 1),
     /* OpenACC link.  */
     GOMP_MAP_LINK =                    (GOMP_MAP_FLAG_SPECIAL_1 | 2),
+    /* Use device data if present, fall back to host address otherwise.  */
+    GOMP_MAP_NO_ALLOC =                        (GOMP_MAP_FLAG_SPECIAL_1 | 3),
     /* Allocate.  */
     GOMP_MAP_FIRSTPRIVATE =            (GOMP_MAP_FLAG_SPECIAL | 0),
     /* Similarly, but store the value in the pointer rather than
index c063ddab27eae05dd1063b62a0637d586710e028..6c1defe2011b793bce101af7538c247ba41369b0 100644 (file)
@@ -1,3 +1,15 @@
+2018-12-19  Julian Brown  <julian@codesourcery.com>
+            Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * target.c (gomp_map_vars_async): Support GOMP_MAP_NO_ALLOC.
+
+       * testsuite/libgomp.oacc-c-c++-common/nocreate-1.c: New test.
+       * testsuite/libgomp.oacc-c-c++-common/nocreate-2.c: New test.
+       * testsuite/libgomp.oacc-c-c++-common/nocreate-3.c: New test.
+       * testsuite/libgomp.oacc-c-c++-common/nocreate-4.c: New test.
+       * testsuite/libgomp.oacc-fortran/nocreate-1.f90: New test.
+       * testsuite/libgomp.oacc-fortran/nocreate-2.f90: New test.
+
 2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * testsuite/libgomp.oacc-c-c++-common/serial-dims.c: New test.
index 91d0f25cde57836e1903e1990fca4f600003cbae..62b8ee4759ee51220b146902d3c1999c1225cfeb 100644 (file)
@@ -1180,6 +1180,12 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep,
          has_firstprivate = true;
          continue;
        }
+      else if ((kind & typemask) == GOMP_MAP_NO_ALLOC)
+        {
+         tgt->list[i].key = NULL;
+         tgt->list[i].offset = 0;
+         continue;
+       }
       cur_node.host_start = (uintptr_t) hostaddrs[i];
       if (!GOMP_MAP_POINTER_P (kind & typemask)
           && (kind & typemask) != GOMP_MAP_ATTACH)
@@ -1468,6 +1474,53 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep,
                                       cbufp);
                  continue;
                }
+             case GOMP_MAP_NO_ALLOC:
+               {
+                 cur_node.host_start = (uintptr_t) hostaddrs[i];
+                 cur_node.host_end = cur_node.host_start + sizes[i];
+                 splay_tree_key n = splay_tree_lookup (mem_map, &cur_node);
+                 if (n != NULL)
+                   {
+                     tgt->list[i].key = n;
+                     tgt->list[i].offset = cur_node.host_start - n->host_start;
+                     tgt->list[i].length = n->host_end - n->host_start;
+                     tgt->list[i].copy_from = false;
+                     tgt->list[i].always_copy_from = false;
+                     tgt->list[i].do_detach = false;
+                     n->refcount++;
+                   }
+                 else
+                   {
+                     tgt->list[i].key = NULL;
+                     tgt->list[i].offset = OFFSET_INLINED;
+                     tgt->list[i].length = sizes[i];
+                     tgt->list[i].copy_from = false;
+                     tgt->list[i].always_copy_from = false;
+                     tgt->list[i].do_detach = false;
+                     if (i + 1 < mapnum)
+                       {
+                         int kind2 = get_kind (short_mapkind, kinds, i + 1);
+                         switch (kind2 & typemask)
+                           {
+                           case GOMP_MAP_ATTACH:
+                           case GOMP_MAP_POINTER:
+                             /* The data is not present but we have an attach
+                                or pointer clause next.  Skip over it.  */
+                             i++;
+                             tgt->list[i].key = NULL;
+                             tgt->list[i].offset = OFFSET_INLINED;
+                             tgt->list[i].length = sizes[i];
+                             tgt->list[i].copy_from = false;
+                             tgt->list[i].always_copy_from = false;
+                             tgt->list[i].do_detach = false;
+                             break;
+                           default:
+                             break;
+                           }
+                       }
+                   }
+                 continue;
+               }
              default:
                break;
              }
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-1.c
new file mode 100644 (file)
index 0000000..c7a1bd9
--- /dev/null
@@ -0,0 +1,40 @@
+/* Test no_create clause when data is present on the device.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <openacc.h>
+
+#define N 128
+
+int
+main (int argc, char *argv[])
+{
+  int *arr = (int *) malloc (N * sizeof (*arr));
+  int *devptr;
+
+  acc_copyin (arr, N * sizeof (*arr));
+
+  #pragma acc parallel no_create(arr[0:N]) copyout(devptr)
+  {
+    devptr = &arr[2];
+  }
+
+#if !ACC_MEM_SHARED
+  if (acc_hostptr (devptr) != (void *) &arr[2])
+    __builtin_abort ();
+#endif
+
+  acc_delete (arr, N * sizeof (*arr));
+
+#if ACC_MEM_SHARED
+  if (&arr[2] != devptr)
+    __builtin_abort ();
+#else
+  if (&arr[2] == devptr)
+    __builtin_abort ();
+#endif
+
+  free (arr);
+
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-2.c
new file mode 100644 (file)
index 0000000..2964a40
--- /dev/null
@@ -0,0 +1,28 @@
+/* Test no_create clause when data is not present on the device.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define N 128
+
+int
+main (int argc, char *argv[])
+{
+  int *arr = (int *) malloc (N * sizeof (*arr));
+  int *devptr;
+
+  #pragma acc data no_create(arr[0:N])
+  {
+    #pragma acc parallel copyout(devptr)
+    {
+      devptr = &arr[2];
+    }
+  }
+
+  if (devptr != &arr[2])
+    __builtin_abort ();
+
+  free (arr);
+
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-3.c
new file mode 100644 (file)
index 0000000..618af6e
--- /dev/null
@@ -0,0 +1,38 @@
+/* Test no_create clause with attach/detach when data is not present on the
+   device.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <openacc.h>
+
+#define N 128
+
+typedef struct {
+  int x;
+  int *y;
+} mystruct;
+
+int
+main (int argc, char *argv[])
+{
+  int *devptr;
+  mystruct s;
+
+  s.x = 5;
+  s.y = (int *) malloc (N * sizeof (int));
+
+  #pragma acc data copyin(s)
+  {
+    #pragma acc parallel no_create(s.y[0:N]) copyout(devptr)
+    {
+      devptr = &s.y[2];
+    }
+  }
+
+  if (devptr != &s.y[2])
+    __builtin_abort ();
+
+  free (s.y);
+
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-4.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/nocreate-4.c
new file mode 100644 (file)
index 0000000..75ab616
--- /dev/null
@@ -0,0 +1,42 @@
+/* Test no_create clause with attach/detach when data is present on the
+   device.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <openacc.h>
+
+#define N 128
+
+typedef struct {
+  int x;
+  int *y;
+} mystruct;
+
+int
+main (int argc, char *argv[])
+{
+  int *devptr;
+  mystruct s;
+
+  s.x = 5;
+  s.y = (int *) malloc (N * sizeof (int));
+
+  #pragma acc data copyin(s)
+  {
+    #pragma acc enter data copyin(s.y[0:N])
+
+    #pragma acc parallel no_create(s.y[0:N]) copyout(devptr)
+    {
+      devptr = &s.y[2];
+    }
+  }
+
+  if (devptr != acc_deviceptr (&s.y[2]))
+    __builtin_abort ();
+
+  #pragma acc exit data delete(s.y[0:N])
+
+  free (s.y);
+
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/nocreate-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/nocreate-1.f90
new file mode 100644 (file)
index 0000000..f048355
--- /dev/null
@@ -0,0 +1,29 @@
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+! Test no_create clause with data construct when data is present/not present.
+
+program nocreate
+  use openacc
+  implicit none
+  integer, parameter :: n = 512
+  integer :: myarr(n)
+  integer i
+
+  do i = 1, n
+    myarr(i) = 0
+  end do
+
+  !$acc data no_create (myarr)
+  if (acc_is_present (myarr)) stop 1
+  !$acc end data
+
+  !$acc enter data copyin (myarr)
+  !$acc data no_create (myarr)
+  if (acc_is_present (myarr) .eqv. .false.) stop 2
+  !$acc end data
+  !$acc exit data copyout (myarr)
+
+  do i = 1, n
+    if (myarr(i) .ne. 0) stop 3
+  end do
+end program nocreate
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/nocreate-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/nocreate-2.f90
new file mode 100644 (file)
index 0000000..34444ec
--- /dev/null
@@ -0,0 +1,61 @@
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+! Test no_create clause with data/parallel constructs.
+
+program nocreate
+  use openacc
+  implicit none
+  integer, parameter :: n = 512
+  integer :: myarr(n)
+  integer i
+
+  do i = 1, n
+    myarr(i) = 0
+  end do
+
+  call do_on_target(myarr, n)
+
+  do i = 1, n
+    if (myarr(i) .ne. i) stop 1
+  end do
+
+  do i = 1, n
+    myarr(i) = 0
+  end do
+
+  !$acc enter data copyin(myarr)
+  call do_on_target(myarr, n)
+  !$acc exit data copyout(myarr)
+
+  do i = 1, n
+    if (myarr(i) .ne. i * 2) stop 2
+  end do
+end program nocreate
+
+subroutine do_on_target (arr, n)
+  use openacc
+  implicit none
+  integer :: n, arr(n)
+  integer :: i
+
+!$acc data no_create (arr)
+
+if (acc_is_present(arr)) then
+  ! The no_create clause is meant for partially shared-memory machines.  This
+  ! test is written to work on non-shared-memory machines, though this is not
+  ! necessarily a useful way to use the no_create clause in practice.
+
+  !$acc parallel loop no_create (arr)
+  do i = 1, n
+    arr(i) = i * 2
+  end do
+  !$acc end parallel loop
+else
+  do i = 1, n
+    arr(i) = i
+  end do
+end if
+
+!$acc end data
+
+end subroutine do_on_target