[OPENMP50]Basic parsing/sema analysis for order(concurrent) clause.
Added parsing/sema/serialization support for order(concurrent) clause in
loop|simd-based directives.
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 5ef8264..c7e7f33 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -137,6 +137,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
break;
}
@@ -216,6 +217,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
break;
}
@@ -1691,3 +1693,8 @@
OS << ")";
}
}
+
+void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
+ OS << "order(" << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getKind())
+ << ")";
+}
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 382ea5c..0b519a6 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -775,6 +775,7 @@
for (auto *E : C->private_refs())
Profiler->VisitStmt(E);
}
+void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {}
} // namespace
void
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 414ebb5..3204e22 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -180,6 +180,11 @@
#define OPENMP_LASTPRIVATE_KIND(Name) .Case(#Name, OMPC_LASTPRIVATE_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_LASTPRIVATE_unknown);
+ case OMPC_order:
+ return llvm::StringSwitch<OpenMPOrderClauseKind>(Str)
+#define OPENMP_ORDER_KIND(Name) .Case(#Name, OMPC_ORDER_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_ORDER_unknown);
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
@@ -382,6 +387,16 @@
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'lastprivate' clause type");
+ case OMPC_order:
+ switch (Type) {
+ case OMPC_ORDER_unknown:
+ return "unknown";
+#define OPENMP_ORDER_KIND(Name) \
+ case OMPC_ORDER_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'order' clause type");
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
@@ -443,6 +458,9 @@
// Nontemporal clause is not supported in OpenMP < 5.0.
if (OpenMPVersion < 50 && CKind == OMPC_nontemporal)
return false;
+ // Order clause is not supported in OpenMP < 5.0.
+ if (OpenMPVersion < 50 && CKind == OMPC_order)
+ return false;
switch (DKind) {
case OMPD_parallel:
switch (CKind) {
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index f64efd0..a84f2fe 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4463,6 +4463,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
}
}
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 1095919..ed2e52a 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2151,6 +2151,7 @@
case OMPC_default:
case OMPC_proc_bind:
case OMPC_atomic_default_mem_order:
+ case OMPC_order:
// OpenMP [2.14.3.1, Restrictions]
// Only a single default clause may be specified on a parallel, task or
// teams directive.
@@ -2159,7 +2160,7 @@
// OpenMP [5.0, Requires directive, Restrictions]
// At most one atomic_default_mem_order clause can appear
// on the directive
- if (!FirstClause) {
+ if (!FirstClause && CKind != OMPC_order) {
Diag(Tok, diag::err_omp_more_one_clause)
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
ErrorFound = true;
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index cb08079..df76b42 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -22,6 +22,7 @@
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TypeOrdering.h"
+#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Sema/Initialization.h"
@@ -3871,6 +3872,36 @@
}
}
+static bool checkOrderedOrderSpecified(Sema &S,
+ const ArrayRef<OMPClause *> Clauses) {
+ const OMPOrderedClause *Ordered = nullptr;
+ const OMPOrderClause *Order = nullptr;
+
+ for (const OMPClause *Clause : Clauses) {
+ if (Clause->getClauseKind() == OMPC_ordered)
+ Ordered = cast<OMPOrderedClause>(Clause);
+ else if (Clause->getClauseKind() == OMPC_order) {
+ Order = cast<OMPOrderClause>(Clause);
+ if (Order->getKind() != OMPC_ORDER_concurrent)
+ Order = nullptr;
+ }
+ if (Ordered && Order)
+ break;
+ }
+
+ if (Ordered && Order) {
+ S.Diag(Order->getKindKwLoc(),
+ diag::err_omp_simple_clause_incompatible_with_ordered)
+ << getOpenMPClauseName(OMPC_order)
+ << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
+ << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
+ S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
+ << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
+ return true;
+ }
+ return false;
+}
+
StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
ArrayRef<OMPClause *> Clauses) {
bool ErrorFound = false;
@@ -3941,10 +3972,18 @@
Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
? SC->getFirstScheduleModifierLoc()
: SC->getSecondScheduleModifierLoc(),
- diag::err_omp_schedule_nonmonotonic_ordered)
+ diag::err_omp_simple_clause_incompatible_with_ordered)
+ << getOpenMPClauseName(OMPC_schedule)
+ << getOpenMPSimpleClauseTypeName(OMPC_schedule,
+ OMPC_SCHEDULE_MODIFIER_nonmonotonic)
<< SourceRange(OC->getBeginLoc(), OC->getEndLoc());
ErrorFound = true;
}
+ // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
+ // If an order(concurrent) clause is present, an ordered clause may not appear
+ // on the same directive.
+ if (checkOrderedOrderSpecified(*this, Clauses))
+ ErrorFound = true;
if (!LCs.empty() && OC && OC->getNumForLoops()) {
for (const OMPLinearClause *C : LCs) {
Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
@@ -4959,6 +4998,7 @@
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
case OMPC_nontemporal:
+ case OMPC_order:
continue;
case OMPC_allocator:
case OMPC_flush:
@@ -4979,7 +5019,7 @@
DSAChecker.Visit(CC);
}
}
- for (auto &P : DSAChecker.getVarsWithInheritedDSA())
+ for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
}
for (const auto &P : VarsWithInheritedDSA) {
@@ -8588,7 +8628,7 @@
SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
<< (TC != nullptr);
- Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
+ Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
ErrorFound = true;
}
}
@@ -10822,6 +10862,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -11533,6 +11574,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
llvm_unreachable("Unexpected OpenMP clause.");
}
return CaptureRegion;
@@ -11898,6 +11940,10 @@
static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_order:
+ Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
+ ArgumentLoc, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -12043,6 +12089,24 @@
LParenLoc, EndLoc);
}
+OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
+ SourceLocation KindKwLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ if (Kind == OMPC_ORDER_unknown) {
+ static_assert(OMPC_ORDER_unknown > 0,
+ "OMPC_ORDER_unknown not greater than 0");
+ Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
+ << getListOfPossibleValues(OMPC_order, /*First=*/0,
+ /*Last=*/OMPC_ORDER_unknown)
+ << getOpenMPClauseName(OMPC_order);
+ return nullptr;
+ }
+ return new (Context)
+ OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+}
+
OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
SourceLocation StartLoc, SourceLocation LParenLoc,
@@ -12137,6 +12201,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -12349,6 +12414,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
+ case OMPC_order:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -12572,6 +12638,7 @@
case OMPC_atomic_default_mem_order:
case OMPC_device_type:
case OMPC_match:
+ case OMPC_order:
llvm_unreachable("Clause is not allowed.");
}
return Res;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 6b90a9e..c00c06e 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2016,6 +2016,19 @@
EndLoc);
}
+ /// Build a new OpenMP 'order' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPOrderClause(OpenMPOrderClauseKind Kind,
+ SourceLocation KindKwLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPOrderClause(Kind, KindKwLoc, StartLoc,
+ LParenLoc, EndLoc);
+ }
+
/// Rebuild the operand to an Objective-C \@synchronized statement.
///
/// By default, performs semantic analysis to build the new statement.
@@ -9399,6 +9412,14 @@
Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
}
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
+ return getDerived().RebuildOMPOrderClause(C->getKind(), C->getKindKwLoc(),
+ C->getBeginLoc(), C->getLParenLoc(),
+ C->getEndLoc());
+}
+
//===----------------------------------------------------------------------===//
// Expression transformation
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 3a3af77..0921190 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11810,6 +11810,9 @@
case OMPC_nontemporal:
C = OMPNontemporalClause::CreateEmpty(Context, Record.readInt());
break;
+ case OMPC_order:
+ C = new (Context) OMPOrderClause();
+ break;
}
assert(C && "Unknown OMPClause type");
@@ -12583,3 +12586,9 @@
Vars.push_back(Record.readSubExpr());
C->setPrivateRefs(Vars);
}
+
+void OMPClauseReader::VisitOMPOrderClause(OMPOrderClause *C) {
+ C->setKind(Record.readEnum<OpenMPOrderClauseKind>());
+ C->setLParenLoc(Record.readSourceLocation());
+ C->setKindKwLoc(Record.readSourceLocation());
+}
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 47aea9a..123f83a 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6563,3 +6563,10 @@
for (auto *E : C->private_refs())
Record.AddStmt(E);
}
+
+void OMPClauseWriter::VisitOMPOrderClause(OMPOrderClause *C) {
+ Record.writeEnum(C->getKind());
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getKindKwLoc());
+}
+