Skip to content

Commit 085845a

Browse files
committed
[OMP5.2] Initial support for doacross clause.
1 parent 41a1625 commit 085845a

File tree

19 files changed

+776
-233
lines changed

19 files changed

+776
-233
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9046,6 +9046,132 @@ class OMPXDynCGroupMemClause
90469046
Expr *getSize() const { return getStmtAs<Expr>(); }
90479047
};
90489048

9049+
/// This represents the 'doacross' clause for the '#pragma omp ordered'
9050+
/// directive.
9051+
///
9052+
/// \code
9053+
/// #pragma omp ordered doacross(sink: i-1, j-1)
9054+
/// \endcode
9055+
/// In this example directive '#pragma omp ordered' with clause 'doacross' with
9056+
/// a dependence-type 'sink' and loop-iteration vector expressions i-1 and j-1.
9057+
class OMPDoacrossClause final
9058+
: public OMPVarListClause<OMPDoacrossClause>,
9059+
private llvm::TrailingObjects<OMPDoacrossClause, Expr *> {
9060+
friend class OMPClauseReader;
9061+
friend OMPVarListClause;
9062+
friend TrailingObjects;
9063+
9064+
/// Dependence type (sink or source).
9065+
OpenMPDoacrossClauseModifier DepType = OMPC_DOACROSS_unknown;
9066+
9067+
/// Dependence type location.
9068+
SourceLocation DepLoc;
9069+
9070+
/// Colon location.
9071+
SourceLocation ColonLoc;
9072+
9073+
/// Number of loops, associated with the doacross clause.
9074+
unsigned NumLoops = 0;
9075+
9076+
/// Build clause with number of expressions \a N.
9077+
///
9078+
/// \param StartLoc Starting location of the clause.
9079+
/// \param LParenLoc Location of '('.
9080+
/// \param EndLoc Ending location of the clause.
9081+
/// \param N Number of expressions in the clause.
9082+
/// \param NumLoops Number of loops associated with the clause.
9083+
OMPDoacrossClause(SourceLocation StartLoc, SourceLocation LParenLoc,
9084+
SourceLocation EndLoc, unsigned N, unsigned NumLoops)
9085+
: OMPVarListClause<OMPDoacrossClause>(llvm::omp::OMPC_doacross, StartLoc,
9086+
LParenLoc, EndLoc, N),
9087+
NumLoops(NumLoops) {}
9088+
9089+
/// Build an empty clause.
9090+
///
9091+
/// \param N Number of expressions in the clause.
9092+
/// \param NumLoops Number of loops associated with the clause.
9093+
explicit OMPDoacrossClause(unsigned N, unsigned NumLoops)
9094+
: OMPVarListClause<OMPDoacrossClause>(llvm::omp::OMPC_doacross,
9095+
SourceLocation(), SourceLocation(),
9096+
SourceLocation(), N),
9097+
NumLoops(NumLoops) {}
9098+
9099+
/// Set dependence type.
9100+
void setDependenceType(OpenMPDoacrossClauseModifier M) { DepType = M; }
9101+
9102+
/// Set dependence type location.
9103+
void setDependenceLoc(SourceLocation Loc) { DepLoc = Loc; }
9104+
9105+
/// Set colon location.
9106+
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
9107+
9108+
public:
9109+
/// Creates clause with a list of expressions \a VL.
9110+
///
9111+
/// \param C AST context.
9112+
/// \param StartLoc Starting location of the clause.
9113+
/// \param LParenLoc Location of '('.
9114+
/// \param EndLoc Ending location of the clause.
9115+
/// \param DepType The dependence type.
9116+
/// \param DepLoc Location of the dependence type.
9117+
/// \param ColonLoc Location of ':'.
9118+
/// \param VL List of references to the expressions.
9119+
/// \param NumLoops Number of loops that associated with the clause.
9120+
static OMPDoacrossClause *
9121+
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
9122+
SourceLocation EndLoc, OpenMPDoacrossClauseModifier DepType,
9123+
SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
9124+
unsigned NumLoops);
9125+
9126+
/// Creates an empty clause with \a N expressions.
9127+
///
9128+
/// \param C AST context.
9129+
/// \param N The number of expressions.
9130+
/// \param NumLoops Number of loops that is associated with this clause.
9131+
static OMPDoacrossClause *CreateEmpty(const ASTContext &C, unsigned N,
9132+
unsigned NumLoops);
9133+
9134+
/// Get dependence type.
9135+
OpenMPDoacrossClauseModifier getDependenceType() const { return DepType; }
9136+
9137+
/// Get dependence type location.
9138+
SourceLocation getDependenceLoc() const { return DepLoc; }
9139+
9140+
/// Get colon location.
9141+
SourceLocation getColonLoc() const { return ColonLoc; }
9142+
9143+
/// Get number of loops associated with the clause.
9144+
unsigned getNumLoops() const { return NumLoops; }
9145+
9146+
/// Set the loop data.
9147+
void setLoopData(unsigned NumLoop, Expr *Cnt);
9148+
9149+
/// Get the loop data.
9150+
Expr *getLoopData(unsigned NumLoop);
9151+
const Expr *getLoopData(unsigned NumLoop) const;
9152+
9153+
child_range children() {
9154+
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
9155+
reinterpret_cast<Stmt **>(varlist_end()));
9156+
}
9157+
9158+
const_child_range children() const {
9159+
auto Children = const_cast<OMPDoacrossClause *>(this)->children();
9160+
return const_child_range(Children.begin(), Children.end());
9161+
}
9162+
9163+
child_range used_children() {
9164+
return child_range(child_iterator(), child_iterator());
9165+
}
9166+
const_child_range used_children() const {
9167+
return const_child_range(const_child_iterator(), const_child_iterator());
9168+
}
9169+
9170+
static bool classof(const OMPClause *T) {
9171+
return T->getClauseKind() == llvm::omp::OMPC_doacross;
9172+
}
9173+
};
9174+
90499175
} // namespace clang
90509176

