]> granicus.if.org Git - clang/commitdiff
Backport r339704 to 7.0 for PR38598
authorHans Wennborg <hans@hanshq.net>
Fri, 17 Aug 2018 07:34:53 +0000 (07:34 +0000)
committerHans Wennborg <hans@hanshq.net>
Fri, 17 Aug 2018 07:34:53 +0000 (07:34 +0000)
> Author: abataev
> Date: Tue Aug 14 11:31:20 2018
> New Revision: 339704
>
> URL: http://llvm.org/viewvc/llvm-project?rev=339704&view=rev
> Log:
> [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/branches/release_70@339998 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Attr.td
lib/AST/ASTContext.cpp
lib/AST/DeclPrinter.cpp
lib/CodeGen/CGOpenMPRuntime.cpp
lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
lib/Sema/SemaOpenMP.cpp
test/OpenMP/declare_target_ast_print.cpp

index fea8e129d7da61a0204431fe49cacc96f6bd198d..1f17819dba74db13be32ea65611b95c73aadb05e 100644 (file)
@@ -2938,9 +2938,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",
@@ -2953,6 +2954,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;
+    }
   }];
 }
 
index f7546c7c0dfc95db2c8a4a36bb94f629b070d63a..c085f52cae312004a67a0aa150630436c552c4e9 100644 (file)
@@ -9798,13 +9798,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;
 }
index 09e22f19f87a11dd1a7ea060e8944f0329e814f9..55485611054c3b770141d529e2fceed7072480b2 100644 (file)
@@ -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).
index b68942f2faf0f54a53f54ac65993b5eec1dac13c..4454c719864faffe83bd99e4c5a4a7521adc4f52 100644 (file)
@@ -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());
@@ -6945,7 +6926,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);
@@ -7436,7 +7417,7 @@ public:
         if (!VD)
           continue;
         llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
-            isDeclareTargetDeclaration(VD);
+            OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
         if (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)
           continue;
         StructRangeInfoTy PartialStruct;
@@ -8066,7 +8047,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;
 }
 
@@ -8093,14 +8074,15 @@ 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()));
   return !Res || *Res == OMPDeclareTargetDeclAttr::MT_Link;
 }
 
 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;
@@ -8173,7 +8155,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))))
index 036b5371fe0b0118c2fa32900ddeb31aa39ef965..2768a8eb18578226b54d6667adde15601e7f9c94 100644 (file)
@@ -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.
index 56152abee1712e85e8694d359ff25cfd77c93827..6060e5b75c22dba887b0382aafa10bb1617606ea 100644 (file)
@@ -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");
 
@@ -1448,7 +1437,7 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) const {
     // 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;
   }
@@ -1987,7 +1976,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;
@@ -13143,6 +13132,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() ==
@@ -13153,16 +13144,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>() &&
index bd1acc28dc6c205132778d92c2740d39f0875c0f..1ffa456b7d7446b9c26e14e26a1aa01dd442ec20 100644 (file)
@@ -150,11 +150,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);
 }