Skip to content

Commit a2891f2

Browse files
committed
[OPENMP] Initial support for 'depend' clause (4.0).
Parsing and sema analysis (without support for array sections in arguments) for 'depend' clause (used in 'task' directive, OpenMP 4.0). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240409 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d4a857b commit a2891f2

20 files changed

+397
-19
lines changed

include/clang/AST/DataRecursiveASTVisitor.h

+6
Original file line numberDiff line numberDiff line change
@@ -2622,6 +2622,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
26222622
return true;
26232623
}
26242624

2625+
template <typename Derived>
2626+
bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
2627+
TRY_TO(VisitOMPClauseList(C));
2628+
return true;
2629+
}
2630+
26252631
// FIXME: look at the following tricky-seeming exprs to see if we
26262632
// need to recurse on anything. These are ones that have methods
26272633
// returning decls or qualtypes or nestednamespecifier -- though I'm

include/clang/AST/OpenMPClause.h

+88
Original file line numberDiff line numberDiff line change
@@ -2212,6 +2212,94 @@ class OMPFlushClause : public OMPVarListClause<OMPFlushClause> {
22122212
}
22132213
};
22142214

2215+
/// \brief This represents implicit clause 'depend' for the '#pragma omp task'
2216+
/// directive.
2217+
///
2218+
/// \code
2219+
/// #pragma omp task depend(in:a,b)
2220+
/// \endcode
2221+
/// In this example directive '#pragma omp task' with clause 'depend' with the
2222+
/// variables 'a' and 'b' with dependency 'in'.
2223+
///
2224+
class OMPDependClause : public OMPVarListClause<OMPDependClause> {
2225+
friend class OMPClauseReader;
2226+
/// \brief Dependency type (one of in, out, inout).
2227+
OpenMPDependClauseKind DepKind;
2228+
/// \brief Dependency type location.
2229+
SourceLocation DepLoc;
2230+
/// \brief Colon location.
2231+
SourceLocation ColonLoc;
2232+
/// \brief Build clause with number of variables \a N.
2233+
///
2234+
/// \param StartLoc Starting location of the clause.
2235+
/// \param LParenLoc Location of '('.
2236+
/// \param EndLoc Ending location of the clause.
2237+
/// \param N Number of the variables in the clause.
2238+
///
2239+
OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc,
2240+
SourceLocation EndLoc, unsigned N)
2241+
: OMPVarListClause<OMPDependClause>(OMPC_depend, StartLoc, LParenLoc,
2242+
EndLoc, N),
2243+
DepKind(OMPC_DEPEND_unknown) {}
2244+
2245+
/// \brief Build an empty clause.
2246+
///
2247+
/// \param N Number of variables.
2248+
///
2249+
explicit OMPDependClause(unsigned N)
2250+
: OMPVarListClause<OMPDependClause>(OMPC_depend, SourceLocation(),
2251+
SourceLocation(), SourceLocation(),
2252+
N),
2253+
DepKind(OMPC_DEPEND_unknown) {}
2254+
/// \brief Set dependency kind.
2255+
void setDependencyKind(OpenMPDependClauseKind K) { DepKind = K; }
2256+
2257+
/// \brief Set dependency kind and its location.
2258+
void setDependencyLoc(SourceLocation Loc) { DepLoc = Loc; }
2259+
2260+
/// \brief Set colon location.
2261+
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
2262+
2263+
public:
2264+
/// \brief Creates clause with a list of variables \a VL.
2265+
///
2266+
/// \param C AST context.
2267+
/// \param StartLoc Starting location of the clause.
2268+
/// \param LParenLoc Location of '('.
2269+
/// \param EndLoc Ending location of the clause.
2270+
/// \param DepKind Dependency type.
2271+
/// \param DepLoc Location of the dependency type.
2272+
/// \param ColonLoc Colon location.
2273+
/// \param VL List of references to the variables.
2274+
///
2275+
static OMPDependClause *
2276+
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
2277+
SourceLocation EndLoc, OpenMPDependClauseKind DepKind,
2278+
SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL);
2279+
/// \brief Creates an empty clause with \a N variables.
2280+
///
2281+
/// \param C AST context.
2282+
/// \param N The number of variables.
2283+
///
2284+
static OMPDependClause *CreateEmpty(const ASTContext &C, unsigned N);
2285+
2286+
/// \brief Get dependency type.
2287+
OpenMPDependClauseKind getDependencyKind() const { return DepKind; }
2288+
/// \brief Get dependency type location.
2289+
SourceLocation getDependencyLoc() const { return DepLoc; }
2290+
/// \brief Get colon location.
2291+
SourceLocation getColonLoc() const { return ColonLoc; }
2292+
2293+
StmtRange children() {
2294+
return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
2295+
reinterpret_cast<Stmt **>(varlist_end()));
2296+
}
2297+
2298+
static bool classof(const OMPClause *T) {
2299+
return T->getClauseKind() == OMPC_depend;
2300+
}
2301+
};
2302+
22152303
} // end namespace clang
22162304

