diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2018-08-14 18:31:20 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2018-08-14 18:31:20 +0000 |
commit | a24c755e26d2fbd5e007687b94bbfa9585beab11 (patch) | |
tree | 77b3dba8209fa51ae43feac8713f03d58c78acfb | |
parent | 26dbd400930e046ea1730e14fd70a9e3c16cb14a (diff) |
[OPENMP] Fix processing of declare target construct.
The attribute marked as inheritable since OpenMP 5.0 supports it +
additional fixes to support new functionality.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@339704 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/Attr.td | 12 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 10 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGOpenMPRuntime.cpp | 38 | ||||
-rw-r--r-- | lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 29 | ||||
-rw-r--r-- | test/OpenMP/declare_target_ast_print.cpp | 24 |
7 files changed, 59 insertions, 72 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 7591635176..901e4480fb 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -2956,9 +2956,10 @@ def OMPDeclareSimdDecl : Attr { }]; } -def OMPDeclareTargetDecl : Attr { +def OMPDeclareTargetDecl : InheritableAttr { let Spellings = [Pragma<"omp", "declare target">]; let SemaHandler = 0; + let Subjects = SubjectList<[Function, SharedVar]>; let Documentation = [OMPDeclareTargetDocs]; let Args = [ EnumArgument<"MapType", "MapTypeTy", @@ -2971,6 +2972,15 @@ def OMPDeclareTargetDecl : Attr { if (getMapType() != MT_To) OS << ' ' << ConvertMapTypeTyToStr(getMapType()); } + static llvm::Optional<MapTypeTy> + isDeclareTargetDeclaration(const ValueDecl *VD) { + if (!VD->hasAttrs()) + return llvm::None; + if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>()) + return Attr->getMapType(); + + return llvm::None; + } }]; } diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index b96e24ae0f..5f94cf2cec 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -9806,13 +9806,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { return true; // If the decl is marked as `declare target`, it should be emitted. - for (const auto *Decl : D->redecls()) { - if (!Decl->hasAttrs()) - continue; - if (const auto *Attr = Decl->getAttr<OMPDeclareTargetDeclAttr>()) - if (Attr->getMapType() != OMPDeclareTargetDeclAttr::MT_Link) - return true; - } + if (const llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) + return *Res != OMPDeclareTargetDeclAttr::MT_Link; return false; } diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 09e22f19f8..5548561105 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -1091,6 +1091,10 @@ void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { printTemplateParameters(FD->getTemplateParameterList(I)); } VisitRedeclarableTemplateDecl(D); + // Declare target attribute is special one, natural spelling for the pragma + // assumes "ending" construct so print it here. + if (D->getTemplatedDecl()->hasAttr<OMPDeclareTargetDeclAttr>()) + Out << "#pragma omp end declare target\n"; // Never print "instantiations" for deduction guides (they don't really // have them). diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index 0393c4a382..245eacc31e 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -897,25 +897,6 @@ static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, CGF.EmitBlock(DoneBB, /*IsFinished=*/true); } -static llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> -isDeclareTargetDeclaration(const ValueDecl *VD) { - for (const Decl *D : VD->redecls()) { - if (!D->hasAttrs()) - continue; - if (const auto *Attr = D->getAttr<OMPDeclareTargetDeclAttr>()) - return Attr->getMapType(); - } - if (const auto *V = dyn_cast<VarDecl>(VD)) { - if (const VarDecl *TD = V->getTemplateInstantiationPattern()) - return isDeclareTargetDeclaration(TD); - } else if (const auto *FD = dyn_cast<FunctionDecl>(VD)) { - if (const auto *TD = FD->getTemplateInstantiationPattern()) - return isDeclareTargetDeclaration(TD); - } - - return llvm::None; -} - LValue ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, const Expr *E) { return CGF.EmitOMPSharedLValue(E); } @@ -2417,7 +2398,7 @@ Address CGOpenMPRuntime::getAddrOfDeclareTargetLink(const VarDecl *VD) { if (CGM.getLangOpts().OpenMPSimd) return Address::invalid(); llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = - isDeclareTargetDeclaration(VD); + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { SmallString<64> PtrName; { @@ -2639,7 +2620,7 @@ bool CGOpenMPRuntime::emitDeclareTargetVarDefinition(const VarDecl *VD, llvm::GlobalVariable *Addr, bool PerformInit) { Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = - isDeclareTargetDeclaration(VD); + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link) return false; VD = VD->getDefinition(CGM.getContext()); @@ -6957,7 +6938,7 @@ private: if (const auto *VD = dyn_cast_or_null<VarDecl>(I->getAssociatedDeclaration())) { if (llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = - isDeclareTargetDeclaration(VD)) + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) if (*Res == OMPDeclareTargetDeclAttr::MT_Link) { IsLink = true; BP = CGF.CGM.getOpenMPRuntime().getAddrOfDeclareTargetLink(VD); @@ -7448,7 +7429,7 @@ public: if (!VD) continue; llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = - isDeclareTargetDeclaration(VD); + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); if (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) continue; StructRangeInfoTy PartialStruct; @@ -8078,7 +8059,7 @@ bool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) { scanForTargetRegionsFunctions(FD->getBody(), CGM.getMangledName(GD)); // Do not to emit function if it is not marked as declare target. - return !isDeclareTargetDeclaration(FD) && + return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD) && AlreadyEmittedTargetFunctions.count(FD->getCanonicalDecl()) == 0; } @@ -8105,7 +8086,8 @@ bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) { // Do not to emit variable if it is not marked as declare target. llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = - isDeclareTargetDeclaration(cast<VarDecl>(GD.getDecl())); + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( + cast<VarDecl>(GD.getDecl())); if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link) { if (CGM.getContext().DeclMustBeEmitted(GD.getDecl())) DeferredGlobalVariables.insert(cast<VarDecl>(GD.getDecl())); @@ -8117,7 +8099,7 @@ bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) { void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD, llvm::Constant *Addr) { if (llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = - isDeclareTargetDeclaration(VD)) { + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags; StringRef VarName; CharUnits VarSize; @@ -8171,7 +8153,7 @@ bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) { void CGOpenMPRuntime::emitDeferredTargetDecls() const { for (const VarDecl *VD : DeferredGlobalVariables) { llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = - isDeclareTargetDeclaration(VD); + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); if (Res) { assert(*Res != OMPDeclareTargetDeclAttr::MT_Link && "Implicit declare target variables must be only to()."); @@ -8202,7 +8184,7 @@ bool CGOpenMPRuntime::markAsGlobalTarget(GlobalDecl GD) { const FunctionDecl *FD = D->getCanonicalDecl(); // Do not to emit function if it is marked as declare target as it was already // emitted. - if (isDeclareTargetDeclaration(D)) { + if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(D)) { if (D->hasBody() && AlreadyEmittedTargetFunctions.count(FD) == 0) { if (auto *F = dyn_cast_or_null<llvm::Function>( CGM.GetGlobalValue(CGM.getMangledName(GD)))) diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index c8d7a23032..0fd261150f 100644 --- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -191,20 +191,10 @@ class CheckVarsEscapingDeclContext final bool AllEscaped = false; bool IsForCombinedParallelRegion = false; - static llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> - isDeclareTargetDeclaration(const ValueDecl *VD) { - for (const Decl *D : VD->redecls()) { - if (!D->hasAttrs()) - continue; - if (const auto *Attr = D->getAttr<OMPDeclareTargetDeclAttr>()) - return Attr->getMapType(); - } - return llvm::None; - } - void markAsEscaped(const ValueDecl *VD) { // Do not globalize declare target variables. - if (!isa<VarDecl>(VD) || isDeclareTargetDeclaration(VD)) + if (!isa<VarDecl>(VD) || + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) return; VD = cast<ValueDecl>(VD->getCanonicalDecl()); // Variables captured by value must be globalized. diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index e2a8c19367..215b4bf109 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1258,17 +1258,6 @@ void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { DSAStack->popFunction(OldFSI); } -static llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> -isDeclareTargetDeclaration(const ValueDecl *VD) { - for (const Decl *D : VD->redecls()) { - if (!D->hasAttrs()) - continue; - if (const auto *Attr = D->getAttr<OMPDeclareTargetDeclAttr>()) - return Attr->getMapType(); - } - return llvm::None; -} - bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { assert(LangOpts.OpenMP && "OpenMP is not allowed"); @@ -1449,14 +1438,14 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) { (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { // Try to mark variable as declare target if it is used in capturing // regions. - if (!isDeclareTargetDeclaration(VD)) + if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) checkDeclIsAllowedInOpenMPTarget(nullptr, VD); return nullptr; } else if (isInOpenMPTargetExecutionDirective()) { // If the declaration is enclosed in a 'declare target' directive, // then it should not be captured. // - if (isDeclareTargetDeclaration(VD)) + if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) return nullptr; return VD; } @@ -1996,7 +1985,7 @@ public: // Skip internally declared static variables. llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = - isDeclareTargetDeclaration(VD); + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) && (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) return; @@ -13152,6 +13141,8 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, return; } } + if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) + D = FTD->getTemplatedDecl(); if (const auto *FD = dyn_cast<FunctionDecl>(D)) { if (FD->hasAttr<OMPDeclareTargetDeclAttr>() && (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() == @@ -13162,16 +13153,6 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, return; } } - if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) { - if (FTD->hasAttr<OMPDeclareTargetDeclAttr>() && - (FTD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() == - OMPDeclareTargetDeclAttr::MT_Link)) { - assert(IdLoc.isValid() && "Source location is expected"); - Diag(IdLoc, diag::err_omp_function_in_link_clause); - Diag(FTD->getLocation(), diag::note_defined_here) << FTD; - return; - } - } if (!E) { // Checking declaration inside declare target region. if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && diff --git a/test/OpenMP/declare_target_ast_print.cpp b/test/OpenMP/declare_target_ast_print.cpp index ae6c296310..921b96a446 100644 --- a/test/OpenMP/declare_target_ast_print.cpp +++ b/test/OpenMP/declare_target_ast_print.cpp @@ -169,11 +169,35 @@ struct SSSTt { // CHECK: #pragma omp end declare target // CHECK: int b; +#pragma omp declare target +template <typename T> +T baz() { return T(); } +#pragma omp end declare target + +template <> +int baz() { return 1; } + +// CHECK: #pragma omp declare target +// CHECK: template <typename T> T baz() { +// CHECK: return T(); +// CHECK: } +// CHECK: #pragma omp end declare target +// CHECK: #pragma omp declare target +// CHECK: template<> float baz<float>() { +// CHECK: return float(); +// CHECK: } +// CHECK: template<> int baz<int>() { +// CHECK: return 1; +// CHECK: } +// CHECK: #pragma omp end declare target + int main (int argc, char **argv) { foo(); foo_c(); foo_cpp(); test1(); + baz<float>(); + baz<int>(); return (0); } |