ABataev created this revision. ABataev added reviewers: jdoerfert, cchen. Herald added subscribers: guansong, yaxunl. Herald added a reviewer: aaron.ballman. Herald added a project: clang. ABataev requested review of this revision. Herald added a subscriber: sstefan1.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D86239 Files: 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
Index: clang/test/OpenMP/declare_target_ast_print.cpp =================================================================== --- clang/test/OpenMP/declare_target_ast_print.cpp +++ clang/test/OpenMP/declare_target_ast_print.cpp @@ -241,6 +241,28 @@ // 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 @@ // CHECK: #pragma omp declare target // CHECK-NEXT: int ts = 1; // CHECK-NEXT: #pragma omp end declare target + #endif Index: clang/test/AST/dump.cpp =================================================================== --- clang/test/AST/dump.cpp +++ clang/test/AST/dump.cpp @@ -86,4 +86,4 @@ // 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 Index: clang/lib/Serialization/ASTReaderDecl.cpp =================================================================== --- clang/lib/Serialization/ASTReaderDecl.cpp +++ clang/lib/Serialization/ASTReaderDecl.cpp @@ -4644,12 +4644,11 @@ } 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; } Index: clang/lib/Sema/SemaOpenMP.cpp =================================================================== --- clang/lib/Sema/SemaOpenMP.cpp +++ clang/lib/Sema/SemaOpenMP.cpp @@ -2473,7 +2473,7 @@ 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 @@ 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 @@ 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 @@ (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 @@ 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); Index: clang/lib/AST/AttrImpl.cpp =================================================================== --- clang/lib/AST/AttrImpl.cpp +++ clang/lib/AST/AttrImpl.cpp @@ -136,8 +136,16 @@ 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 @@ 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; } Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -9968,7 +9968,7 @@ 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(); @@ -10228,7 +10228,7 @@ 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; Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -3326,13 +3326,15 @@ [ "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); }]; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits