diff --git a/flang/docs/OpenMP-semantics.md b/flang/docs/OpenMP-semantics.md index 46dc189456f99..579c40692ba4b 100644 --- a/flang/docs/OpenMP-semantics.md +++ b/flang/docs/OpenMP-semantics.md @@ -318,6 +318,7 @@ w/ For the following OpenMP regions: * `target` regions +* `target data` regions * `teams` regions * `parallel` regions * `simd` regions @@ -407,6 +408,16 @@ More details are listed in the following table: OmpLastPrivate + + use_device_ptr + + Yes + + New Symbol + + OmpUseDevicePtr + + To determine the right data-sharing attribute, @@ -519,6 +530,12 @@ will be determined and represented as `Flag` in the `Symbol` object of the variable. No `Symbol` or `Scope` will be created. +However, there are some exceptions for this, Pointers that appear in a +use_device_ptr clause are privatized and the device pointers to the +corresponding list items in the device data environment are assigned into the +private versions so it is best to follow the representation for privatised +variables i.e represent them with a new Symbol and `OmpUseDevicePtr` flag. + The basic steps to determine the data-mapping attribute are: 1. If _map_ clause is present, diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h index ddeb73f09af15..41a03a2b6a949 100644 --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -560,6 +560,7 @@ class Symbol { OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate, // OpenMP data-mapping attribute OmpMapTo, OmpMapFrom, OmpMapAlloc, OmpMapRelease, OmpMapDelete, + OmpUseDevicePtr, // OpenMP data-copying attribute OmpCopyIn, OmpCopyPrivate, // OpenMP miscellaneous flags diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index e7d628d4c428f..cec08e18e44c5 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -309,7 +309,7 @@ TYPE_PARSER( "TO" >> construct(construct( parenthesized(Parser{}))) || "USE_DEVICE_PTR" >> construct(construct( - parenthesized(nonemptyList(name)))) || + parenthesized(Parser{}))) || "UNIFIED_ADDRESS" >> construct(construct()) || "UNIFIED_SHARED_MEMORY" >> diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 9794424e266d6..c7bc0197630c9 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -2766,11 +2766,12 @@ const parser::OmpObjectList *OmpStructureChecker::GetOmpObjectList( const parser::OmpClause &clause) { // Clauses with OmpObjectList as its data member - using MemberObjectListClauses = std::tuple; + using MemberObjectListClauses = + std::tuple; // Clauses with OmpObjectList in the tuple using TupleObjectListClauses = std::tuple { return false; } + bool Pre(const parser::OmpClause::UseDevicePtr &x) { + ResolveOmpObjectList(x.v, Symbol::Flag::OmpUseDevicePtr); + return false; + } + void Post(const parser::Name &); // Keep track of labels in the statements that causes jumps to target labels @@ -506,7 +511,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { Symbol::Flag::OmpPrivate, Symbol::Flag::OmpLinear, Symbol::Flag::OmpFirstPrivate, Symbol::Flag::OmpLastPrivate, Symbol::Flag::OmpReduction, Symbol::Flag::OmpCriticalLock, - Symbol::Flag::OmpCopyIn}; + Symbol::Flag::OmpCopyIn, Symbol::Flag::OmpUseDevicePtr}; static constexpr Symbol::Flags ompFlagsRequireMark{ Symbol::Flag::OmpThreadprivate}; diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 820b3d8fda0b6..57870a7ccce02 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -1414,7 +1414,6 @@ bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) { const auto &beginBlockDir{std::get(x.t)}; const auto &beginDir{std::get(beginBlockDir.t)}; switch (beginDir.v) { - case llvm::omp::Directive::OMPD_target_data: case llvm::omp::Directive::OMPD_master: case llvm::omp::Directive::OMPD_ordered: case llvm::omp::Directive::OMPD_taskgroup: diff --git a/flang/test/Semantics/OpenMP/use_device_ptr.f90 b/flang/test/Semantics/OpenMP/use_device_ptr.f90 new file mode 100644 index 0000000000000..738904bbab64c --- /dev/null +++ b/flang/test/Semantics/OpenMP/use_device_ptr.f90 @@ -0,0 +1,21 @@ +! RUN: %flang -fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s +! OpenMP Version 5.0 +! 2.10.1 use_device_ptr clause +! List items that appear in a use_device_ptr clause are converted into device +! pointers to the corresponding list item in the device data environment. + +subroutine omp_target_data + use iso_c_binding + integer :: a(1024) + !CHECK: b size=8 offset=4096: ObjectEntity type: TYPE(c_ptr) + type(C_PTR) :: b + integer, pointer :: arrayB + a = 1 + !$omp target data map(tofrom: a, arrayB) use_device_ptr(b) + !CHECK: b (OmpUseDevicePtr) + allocate(arrayB) + call c_f_pointer(b, arrayB) + a = arrayB + !$omp end target data +end subroutine omp_target_data + diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index fe5af4cb0c428..6e94302fab31c 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -295,8 +295,7 @@ def OMPC_From : Clause<"from"> { } def OMPC_UseDevicePtr : Clause<"use_device_ptr"> { let clangClass = "OMPUseDevicePtrClause"; - let flangClass = "Name"; - let isValueList = true; + let flangClass = "OmpObjectList"; } def OMPC_IsDevicePtr : Clause<"is_device_ptr"> { let clangClass = "OMPIsDevicePtrClause";