22172305
#endif

include/clang/AST/RecursiveASTVisitor.h

+6
Original file line numberDiff line numberDiff line change
@@ -2655,6 +2655,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
26552655
return true;
26562656
}
26572657

2658+
template <typename Derived>
2659+
bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
2660+
TRY_TO(VisitOMPClauseList(C));
2661+
return true;
2662+
}
2663+
26582664
// FIXME: look at the following tricky-seeming exprs to see if we
26592665
// need to recurse on anything. These are ones that have methods
26602666
// returning decls or qualtypes or nestednamespecifier -- though I'm

include/clang/Basic/DiagnosticSemaKinds.td

+2
Original file line numberDiff line numberDiff line change
@@ -7413,6 +7413,8 @@ def err_omp_unexpected_clause_value : Error<
74137413
"expected %0 in OpenMP clause '%1'">;
74147414
def err_omp_expected_var_name : Error<
74157415
"expected variable name">;
7416+
def err_omp_expected_var_name_or_array_item : Error<
7417+
"expected variable name, array element or array section">;
74167418
def note_omp_task_predetermined_firstprivate_here : Note<
74177419
"predetermined as a firstprivate in a task construct here">;
74187420
def err_omp_clause_ref_type_arg : Error<

include/clang/Basic/OpenMPKinds.def

+11
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@
6969
#ifndef OPENMP_SCHEDULE_KIND
7070
#define OPENMP_SCHEDULE_KIND(Name)
7171
#endif
72+
#ifndef OPENMP_DEPEND_KIND
73+
#define OPENMP_DEPEND_KIND(Name)
74+
#endif
7275

7376
// OpenMP directives.
7477
OPENMP_DIRECTIVE(threadprivate)
@@ -123,6 +126,7 @@ OPENMP_CLAUSE(write, OMPWriteClause)
123126
OPENMP_CLAUSE(update, OMPUpdateClause)
124127
OPENMP_CLAUSE(capture, OMPCaptureClause)
125128
OPENMP_CLAUSE(seq_cst, OMPSeqCstClause)
129+
OPENMP_CLAUSE(depend, OMPDependClause)
126130

127131
// Clauses allowed for OpenMP directive 'parallel'.
128132
OPENMP_PARALLEL_CLAUSE(if)
@@ -195,6 +199,11 @@ OPENMP_SCHEDULE_KIND(guided)
195199
OPENMP_SCHEDULE_KIND(auto)
196200
OPENMP_SCHEDULE_KIND(runtime)
197201

202+
// Static attributes for 'depend' clause.
203+
OPENMP_DEPEND_KIND(in)
204+
OPENMP_DEPEND_KIND(out)
205+
OPENMP_DEPEND_KIND(inout)
206+
198207
// Clauses allowed for OpenMP directive 'parallel for'.
199208
OPENMP_PARALLEL_FOR_CLAUSE(if)
200209
OPENMP_PARALLEL_FOR_CLAUSE(num_threads)
@@ -248,6 +257,7 @@ OPENMP_TASK_CLAUSE(firstprivate)
248257
OPENMP_TASK_CLAUSE(shared)
249258
OPENMP_TASK_CLAUSE(untied)
250259
OPENMP_TASK_CLAUSE(mergeable)
260+
OPENMP_TASK_CLAUSE(depend)
251261

252262
// Clauses allowed for OpenMP directive 'atomic'.
253263
OPENMP_ATOMIC_CLAUSE(read)
@@ -268,6 +278,7 @@ OPENMP_TEAMS_CLAUSE(firstprivate)
268278
OPENMP_TEAMS_CLAUSE(shared)
269279
OPENMP_TEAMS_CLAUSE(reduction)
270280

281+
#undef OPENMP_DEPEND_KIND
271282
#undef OPENMP_SCHEDULE_KIND
272283
#undef OPENMP_PROC_BIND_KIND
273284
#undef OPENMP_DEFAULT_KIND

include/clang/Basic/OpenMPKinds.h