90519177
#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3864,6 +3864,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPXDynCGroupMemClause(
38643864
return true;
38653865
}
38663866

3867+
template <typename Derived>
3868+
bool RecursiveASTVisitor<Derived>::VisitOMPDoacrossClause(
3869+
OMPDoacrossClause *C) {
3870+
TRY_TO(VisitOMPClauseList(C));
3871+
return true;
3872+
}
3873+
38673874
// FIXME: look at the following tricky-seeming exprs to see if we
38683875
// need to recurse on anything. These are ones that have methods
38693876
// returning decls or qualtypes or nestednamespecifier -- though I'm

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10868,7 +10868,7 @@ def note_omp_previous_named_if_clause : Note<
1086810868
def err_omp_ordered_directive_with_param : Error<
1086910869
"'ordered' directive %select{without any clauses|with 'threads' clause}0 cannot be closely nested inside ordered region with specified parameter">;
1087010870
def err_omp_ordered_directive_without_param : Error<
10871-
"'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter">;
10871+
"'ordered' directive with '%0' clause cannot be closely nested inside ordered region without specified parameter">;
1087210872
def note_omp_ordered_param : Note<
1087310873
"'ordered' clause%select{| with specified parameter}0">;
1087410874
def err_omp_expected_base_var_name : Error<
@@ -10900,7 +10900,7 @@ def note_omp_critical_hint_here : Note<
1090010900
def note_omp_critical_no_hint : Note<
1090110901
"%select{|previous }0directive with no 'hint' clause specified">;
1090210902
def err_omp_depend_clause_thread_simd : Error<
10903-
"'depend' clauses cannot be mixed with '%0' clause">;
10903+
"'%0' clauses cannot be mixed with '%1' clause">;
1090410904
def err_omp_depend_sink_expected_loop_iteration : Error<
1090510905
"expected%select{| %1}0 loop iteration variable">;
1090610906
def err_omp_depend_sink_unexpected_expr : Error<
@@ -10909,8 +10909,8 @@ def err_omp_depend_sink_expected_plus_minus : Error<
1090910909
"expected '+' or '-' operation">;
1091010910
def err_omp_taskwait_depend_mutexinoutset_not_allowed : Error<
1091110911
"'mutexinoutset' modifier not allowed in 'depend' clause on 'taskwait' directive">;
10912-
def err_omp_depend_sink_source_not_allowed : Error<
10913-
"'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">;
10912+
def err_omp_sink_and_source_not_allowed : Error<
10913+
"'%0(%select{source|sink:vec}1)' clause%select{|s}1 cannot be mixed with '%0(%select{sink:vec|source}1)' clause%select{s|}1">;
1091410914
def err_omp_depend_zero_length_array_section_not_allowed : Error<
1091510915
"zero-length array section is not allowed in 'depend' clause">;
1091610916
def err_omp_depend_sink_source_with_modifier : Error<

