Author: Alexey Bataev Date: 2020-08-24T09:58:37-04:00 New Revision: bedc841a5098bc0a90bbc66328d7aab4b2c23c4a
URL: https://github.com/llvm/llvm-project/commit/bedc841a5098bc0a90bbc66328d7aab4b2c23c4a DIFF: https://github.com/llvm/llvm-project/commit/bedc841a5098bc0a90bbc66328d7aab4b2c23c4a.diff LOG: [OPENMP]Fix PR47158, case 3: allow devic_typein nested declare target region. OpenMP 5.0 supports nested declare target regions. So, in general,it is allow to mark a declarationas declare target with different device_type or link type. Patch adds support for such kind of nesting. Differential Revision: https://reviews.llvm.org/D86239 Added: Modified: clang/include/clang/Basic/Attr.td clang/include/clang/Sema/Sema.h clang/lib/AST/AttrImpl.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/test/AST/dump.cpp clang/test/OpenMP/declare_target_ast_print.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 45244c67efe0..9929948adb20 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3330,13 +3330,15 @@ def OMPDeclareTargetDecl : InheritableAttr { [ "MT_To", "MT_Link" ]>, EnumArgument<"DevType", "DevTypeTy", [ "host", "nohost", "any" ], - [ "DT_Host", "DT_NoHost", "DT_Any" ]> + [ "DT_Host", "DT_NoHost", "DT_Any" ]>, + UnsignedArgument<"Level"> ]; let AdditionalMembers = [{ void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const; static llvm::Optional<MapTypeTy> isDeclareTargetDeclaration(const ValueDecl *VD); static llvm::Optional<DevTypeTy> getDeviceType(const ValueDecl *VD); + static llvm::Optional<SourceLocation> getLocation(const ValueDecl *VD); }]; } diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 84e66b85208e..27f424a4cb25 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9974,7 +9974,7 @@ class Sema final { private: void *VarDataSharingAttributesStack; /// Number of nested '#pragma omp declare target' directives. - unsigned DeclareTargetNestingLevel = 0; + SmallVector<SourceLocation, 4> DeclareTargetNesting; /// Initialization of data-sharing attributes stack. void InitDataSharingAttributesStack(); void DestroyDataSharingAttributesStack(); @@ -10234,7 +10234,7 @@ class Sema final { SourceLocation Loc); /// Return true inside OpenMP declare target region. bool isInOpenMPDeclareTargetContext() const { - return DeclareTargetNestingLevel > 0; + return !DeclareTargetNesting.empty(); } /// Return true inside OpenMP target region. bool isInOpenMPTargetExecutionDirective() const; diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp index 7818fbb1918b..7ca58f2b83a2 100644 --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/lib/AST/AttrImpl.cpp @@ -136,8 +136,16 @@ llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(const ValueDecl *VD) { if (!VD->hasAttrs()) return llvm::None; - if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>()) - return Attr->getMapType(); + unsigned Level = 0; + const OMPDeclareTargetDeclAttr *FoundAttr = nullptr; + for (const auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) { + if (Level < Attr->getLevel()) { + Level = Attr->getLevel(); + FoundAttr = Attr; + } + } + if (FoundAttr) + return FoundAttr->getMapType(); return llvm::None; } @@ -146,8 +154,34 @@ llvm::Optional<OMPDeclareTargetDeclAttr::DevTypeTy> OMPDeclareTargetDeclAttr::getDeviceType(const ValueDecl *VD) { if (!VD->hasAttrs()) return llvm::None; - if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>()) - return Attr->getDevType(); + unsigned Level = 0; + const OMPDeclareTargetDeclAttr *FoundAttr = nullptr; + for (const auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) { + if (Level < Attr->getLevel()) { + Level = Attr->getLevel(); + FoundAttr = Attr; + } + } + if (FoundAttr) + return FoundAttr->getDevType(); + + return llvm::None; +} + +llvm::Optional<SourceLocation> +OMPDeclareTargetDeclAttr::getLocation(const ValueDecl *VD) { + if (!VD->hasAttrs()) + return llvm::None; + unsigned Level = 0; + const OMPDeclareTargetDeclAttr *FoundAttr = nullptr; + for (const auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) { + if (Level < Attr->getLevel()) { + Level = Attr->getLevel(); + FoundAttr = Attr; + } + } + if (FoundAttr) + return FoundAttr->getRange().getBegin(); return llvm::None; } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 53917ef98acd..cd20b6bfdb98 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2473,7 +2473,7 @@ void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, StringRef HostDevTy = getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; - Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), + Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), diag::note_omp_marked_device_type_here) << HostDevTy; return; @@ -2484,7 +2484,7 @@ void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( OMPC_device_type, OMPC_DEVICE_TYPE_nohost); Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; - Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), + Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), diag::note_omp_marked_device_type_here) << NoHostDevTy; } @@ -18483,14 +18483,14 @@ bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { Diag(Loc, diag::err_omp_region_not_file_context); return false; } - ++DeclareTargetNestingLevel; + DeclareTargetNesting.push_back(Loc); return true; } void Sema::ActOnFinishOpenMPDeclareTargetDirective() { - assert(DeclareTargetNestingLevel > 0 && + assert(!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); - --DeclareTargetNestingLevel; + DeclareTargetNesting.pop_back(); } NamedDecl * @@ -18543,19 +18543,25 @@ void Sema::ActOnOpenMPDeclareTargetName( (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) Diag(Loc, diag::warn_omp_declare_target_after_first_use); + auto *VD = cast<ValueDecl>(ND); Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = - OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); - if (DevTy.hasValue() && *DevTy != DT) { + OMPDeclareTargetDeclAttr::getDeviceType(VD); + Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD); + if (DevTy.hasValue() && *DevTy != DT && + (DeclareTargetNesting.empty() || + *AttrLoc != DeclareTargetNesting.back())) { Diag(Loc, diag::err_omp_device_type_mismatch) << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); return; } Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = - OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); - if (!Res) { - auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, - SourceRange(Loc, Loc)); + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); + if (!Res || (!DeclareTargetNesting.empty() && + *AttrLoc == DeclareTargetNesting.back())) { + auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( + Context, MT, DT, DeclareTargetNesting.size() + 1, + SourceRange(Loc, Loc)); ND->addAttr(A); if (ASTMutationListener *ML = Context.getASTMutationListener()) ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); @@ -18647,7 +18653,9 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, isa<FunctionTemplateDecl>(D)) { auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( Context, OMPDeclareTargetDeclAttr::MT_To, - OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); + OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(), + SourceRange(DeclareTargetNesting.back(), + DeclareTargetNesting.back())); D->addAttr(A); if (ASTMutationListener *ML = Context.getASTMutationListener()) ML->DeclarationMarkedOpenMPDeclareTarget(D, A); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index c7a009d1e50d..47b378f5727b 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -4666,12 +4666,11 @@ void ASTDeclReader::UpdateDecl(Decl *D, } case UPD_DECL_MARKED_OPENMP_DECLARETARGET: { - OMPDeclareTargetDeclAttr::MapTypeTy MapType = - static_cast<OMPDeclareTargetDeclAttr::MapTypeTy>(Record.readInt()); - OMPDeclareTargetDeclAttr::DevTypeTy DevType = - static_cast<OMPDeclareTargetDeclAttr::DevTypeTy>(Record.readInt()); + auto MapType = Record.readEnum<OMPDeclareTargetDeclAttr::MapTypeTy>(); + auto DevType = Record.readEnum<OMPDeclareTargetDeclAttr::DevTypeTy>(); + unsigned Level = Record.readInt(); D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit( - Reader.getContext(), MapType, DevType, readSourceRange(), + Reader.getContext(), MapType, DevType, Level, readSourceRange(), AttributeCommonInfo::AS_Pragma)); break; } diff --git a/clang/test/AST/dump.cpp b/clang/test/AST/dump.cpp index 06af15f07089..bbd388cbf095 100644 --- a/clang/test/AST/dump.cpp +++ b/clang/test/AST/dump.cpp @@ -86,4 +86,4 @@ int bar() { // CHECK-NEXT: | `-ReturnStmt {{.+}} <line:[[@LINE-8]]:3, col:10> // CHECK-NEXT: | `-ImplicitCastExpr {{.+}} <col:10> 'int' <LValueToRValue> // CHECK-NEXT: | `-DeclRefExpr {{.+}} <col:10> 'int' lvalue Var {{.+}} 'f' 'int' -// CHECK-NEXT: `-OMPDeclareTargetDeclAttr {{.+}} <<invalid sloc>> Implicit MT_To +// CHECK-NEXT: `-OMPDeclareTargetDeclAttr {{.+}} <line:75:21> Implicit MT_To DT_Any 1 diff --git a/clang/test/OpenMP/declare_target_ast_print.cpp b/clang/test/OpenMP/declare_target_ast_print.cpp index 14115e6a3ad6..40dce02191e7 100644 --- a/clang/test/OpenMP/declare_target_ast_print.cpp +++ b/clang/test/OpenMP/declare_target_ast_print.cpp @@ -241,6 +241,28 @@ int baz() { return 1; } // CHECK: void cba(); // CHECK: #pragma omp end declare target +#pragma omp declare target +int abc1() { return 1; } +#pragma omp declare target to(abc1) device_type(nohost) +#pragma omp end declare target + +// CHECK-NEXT: #pragma omp declare target +// CHECK-NEXT: #pragma omp declare target device_type(nohost) +// CHECK-NEXT: int abc1() { +// CHECK-NEXT: return 1; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp end declare target + +#pragma omp declare target +int inner_link; +#pragma omp declare target link(inner_link) +#pragma omp end declare target + +// CHECK-NEXT: #pragma omp declare target +// CHECK-NEXT: #pragma omp declare target link +// CHECK-NEXT: int inner_link; +// CHECK-NEXT: #pragma omp end declare target + int main (int argc, char **argv) { foo(); foo_c(); @@ -254,4 +276,5 @@ int main (int argc, char **argv) { // CHECK: #pragma omp declare target // CHECK-NEXT: int ts = 1; // CHECK-NEXT: #pragma omp end declare target + #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits