summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-03-20 20:14:22 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2019-03-20 20:14:22 +0000
commitda1812dcb198a84f6c45919e4ba7e0cf035238c8 (patch)
tree81b7cb2552bbc612130e3216054f39a0b22054c5
parent4f7e7882e9972ec567a0529a38737cb83324c91b (diff)
[OPENMP]Improve detection of omp_allocator_handle_t type and predefined
allocators. It is better to deduce omp_allocator_handle_t type from the predefined allocators, because omp.h header might not define it explicitly. Plus, it allows to identify the predefined allocators correctly when trying to build the allcoator for the global variables. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356607 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/Attr.td17
-rw-r--r--include/clang/Sema/Sema.h2
-rw-r--r--lib/Sema/SemaOpenMP.cpp131
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp9
-rw-r--r--lib/Serialization/ASTWriter.cpp9
-rw-r--r--test/OpenMP/allocate_allocator_messages.cpp10
-rw-r--r--test/PCH/chain-openmp-allocate.cpp7
7 files changed, 148 insertions, 37 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index b6bc7abe49..f14c8dc202 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -3151,7 +3151,22 @@ def OMPAllocateDecl : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let SemaHandler = 0;
- let Args = [ExprArgument<"Allocator">];
+ let Args = [
+ EnumArgument<"AllocatorType", "AllocatorTypeTy",
+ [
+ "omp_default_mem_alloc", "omp_large_cap_mem_alloc",
+ "omp_const_mem_alloc", "omp_high_bw_mem_alloc",
+ "omp_low_lat_mem_alloc", "omp_cgroup_mem_alloc",
+ "omp_pteam_mem_alloc", "omp_thread_mem_alloc", ""
+ ],
+ [
+ "OMPDefaultMemAlloc", "OMPLargeCapMemAlloc",
+ "OMPConstMemAlloc", "OMPHighBWMemAlloc", "OMPLowLatMemAlloc",
+ "OMPCGroupMemAlloc", "OMPPTeamMemAlloc", "OMPThreadMemAlloc",
+ "OMPUserDefinedMemAlloc"
+ ]>,
+ ExprArgument<"Allocator">
+ ];
let Documentation = [Undocumented];
}
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index cb9d65db6d..65a6ecc2d2 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -8773,8 +8773,6 @@ public:
//
private:
void *VarDataSharingAttributesStack;
- /// omp_allocator_handle_t type.
- QualType OMPAllocatorHandleT;
/// Number of nested '#pragma omp declare target' directives.
unsigned DeclareTargetNestingLevel = 0;
/// Initialization of data-sharing attributes stack.
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index a36eaefecf..5d7ad8c5be 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -188,10 +188,29 @@ private:
/// Vector of previously declared requires directives
SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
+ /// omp_allocator_handle_t type.
+ QualType OMPAllocatorHandleT;
+ /// Expression for the predefined allocators.
+ Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
+ nullptr};
public:
explicit DSAStackTy(Sema &S) : SemaRef(S) {}
+ /// Sets omp_allocator_handle_t type.
+ void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
+ /// Gets omp_allocator_handle_t type.
+ QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
+ /// Sets the given default allocator.
+ void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
+ Expr *Allocator) {
+ OMPPredefinedAllocators[AllocatorKind] = Allocator;
+ }
+ /// Returns the specified default allocator.
+ Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
+ return OMPPredefinedAllocators[AllocatorKind];
+ }
+
bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
OpenMPClauseKind getClauseParsingMode() const {
assert(isClauseParsingMode() && "Must be in clause parsing mode.");
@@ -2194,6 +2213,44 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
return D;
}
+static OMPAllocateDeclAttr::AllocatorTypeTy
+getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
+ if (!Allocator)
+ return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
+ if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
+ Allocator->isInstantiationDependent() ||
+ Allocator->containsUnexpandedParameterPack() ||
+ !Allocator->isEvaluatable(S.getASTContext()))
+ return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
+ bool Suppress = S.getDiagnostics().getSuppressAllDiagnostics();
+ S.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
+ auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
+ for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
+ I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
+ auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
+ Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
+ // Compare allocator with the predefined allocator and if true - return
+ // predefined allocator kind.
+ ExprResult DefAllocRes = S.DefaultLvalueConversion(DefAllocator);
+ ExprResult AllocRes = S.DefaultLvalueConversion(Allocator);
+ ExprResult CompareRes = S.CreateBuiltinBinOp(
+ Allocator->getExprLoc(), BO_EQ, DefAllocRes.get(), AllocRes.get());
+ if (!CompareRes.isUsable())
+ continue;
+ bool Result;
+ if (!CompareRes.get()->EvaluateAsBooleanCondition(Result,
+ S.getASTContext()))
+ continue;
+ if (Result) {
+ AllocatorKindRes = AllocatorKind;
+ break;
+ }
+
+ }
+ S.getDiagnostics().setSuppressAllDiagnostics(Suppress);
+ return AllocatorKindRes;
+}
+
Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
SourceLocation Loc, ArrayRef<Expr *> VarList,
ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
@@ -2201,6 +2258,8 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
Expr *Allocator = nullptr;
if (!Clauses.empty())
Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
+ OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
+ getAllocatorKind(*this, DSAStack, Allocator);
SmallVector<Expr *, 8> Vars;
for (Expr *RefExpr : VarList) {
auto *DE = cast<DeclRefExpr>(RefExpr);
@@ -2220,27 +2279,17 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
// must be used.
if (VD->hasAttr<OMPAllocateDeclAttr>()) {
const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
- const Expr *PrevAllocator = A->getAllocator();
- bool AllocatorsMatch = false;
- if (Allocator && PrevAllocator) {
+ Expr *PrevAllocator = A->getAllocator();
+ OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
+ getAllocatorKind(*this, DSAStack, PrevAllocator);
+ bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
+ if (AllocatorsMatch && Allocator && PrevAllocator) {
const Expr *AE = Allocator->IgnoreParenImpCasts();
const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
llvm::FoldingSetNodeID AEId, PAEId;
AE->Profile(AEId, Context, /*Canonical=*/true);
PAE->Profile(PAEId, Context, /*Canonical=*/true);
AllocatorsMatch = AEId == PAEId;
- } else if (!Allocator && !PrevAllocator) {
- AllocatorsMatch = true;
- } else {
- const Expr *AE = Allocator ? Allocator : PrevAllocator;
- // In this case the specified allocator must be the default one.
- AE = AE->IgnoreParenImpCasts();
- if (const auto *DRE = dyn_cast<DeclRefExpr>(AE)) {
- DeclarationName DN = DRE->getDecl()->getDeclName();
- AllocatorsMatch =
- DN.isIdentifier() &&
- DN.getAsIdentifierInfo()->isStr("omp_default_mem_alloc");
- }
}
if (!AllocatorsMatch) {
SmallString<256> AllocatorBuffer;
@@ -2314,8 +2363,8 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
!Allocator->isInstantiationDependent() &&
!Allocator->containsUnexpandedParameterPack())) &&
!VD->hasAttr<OMPAllocateDeclAttr>()) {
- Attr *A = OMPAllocateDeclAttr::CreateImplicit(Context, Allocator,
- DE->getSourceRange());
+ Attr *A = OMPAllocateDeclAttr::CreateImplicit(
+ Context, AllocatorKind, Allocator, DE->getSourceRange());
VD->addAttr(A);
if (ASTMutationListener *ML = Context.getASTMutationListener())
ML->DeclarationMarkedOpenMPAllocate(VD, A);
@@ -9375,19 +9424,46 @@ OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
}
/// Tries to find omp_allocator_handle_t type.
-static bool FindOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
- QualType &OMPAllocatorHandleT) {
+static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
+ DSAStackTy *Stack) {
+ QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
if (!OMPAllocatorHandleT.isNull())
return true;
- DeclarationName OMPAllocatorHandleTName =
- &S.getASTContext().Idents.get("omp_allocator_handle_t");
- auto *TD = dyn_cast_or_null<TypeDecl>(S.LookupSingleName(
- S.TUScope, OMPAllocatorHandleTName, Loc, Sema::LookupAnyName));
- if (!TD) {
+ // Build the predefined allocator expressions.
+ bool ErrorFound = false;
+ for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
+ I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
+ auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
+ StringRef Allocator =
+ OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
+ DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
+ auto *VD = dyn_cast_or_null<ValueDecl>(
+ S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
+ if (!VD) {
+ ErrorFound = true;
+ break;
+ }
+ QualType AllocatorType =
+ VD->getType().getNonLValueExprType(S.getASTContext());
+ ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
+ if (!Res.isUsable()) {
+ ErrorFound = true;
+ break;
+ }
+ if (OMPAllocatorHandleT.isNull())
+ OMPAllocatorHandleT = AllocatorType;
+ if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
+ ErrorFound = true;
+ break;
+ }
+ Stack->setAllocator(AllocatorKind, Res.get());
+ }
+ if (ErrorFound) {
S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
return false;
}
- OMPAllocatorHandleT = S.getASTContext().getTypeDeclType(TD);
+ OMPAllocatorHandleT.addConst();
+ Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
return true;
}
@@ -9396,13 +9472,14 @@ OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
SourceLocation EndLoc) {
// OpenMP [2.11.3, allocate Directive, Description]
// allocator is an expression of omp_allocator_handle_t type.
- if (!FindOMPAllocatorHandleT(*this, A->getExprLoc(), OMPAllocatorHandleT))
+ if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
return nullptr;
ExprResult Allocator = DefaultLvalueConversion(A);
if (Allocator.isInvalid())
return nullptr;
- Allocator = PerformImplicitConversion(Allocator.get(), OMPAllocatorHandleT,
+ Allocator = PerformImplicitConversion(Allocator.get(),
+ DSAStack->getOMPAllocatorHandleT(),
Sema::AA_Initializing,
/*AllowExplicit=*/true);
if (Allocator.isInvalid())
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index f37372fcb0..32bd82d077 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -4490,10 +4490,15 @@ void ASTDeclReader::UpdateDecl(Decl *D,
ReadSourceRange()));
break;
- case UPD_DECL_MARKED_OPENMP_ALLOCATE:
+ case UPD_DECL_MARKED_OPENMP_ALLOCATE: {
+ auto AllocatorKind =
+ static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(Record.readInt());
+ Expr *Allocator = Record.readExpr();
+ SourceRange SR = ReadSourceRange();
D->addAttr(OMPAllocateDeclAttr::CreateImplicit(
- Reader.getContext(), Record.readExpr(), ReadSourceRange()));
+ Reader.getContext(), AllocatorKind, Allocator, SR));
break;
+ }
case UPD_DECL_EXPORTED: {
unsigned SubmoduleID = readSubmoduleID();
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 03956050a3..c593dd98db 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -5290,10 +5290,13 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
D->getAttr<OMPThreadPrivateDeclAttr>()->getRange());
break;
- case UPD_DECL_MARKED_OPENMP_ALLOCATE:
- Record.AddStmt(D->getAttr<OMPAllocateDeclAttr>()->getAllocator());
- Record.AddSourceRange(D->getAttr<OMPAllocateDeclAttr>()->getRange());
+ case UPD_DECL_MARKED_OPENMP_ALLOCATE: {
+ auto *A = D->getAttr<OMPAllocateDeclAttr>();
+ Record.push_back(A->getAllocatorType());
+ Record.AddStmt(A->getAllocator());
+ Record.AddSourceRange(A->getRange());
break;
+ }
case UPD_DECL_MARKED_OPENMP_DECLARETARGET:
Record.push_back(D->getAttr<OMPDeclareTargetDeclAttr>()->getMapType());
diff --git a/test/OpenMP/allocate_allocator_messages.cpp b/test/OpenMP/allocate_allocator_messages.cpp
index db7d53d2f2..97f5d6f564 100644
--- a/test/OpenMP/allocate_allocator_messages.cpp
+++ b/test/OpenMP/allocate_allocator_messages.cpp
@@ -15,13 +15,19 @@ int sss;
#pragma omp allocate(sss) allocator(sss) // expected-error {{omp_allocator_handle_t type not found; include <omp.h>}}
typedef void **omp_allocator_handle_t;
-extern const omp_allocator_handle_t omp_thread_mem_alloc;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
struct St1{
int a;
static int b;
-#pragma omp allocate(b) allocator(sss) // expected-error {{initializing 'omp_allocator_handle_t' (aka 'void **') with an expression of incompatible type 'int'}} expected-note {{previous allocator is specified here}}
+#pragma omp allocate(b) allocator(sss) // expected-error {{initializing 'const omp_allocator_handle_t' (aka 'void **const') with an expression of incompatible type 'int'}} expected-note {{previous allocator is specified here}}
#pragma omp allocate(b)
#pragma omp allocate(b) allocator(omp_thread_mem_alloc) // expected-warning {{allocate directive specifies 'omp_thread_mem_alloc' allocator while previously used default}}
} d; // expected-note 2 {{'d' defined here}}
diff --git a/test/PCH/chain-openmp-allocate.cpp b/test/PCH/chain-openmp-allocate.cpp
index 1383d0ff27..d6daaff0db 100644
--- a/test/PCH/chain-openmp-allocate.cpp
+++ b/test/PCH/chain-openmp-allocate.cpp
@@ -14,6 +14,13 @@
typedef void **omp_allocator_handle_t;
extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
int a;
// CHECK: int a;