clang/include/clang/Basic/OpenMPKinds.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@
8080
#ifndef OPENMP_NUMTASKS_MODIFIER
8181
#define OPENMP_NUMTASKS_MODIFIER(Name)
8282
#endif
83+
#ifndef OPENMP_DOACROSS_MODIFIER
84+
#define OPENMP_DOACROSS_MODIFIER(Name)
85+
#endif
8386

8487
// Static attributes for 'schedule' clause.
8588
OPENMP_SCHEDULE_KIND(static)
@@ -201,6 +204,10 @@ OPENMP_GRAINSIZE_MODIFIER(strict)
201204
// Modifiers for the 'num_tasks' clause.
202205
OPENMP_NUMTASKS_MODIFIER(strict)
203206

207+
// Modifiers for the 'doacross' clause.
208+
OPENMP_DOACROSS_MODIFIER(source)
209+
OPENMP_DOACROSS_MODIFIER(sink)
210+
204211
#undef OPENMP_NUMTASKS_MODIFIER
205212
#undef OPENMP_GRAINSIZE_MODIFIER
206213
#undef OPENMP_BIND_KIND
@@ -224,4 +231,5 @@ OPENMP_NUMTASKS_MODIFIER(strict)
224231
#undef OPENMP_DIST_SCHEDULE_KIND
225232
#undef OPENMP_DEFAULTMAP_KIND
226233
#undef OPENMP_DEFAULTMAP_MODIFIER
234+
#undef OPENMP_DOACROSS_MODIFIER
227235

clang/include/clang/Basic/OpenMPKinds.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,13 @@ enum OpenMPNumTasksClauseModifier {
215215
OMPC_NUMTASKS_unknown
216216
};
217217

218+
/// OpenMP dependence types for 'doacross' clause.
219+
enum OpenMPDoacrossClauseModifier {
220+
#define OPENMP_DOACROSS_MODIFIER(Name) OMPC_DOACROSS_##Name,
221+
#include "clang/Basic/OpenMPKinds.def"
222+
OMPC_DOACROSS_unknown
223+
};
224+
218225
/// Contains 'interop' data for 'append_args' and 'init' clauses.
219226
class Expr;
220227
struct OMPInteropInfo final {

clang/include/clang/Sema/Sema.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11032,10 +11032,7 @@ class Sema final {
1103211032
/// Initialization of data-sharing attributes stack.
1103311033
void InitDataSharingAttributesStack();
1103411034
void DestroyDataSharingAttributesStack();
11035-
ExprResult
11036-
VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind,
11037-
bool StrictlyPositive = true,
11038-
bool SuppressExprDiags = false);
11035+
1103911036
/// Returns OpenMP nesting level for current directive.
1104011037
unsigned getOpenMPNestingLevel() const;
1104111038

@@ -11121,6 +11118,11 @@ class Sema final {
1112111118
return !OMPDeclareVariantScopes.empty();
1112211119
}
1112311120

11121+
ExprResult
11122+
VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind,
11123+
bool StrictlyPositive = true,
11124+
bool SuppressExprDiags = false);
11125+
1112411126
/// Given the potential call expression \p Call, determine if there is a
1112511127
/// specialization via the OpenMP declare variant mechanism available. If
1112611128
/// there is, return the specialized call expression, otherwise return the
@@ -12281,6 +12283,13 @@ class Sema final {
1228112283
SourceLocation LParenLoc,
1228212284
SourceLocation EndLoc);
1228312285