+8
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ enum OpenMPScheduleClauseKind {
6262
OMPC_SCHEDULE_unknown
6363
};
6464

65+
/// \brief OpenMP attributes for 'depend' clause.
66+
enum OpenMPDependClauseKind {
67+
#define OPENMP_DEPEND_KIND(Name) \
68+
OMPC_DEPEND_##Name,
69+
#include "clang/Basic/OpenMPKinds.def"
70+
OMPC_DEPEND_unknown
71+
};
72+
6573
OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str);
6674
const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind);
6775

include/clang/Sema/Sema.h

+13-7
Original file line numberDiff line numberDiff line change
@@ -7859,13 +7859,13 @@ class Sema {
78597859
OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
78607860
SourceLocation EndLoc);
78617861

7862-
OMPClause *
7863-
ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> Vars,
7864-
Expr *TailExpr, SourceLocation StartLoc,
7865-
SourceLocation LParenLoc, SourceLocation ColonLoc,
7866-
SourceLocation EndLoc,
7867-
CXXScopeSpec &ReductionIdScopeSpec,
7868-
const DeclarationNameInfo &ReductionId);
7862+
OMPClause *ActOnOpenMPVarListClause(
7863+
OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr,
7864+
SourceLocation StartLoc, SourceLocation LParenLoc,
7865+
SourceLocation ColonLoc, SourceLocation EndLoc,
7866+
CXXScopeSpec &ReductionIdScopeSpec,
7867+
const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
7868+
SourceLocation DepLoc);
78697869
/// \brief Called on well-formed 'private' clause.
78707870
OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
78717871
SourceLocation StartLoc,
@@ -7922,6 +7922,12 @@ class Sema {
79227922
SourceLocation StartLoc,
79237923
SourceLocation LParenLoc,
79247924
SourceLocation EndLoc);
7925+
/// \brief Called on well-formed 'depend' clause.
7926+
OMPClause *
7927+
ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc,
7928+
SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
7929+
SourceLocation StartLoc, SourceLocation LParenLoc,
7930+
SourceLocation EndLoc);
79257931

79267932
/// \brief The kind of conversion being performed.
79277933
enum CheckedConversionKind {

lib/AST/Stmt.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,30 @@ OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
15791579
return new (Mem) OMPFlushClause(N);
15801580
}
15811581

1582+
OMPDependClause *
1583+
OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,
1584+
SourceLocation LParenLoc, SourceLocation EndLoc,
1585+
OpenMPDependClauseKind DepKind, SourceLocation DepLoc,
1586+
SourceLocation ColonLoc, ArrayRef<Expr *> VL) {
1587+
void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPDependClause),
1588+
llvm::alignOf<Expr *>()) +
1589+
sizeof(Expr *) * VL.size());
1590+
OMPDependClause *Clause =
1591+
new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size());
1592+
Clause->setVarRefs(VL);
1593+
Clause->setDependencyKind(DepKind);
1594+
Clause->setDependencyLoc(DepLoc);
1595+
Clause->setColonLoc(ColonLoc);
1596+
return Clause;
1597+
}
1598+
1599+
OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) {
1600+
void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPDependClause),
1601+
llvm::alignOf<Expr *>()) +
1602+
sizeof(Expr *) * N);
1603+
return new (Mem) OMPDependClause(N);
1604+
}
1605+
15821606
const OMPClause *
15831607
OMPExecutableDirective::getSingleClause(OpenMPClauseKind K) const {
15841608
auto &&I = getClausesOfKind(K);

lib/AST/StmtPrinter.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,17 @@ void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
799799
OS << ")";
800800
}
801801
}
802+
803+
void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
804+
if (!Node->varlist_empty()) {
805+
OS << "depend(";
806+
OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
807+
Node->getDependencyKind())
808+
<< " :";
809+
VisitOMPClauseList(Node, ' ');
810+
OS << ")";
811+
}
812+
}
802813
}
803814

804815
//===----------------------------------------------------------------------===//

lib/AST/StmtProfile.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,9 @@ OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
425425
void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
426426
VisitOMPClauseList(C);
427427
}
428+
void OMPClauseProfiler::VisitOMPDependClause(const OMPDependClause *C) {
429+
VisitOMPClauseList(C);
430+
}
428431
}
429432

430433
void

