[clang] bedc841 - [OPENMP]Fix PR47158, case 3: allow devic_typein nested declare target region.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 24 07:05:10 PDT 2020
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
More information about the cfe-commits
mailing list