12286+
/// Called on well-formed 'doacross' clause.
12287+
OMPClause *
12288+
ActOnOpenMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
12289+
SourceLocation DepLoc, SourceLocation ColonLoc,
12290+
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12291+
SourceLocation LParenLoc, SourceLocation EndLoc);
12292+
1228412293
/// The kind of conversion being performed.
1228512294
enum CheckedConversionKind {
1228612295
/// An implicit conversion.

clang/lib/AST/OpenMPClause.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,52 @@ OMPBindClause::Create(const ASTContext &C, OpenMPBindClauseKind K,
16691669
OMPBindClause *OMPBindClause::CreateEmpty(const ASTContext &C) {
16701670
return new (C) OMPBindClause();
16711671
}
1672+
1673+
OMPDoacrossClause *
1674+
OMPDoacrossClause::Create(const ASTContext &C, SourceLocation StartLoc,
1675+
SourceLocation LParenLoc, SourceLocation EndLoc,
1676+
OpenMPDoacrossClauseModifier DepType,
1677+
SourceLocation DepLoc, SourceLocation ColonLoc,
1678+
ArrayRef<Expr *> VL, unsigned NumLoops) {
1679+
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + NumLoops),
1680+
alignof(OMPDoacrossClause));
1681+
OMPDoacrossClause *Clause = new (Mem)
1682+
OMPDoacrossClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
1683+
Clause->setDependenceType(DepType);
1684+
Clause->setDependenceLoc(DepLoc);
1685+
Clause->setColonLoc(ColonLoc);
1686+
Clause->setVarRefs(VL);
1687+
for (unsigned I = 0; I < NumLoops; ++I)
1688+
Clause->setLoopData(I, nullptr);
1689+
return Clause;
1690+
}
1691+
1692+
OMPDoacrossClause *OMPDoacrossClause::CreateEmpty(const ASTContext &C,
1693+
unsigned N,
1694+
unsigned NumLoops) {
1695+
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + NumLoops),
1696+
alignof(OMPDoacrossClause));
1697+
return new (Mem) OMPDoacrossClause(N, NumLoops);
1698+
}
1699+
1700+
void OMPDoacrossClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
1701+
assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1702+
auto *It = std::next(getVarRefs().end(), NumLoop);
1703+
*It = Cnt;
1704+
}
1705+
1706+
Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) {
1707+
assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1708+
auto *It = std::next(getVarRefs().end(), NumLoop);
1709+
return *It;
1710+
}
1711+
1712+
const Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) const {
1713+
assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
1714+
const auto *It = std::next(getVarRefs().end(), NumLoop);
1715+
return *It;
1716+
}
1717+
16721718
//===----------------------------------------------------------------------===//
16731719
// OpenMP clauses printing methods
16741720
//===----------------------------------------------------------------------===//
@@ -2464,6 +2510,14 @@ void OMPClausePrinter::VisitOMPXDynCGroupMemClause(
24642510
OS << ")";
24652511
}
24662512

2513+
void OMPClausePrinter::VisitOMPDoacrossClause(OMPDoacrossClause *Node) {
2514+
OS << "doacross(";
2515+
OpenMPDoacrossClauseModifier DepType = Node->getDependenceType();
2516+
OS << (DepType == OMPC_DOACROSS_source ? "source:" : "sink:");
2517+
VisitOMPClauseList(Node, ' ');
2518+
OS << ")";
2519+
}
2520+
24672521
void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,
24682522
VariantMatchInfo &VMI) const {
24692523
for (const OMPTraitSet &Set : Sets) {

clang/lib/AST/StmtProfile.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,9 @@ void OMPClauseProfiler::VisitOMPXDynCGroupMemClause(
920920
if (Expr *Size = C->getSize())
921921
Profiler->VisitStmt(Size);
922922
}
923+
void OMPClauseProfiler::VisitOMPDoacrossClause(const OMPDoacrossClause *C) {
924+
VisitOMPClauseList(C);
925+
}
923926
} // namespace
924927

925928
void

clang/lib/Basic/OpenMPKinds.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
5050
return OMPC_DEPEND_unknown;
5151
return Type;
5252
}
53+
case OMPC_doacross:
54+
return llvm::StringSwitch<OpenMPDoacrossClauseModifier>(Str)
55+
#define OPENMP_DOACROSS_MODIFIER(Name) .Case(#Name, OMPC_DOACROSS_##Name)
56+
#include "clang/Basic/OpenMPKinds.def"
57+
.Default(OMPC_DOACROSS_unknown);
5358
case OMPC_linear:
5459
return llvm::StringSwitch<OpenMPLinearClauseKind>(Str)
5560
#define OPENMP_LINEAR_KIND(Name) .Case(#Name, OMPC_LINEAR_##Name)
@@ -282,6 +287,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
282287
#include "clang/Basic/OpenMPKinds.def"
283288
}
284289
llvm_unreachable("Invalid OpenMP 'depend' clause type");
290+
case OMPC_doacross:
291+
switch (Type) {
292+
case OMPC_DOACROSS_unknown:
293+
return "unknown";
294+
#define OPENMP_DOACROSS_MODIFIER(Name) \
295+
case OMPC_DOACROSS_##Name: \
296+
return #Name;
297+
#include "clang/Basic/OpenMPKinds.def"
298+
}
299+
llvm_unreachable("Invalid OpenMP 'doacross' clause type");
285300
case OMPC_linear:
286301
switch (Type) {
287302
case OMPC_LINEAR_unknown:

0 commit comments

Comments
 (0)