lib/Basic/OpenMPKinds.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
9191
#define OPENMP_SCHEDULE_KIND(Name) .Case(#Name, OMPC_SCHEDULE_##Name)
9292
#include "clang/Basic/OpenMPKinds.def"
9393
.Default(OMPC_SCHEDULE_unknown);
94+
case OMPC_depend:
95+
return llvm::StringSwitch<OpenMPDependClauseKind>(Str)
96+
#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)
97+
#include "clang/Basic/OpenMPKinds.def"
98+
.Default(OMPC_DEPEND_unknown);
9499
case OMPC_unknown:
95100
case OMPC_threadprivate:
96101
case OMPC_if:
@@ -152,6 +157,15 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
152157
#define OPENMP_SCHEDULE_KIND(Name) \
153158
case OMPC_SCHEDULE_##Name: \
154159
return #Name;
160+
#include "clang/Basic/OpenMPKinds.def"
161+
}
162+
case OMPC_depend:
163+
switch (Type) {
164+
case OMPC_DEPEND_unknown:
165+
return "unknown";
166+
#define OPENMP_DEPEND_KIND(Name) \
167+
case OMPC_DEPEND_##Name: \
168+
return #Name;
155169
#include "clang/Basic/OpenMPKinds.def"
156170
}
157171
llvm_unreachable("Invalid OpenMP 'schedule' clause type");

lib/CodeGen/CGStmtOpenMP.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -2041,6 +2041,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
20412041
case OMPC_nowait:
20422042
case OMPC_untied:
20432043
case OMPC_threadprivate:
2044+
case OMPC_depend:
20442045
case OMPC_mergeable:
20452046
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
20462047
}

lib/Parse/ParseOpenMP.cpp

+32-3
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
453453
case OMPC_copyin:
454454
case OMPC_copyprivate:
455455
case OMPC_flush:
456+
case OMPC_depend:
456457
Clause = ParseOpenMPVarListClause(CKind);
457458
break;
458459
case OMPC_unknown:
@@ -674,6 +675,8 @@ static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
674675
/// 'copyprivate' '(' list ')'
675676
/// flush-clause:
676677
/// 'flush' '(' list ')'
678+
/// depend-clause:
679+
/// 'depend' '(' in | out | inout : list ')'
677680
///
678681
OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
679682
SourceLocation Loc = Tok.getLocation();
@@ -683,6 +686,9 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
683686
CXXScopeSpec ReductionIdScopeSpec;
684687
UnqualifiedId ReductionId;
685688
bool InvalidReductionId = false;
689+
OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
690+
SourceLocation DepLoc;
691+
686692
// Parse '('.
687693
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
688694
if (T.expectAndConsume(diag::err_expected_lparen_after,
@@ -706,10 +712,30 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
706712
} else {
707713
Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
708714
}
715+
} else if (Kind == OMPC_depend) {
716+
// Handle dependency type for depend clause.
717+
ColonProtectionRAIIObject ColonRAII(*this);
718+
DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
719+
Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
720+
DepLoc = Tok.getLocation();
721+
722+
if (DepKind == OMPC_DEPEND_unknown) {
723+
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
724+
StopBeforeMatch);
725+
} else {
726+
ConsumeToken();
727+
}
728+
if (Tok.is(tok::colon)) {
729+
ColonLoc = ConsumeToken();
730+
} else {
731+
Diag(Tok, diag::warn_pragma_expected_colon) << "dependency type";
732+
}
709733
}
710734

711735
SmallVector<Expr *, 5> Vars;
712-
bool IsComma = !InvalidReductionId;
736+
bool IsComma = ((Kind != OMPC_reduction) && (Kind != OMPC_depend)) ||
737+
((Kind == OMPC_reduction) && !InvalidReductionId) ||
738+
((Kind == OMPC_depend) && DepKind != OMPC_DEPEND_unknown);
713739
const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
714740
while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
715741
Tok.isNot(tok::annot_pragma_openmp_end))) {
@@ -753,13 +779,16 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
753779

754780
// Parse ')'.
755781
T.consumeClose();
756-
if (Vars.empty() || (MustHaveTail && !TailExpr) || InvalidReductionId)
782+
if ((Kind == OMPC_depend && DepKind != OMPC_DEPEND_unknown && Vars.empty()) ||
783+
(Kind != OMPC_depend && Vars.empty()) || (MustHaveTail && !TailExpr) ||
784+
InvalidReductionId)
757785
return nullptr;
758786

759787
return Actions.ActOnOpenMPVarListClause(
760788
Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
761789
ReductionIdScopeSpec,
762790
ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
763-
: DeclarationNameInfo());
791+
: DeclarationNameInfo(),
792+
DepKind, DepLoc);
764793
}
765794

0 commit comments

Comments
 (0)