summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/OpenMPClause.cpp28
-rw-r--r--clang/lib/AST/StmtProfile.cpp3
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp5
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp1
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp1
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp91
-rw-r--r--clang/lib/Sema/TreeTransform.h28
-rw-r--r--clang/lib/Serialization/ASTReader.cpp13
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp8
9 files changed, 171 insertions, 7 deletions
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 7315d7c3cdb..f062c3e463a 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -135,6 +135,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_atomic_default_mem_order:
case OMPC_device_type:
case OMPC_match:
+ case OMPC_nontemporal:
break;
}
@@ -213,6 +214,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_atomic_default_mem_order:
case OMPC_device_type:
case OMPC_match:
+ case OMPC_nontemporal:
break;
}
@@ -1155,6 +1157,25 @@ OMPIsDevicePtrClause::CreateEmpty(const ASTContext &C,
return new (Mem) OMPIsDevicePtrClause(Sizes);
}
+OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ // Allocate space for nontemporal variables.
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
+ auto *Clause =
+ new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPNontemporalClause *OMPNontemporalClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
+ return new (Mem) OMPNontemporalClause(N);
+}
+
//===----------------------------------------------------------------------===//
// OpenMP clauses printing methods
//===----------------------------------------------------------------------===//
@@ -1648,3 +1669,10 @@ void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
}
}
+void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "nontemporal";
+ VisitOMPClauseList(Node, '(');
+ OS << ")";
+ }
+}
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index c94d2c54bae..56a65e8deb9 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -769,6 +769,9 @@ void OMPClauseProfiler::VisitOMPIsDevicePtrClause(
const OMPIsDevicePtrClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseProfiler::VisitOMPNontemporalClause(const OMPNontemporalClause *C) {
+ VisitOMPClauseList(C);
+}
}
void
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 6dadfce1eb8..3222db71365 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -223,6 +223,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_match:
+ case OMPC_nontemporal:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -417,6 +418,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_match:
+ case OMPC_nontemporal:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -427,6 +429,9 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
unsigned OpenMPVersion) {
assert(unsigned(DKind) <= unsigned(OMPD_unknown));
assert(CKind <= OMPC_unknown);
+ // Nontemporal clause is not supported in OpenMP < 5.0.
+ if (OpenMPVersion < 50 && CKind == OMPC_nontemporal)
+ return false;
switch (DKind) {
case OMPD_parallel:
switch (CKind) {
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 3c266a5a314..e8a3790e3b5 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4206,6 +4206,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
case OMPC_atomic_default_mem_order:
case OMPC_device_type:
case OMPC_match:
+ case OMPC_nontemporal:
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
}
}
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 9dbbcc08db8..181ed331325 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2194,6 +2194,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
case OMPC_allocate:
+ case OMPC_nontemporal:
Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
break;
case OMPC_device_type:
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index afe0f1a0dcd..915bf53d06e 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -83,7 +83,7 @@ private:
DeclRefExpr *PrivateCopy = nullptr;
};
using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
- using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
+ using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
using LCDeclInfo = std::pair<unsigned, VarDecl *>;
using LoopControlVariablesMapTy =
llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
@@ -125,7 +125,8 @@ private:
struct SharingMapTy {
DeclSAMapTy SharingMap;
DeclReductionMapTy ReductionMap;
- AlignedMapTy AlignedMap;
+ UsedRefMapTy AlignedMap;
+ UsedRefMapTy NontemporalMap;
MappedExprComponentsTy MappedExprComponents;
LoopControlVariablesMapTy LCVMap;
DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
@@ -421,6 +422,10 @@ public:
/// add it and return NULL; otherwise return previous occurrence's expression
/// for diagnostics.
const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
+ /// If 'nontemporal' declaration for given variable \a D was not seen yet,
+ /// add it and return NULL; otherwise return previous occurrence's expression
+ /// for diagnostics.
+ const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
/// Register specified variable as loop control variable.
void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
@@ -1073,6 +1078,21 @@ const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
return It->second;
}
+const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
+ const Expr *NewDE) {
+ assert(!isStackEmpty() && "Data sharing attributes stack is empty");
+ D = getCanonicalDecl(D);
+ SharingMapTy &StackElem = getTopOfStack();
+ auto It = StackElem.NontemporalMap.find(D);
+ if (It == StackElem.NontemporalMap.end()) {
+ assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
+ StackElem.NontemporalMap[D] = NewDE;
+ return nullptr;
+ }
+ assert(It->second && "Unexpected nullptr expr in the aligned map");
+ return It->second;
+}
+
void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
D = getCanonicalDecl(D);
@@ -4874,6 +4894,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_nontemporal:
continue;
case OMPC_allocator:
case OMPC_flush:
@@ -5019,8 +5040,9 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
// OpenMP [2.8.1, simd construct, Restrictions]
// A list-item cannot appear in more than one aligned clause.
if (AlignedArgs.count(CanonPVD) > 0) {
- Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
- << 1 << E->getSourceRange();
+ Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
+ << 1 << getOpenMPClauseName(OMPC_aligned)
+ << E->getSourceRange();
Diag(AlignedArgs[CanonPVD]->getExprLoc(),
diag::note_omp_explicit_dsa)
<< getOpenMPClauseName(OMPC_aligned);
@@ -5042,8 +5064,8 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
}
if (isa<CXXThisExpr>(E)) {
if (AlignedThis) {
- Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
- << 2 << E->getSourceRange();
+ Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
+ << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
<< getOpenMPClauseName(OMPC_aligned);
}
@@ -10735,6 +10757,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_atomic_default_mem_order:
case OMPC_device_type:
case OMPC_match:
+ case OMPC_nontemporal:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -11445,6 +11468,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPC_atomic_default_mem_order:
case OMPC_device_type:
case OMPC_match:
+ case OMPC_nontemporal:
llvm_unreachable("Unexpected OpenMP clause.");
}
return CaptureRegion;
@@ -11868,6 +11892,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
case OMPC_dynamic_allocators:
case OMPC_device_type:
case OMPC_match:
+ case OMPC_nontemporal:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -12048,6 +12073,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_atomic_default_mem_order:
case OMPC_device_type:
case OMPC_match:
+ case OMPC_nontemporal:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -12259,6 +12285,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_atomic_default_mem_order:
case OMPC_device_type:
case OMPC_match:
+ case OMPC_nontemporal:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -12426,6 +12453,9 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
ColonLoc, EndLoc);
break;
+ case OMPC_nontemporal:
+ Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -14553,7 +14583,8 @@ OMPClause *Sema::ActOnOpenMPAlignedClause(
// OpenMP [2.8.1, simd construct, Restrictions]
// A list-item cannot appear in more than one aligned clause.
if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
- Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
+ Diag(ELoc, diag::err_omp_used_in_clause_twice)
+ << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
<< getOpenMPClauseName(OMPC_aligned);
continue;
@@ -17122,3 +17153,49 @@ OMPClause *Sema::ActOnOpenMPAllocateClause(
return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
ColonLoc, EndLoc, Vars);
}
+
+OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ SmallVector<Expr *, 8> Vars;
+ for (Expr *RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
+ SourceLocation ELoc;
+ SourceRange ERange;
+ Expr *SimpleRefExpr = RefExpr;
+ auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
+ if (Res.second)
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ ValueDecl *D = Res.first;
+ if (!D)
+ continue;
+
+ auto *VD = dyn_cast<VarDecl>(D);
+
+ // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
+ // A list-item cannot appear in more than one nontemporal clause.
+ if (const Expr *PrevRef =
+ DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
+ Diag(ELoc, diag::err_omp_used_in_clause_twice)
+ << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
+ Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
+ << getOpenMPClauseName(OMPC_nontemporal);
+ continue;
+ }
+
+ DeclRefExpr *Ref = nullptr;
+ if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
+ Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
+ Vars.push_back((VD || !Ref || CurContext->isDependentContext())
+ ? RefExpr->IgnoreParens()
+ : Ref);
+ }
+
+ if (Vars.empty())
+ return nullptr;
+
+ return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
+ Vars);
+}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 2e4e9128506..2860db365f3 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -22,6 +22,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
@@ -2001,6 +2002,18 @@ public:
MLoc, KindLoc, EndLoc);
}
+ /// Build a new OpenMP 'nontemporal' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc,
+ EndLoc);
+ }
+
/// Rebuild the operand to an Objective-C \@synchronized statement.
///
/// By default, performs semantic analysis to build the new statement.
@@ -9266,6 +9279,21 @@ TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
}
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
+ llvm::SmallVector<Expr *, 16> Vars;
+ Vars.reserve(C->varlist_size());
+ for (auto *VE : C->varlists()) {
+ ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+ if (EVar.isInvalid())
+ return nullptr;
+ Vars.push_back(EVar.get());
+ }
+ return getDerived().RebuildOMPNontemporalClause(
+ Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+}
+
//===----------------------------------------------------------------------===//
// Expression transformation
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index a2e4e7b469c..9258a6fb126 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11698,6 +11698,9 @@ OMPClause *OMPClauseReader::readClause() {
case OMPC_allocate:
C = OMPAllocateClause::CreateEmpty(Context, Record.readInt());
break;
+ case OMPC_nontemporal:
+ C = OMPNontemporalClause::CreateEmpty(Context, Record.readInt());
+ break;
}
assert(C && "Unknown OMPClause type");
@@ -12454,3 +12457,13 @@ void OMPClauseReader::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
}
C->setComponents(Components, ListSizes);
}
+
+void OMPClauseReader::VisitOMPNontemporalClause(OMPNontemporalClause *C) {
+ C->setLParenLoc(Record.readSourceLocation());
+ unsigned NumVars = C->varlist_size();
+ SmallVector<Expr *, 16> Vars;
+ Vars.reserve(NumVars);
+ for (unsigned i = 0; i != NumVars; ++i)
+ Vars.push_back(Record.readSubExpr());
+ C->setVarRefs(Vars);
+}
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index a8ea8563a1d..a632072d01b 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/OpenMPClause.h"
#include "clang/Serialization/ASTRecordWriter.h"
#include "ASTCommon.h"
#include "ASTReaderInternals.h"
@@ -6537,3 +6538,10 @@ void OMPClauseWriter::VisitOMPAtomicDefaultMemOrderClause(
Record.AddSourceLocation(C->getLParenLoc());
Record.AddSourceLocation(C->getAtomicDefaultMemOrderKindKwLoc());
}
+
+void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) {
+ Record.push_back(C->varlist_size());
+ Record.AddSourceLocation(C->getLParenLoc());
+ for (auto *VE : C->varlists())
+ Record.AddStmt(VE);
+}
OpenPOWER on IntegriCloud