Skip to content

Commit 567a660

Browse files
committed
[OpenMP 5.2] Initial parsing and semantic analysis suppport for 'step' modifier on 'linear' clause
Reference: (1) OpenMP 5.2 Specification - Seciton 5.4.6 Differential revision: https://reviews.llvm.org/D159546
1 parent a3c6875 commit 567a660

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+829
-259
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3918,6 +3918,9 @@ class OMPLinearClause final
39183918
/// Location of ':'.
39193919
SourceLocation ColonLoc;
39203920

3921+
/// Location of 'step' modifier.
3922+
SourceLocation StepModifierLoc;
3923+
39213924
/// Sets the linear step for clause.
39223925
void setStep(Expr *Step) { *(getFinals().end()) = Step; }
39233926

@@ -3929,16 +3932,18 @@ class OMPLinearClause final
39293932
/// \param StartLoc Starting location of the clause.
39303933
/// \param LParenLoc Location of '('.
39313934
/// \param ColonLoc Location of ':'.
3935+
/// \param StepModifierLoc Location of 'step' modifier.
39323936
/// \param EndLoc Ending location of the clause.
39333937
/// \param NumVars Number of variables.
39343938
OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
39353939
OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
3936-
SourceLocation ColonLoc, SourceLocation EndLoc,
3937-
unsigned NumVars)
3940+
SourceLocation ColonLoc, SourceLocation StepModifierLoc,
3941+
SourceLocation EndLoc, unsigned NumVars)
39383942
: OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear, StartLoc,
39393943
LParenLoc, EndLoc, NumVars),
39403944
OMPClauseWithPostUpdate(this), Modifier(Modifier),
3941-
ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {}
3945+
ModifierLoc(ModifierLoc), ColonLoc(ColonLoc),
3946+
StepModifierLoc(StepModifierLoc) {}
39423947

39433948
/// Build an empty clause.
39443949
///
@@ -4017,6 +4022,7 @@ class OMPLinearClause final
40174022
/// \param Modifier Modifier of 'linear' clause.
40184023
/// \param ModifierLoc Modifier location.
40194024
/// \param ColonLoc Location of ':'.
4025+
/// \param StepModifierLoc Location of 'step' modifier.
40204026
/// \param EndLoc Ending location of the clause.
40214027
/// \param VL List of references to the variables.
40224028
/// \param PL List of private copies of original variables.
@@ -4030,9 +4036,10 @@ class OMPLinearClause final
40304036
static OMPLinearClause *
40314037
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
40324038
OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
4033-
SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
4034-
ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
4035-
Stmt *PreInit, Expr *PostUpdate);
4039+
SourceLocation ColonLoc, SourceLocation StepModifierLoc,
4040+
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL,
4041+
ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,
4042+
Expr *PostUpdate);
40364043

40374044
/// Creates an empty clause with the place for \a NumVars variables.
40384045
///
@@ -4055,9 +4062,15 @@ class OMPLinearClause final
40554062
/// Sets the location of ':'.
40564063
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
40574064

4065+
/// Sets the location of 'step' modifier.
4066+
void setStepModifierLoc(SourceLocation Loc) { StepModifierLoc = Loc; }
4067+
40584068
/// Returns the location of ':'.
40594069
SourceLocation getColonLoc() const { return ColonLoc; }
40604070

4071+
/// Returns the location of 'step' modifier.
4072+
SourceLocation getStepModifierLoc() const { return StepModifierLoc; }
4073+
40614074
/// Returns linear step.
40624075
Expr *getStep() { return *(getFinals().end()); }
40634076

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,6 +1348,8 @@ def warn_pragma_omp_ignored : Warning<
13481348
def warn_omp_extra_tokens_at_eol : Warning<
13491349
"extra tokens at the end of '#pragma omp %0' are ignored">,
13501350
InGroup<ExtraTokens>;
1351+
def err_omp_multiple_step_or_linear_modifier : Error<
1352+
"multiple %select{'step size'|'linear modifier'}0 found in linear clause">;
13511353
def warn_pragma_expected_colon_r_paren : Warning<
13521354
"missing ':' or ')' after %0 - ignoring">, InGroup<IgnoredPragmas>;
13531355
def err_omp_unknown_directive : Error<

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11028,6 +11028,8 @@ def err_omp_wrong_linear_modifier : Error<
1102811028
"expected %select{'val' modifier|one of 'ref', val' or 'uval' modifiers}0">;
1102911029
def err_omp_wrong_linear_modifier_non_reference : Error<
1103011030
"variable of non-reference type %0 can be used only with 'val' modifier, but used with '%1'">;
11031+
def err_omp_step_simple_modifier_exclusive : Error<
11032+
"step simple modifier is exclusive and can't be use with 'val', 'uval' or 'ref' modifier">;
1103111033
def err_omp_wrong_simdlen_safelen_values : Error<
1103211034
"the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter">;
1103311035
def err_omp_wrong_if_directive_name_modifier : Error<

clang/include/clang/Basic/OpenMPKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ OPENMP_DEPEND_KIND(inoutallmemory)
131131
OPENMP_LINEAR_KIND(val)
132132
OPENMP_LINEAR_KIND(ref)
133133
OPENMP_LINEAR_KIND(uval)
134+
OPENMP_LINEAR_KIND(step)
134135

135136
// Modifiers for 'atomic_default_mem_order' clause.
136137
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst)

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12307,6 +12307,8 @@ class Sema final {
1230712307
bool IsMapTypeImplicit = false;
1230812308
SourceLocation ExtraModifierLoc;
1230912309
SourceLocation OmpAllMemoryLoc;
12310+
SourceLocation
12311+
StepModifierLoc; /// 'step' modifier location for linear clause
1231012312
};
1231112313

1231212314
OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
@@ -12371,11 +12373,11 @@ class Sema final {
1237112373
const DeclarationNameInfo &ReductionId,
1237212374
ArrayRef<Expr *> UnresolvedReductions = std::nullopt);
1237312375
/// Called on well-formed 'linear' clause.
12374-
OMPClause *
12375-
ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
12376-
SourceLocation StartLoc, SourceLocation LParenLoc,
12377-
OpenMPLinearClauseKind LinKind, SourceLocation LinLoc,
12378-
SourceLocation ColonLoc, SourceLocation EndLoc);
12376+
OMPClause *ActOnOpenMPLinearClause(
12377+
ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
12378+
SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
12379+
SourceLocation LinLoc, SourceLocation ColonLoc,
12380+
SourceLocation StepModifierLoc, SourceLocation EndLoc);
1237912381
/// Called on well-formed 'aligned' clause.
1238012382
OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList,
1238112383
Expr *Alignment,

clang/lib/AST/OpenMPClause.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -583,15 +583,17 @@ void OMPLinearClause::setUsedExprs(ArrayRef<Expr *> UE) {
583583
OMPLinearClause *OMPLinearClause::Create(
584584
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
585585
OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
586-
SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
587-
ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
588-
Stmt *PreInit, Expr *PostUpdate) {
586+
SourceLocation ColonLoc, SourceLocation StepModifierLoc,
587+
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL,
588+
ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,
589+
Expr *PostUpdate) {
589590
// Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
590591
// (Step and CalcStep), list of used expression + step.
591592
void *Mem =
592593
C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2 + VL.size() + 1));
593-
OMPLinearClause *Clause = new (Mem) OMPLinearClause(
594-
StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size());
594+
OMPLinearClause *Clause =
595+
new (Mem) OMPLinearClause(StartLoc, LParenLoc, Modifier, ModifierLoc,
596+
ColonLoc, StepModifierLoc, EndLoc, VL.size());
595597
Clause->setVarRefs(VL);
596598
Clause->setPrivates(PL);
597599
Clause->setInits(IL);
@@ -2207,16 +2209,20 @@ void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
22072209
void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
22082210
if (!Node->varlist_empty()) {
22092211
OS << "linear";
2212+
VisitOMPClauseList(Node, '(');
2213+
if (Node->getModifierLoc().isValid() || Node->getStep() != nullptr) {
2214+
OS << ": ";
2215+
}
22102216
if (Node->getModifierLoc().isValid()) {
2211-
OS << '('
2212-
<< getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
2217+
OS << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
22132218
}
2214-
VisitOMPClauseList(Node, '(');
2215-
if (Node->getModifierLoc().isValid())
2216-
OS << ')';
22172219
if (Node->getStep() != nullptr) {
2218-
OS << ": ";
2220+
if (Node->getModifierLoc().isValid()) {
2221+
OS << ", ";
2222+
}
2223+
OS << "step(";
22192224
Node->getStep()->printPretty(OS, nullptr, Policy, 0);
2225+
OS << ")";
22202226
}
22212227
OS << ")";
22222228
}

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4401,6 +4401,25 @@ bool Parser::ParseOpenMPReservedLocator(OpenMPClauseKind Kind,
44014401
return false;
44024402
}
44034403

4404+
/// Parse step size expression. Returns true if parsing is successfull,
4405+
/// otherwise returns false.
4406+
static bool parseStepSize(Parser &P, Sema::OpenMPVarListDataTy &Data,
4407+
OpenMPClauseKind CKind, SourceLocation ELoc) {
4408+
ExprResult Tail = P.ParseAssignmentExpression();
4409+
Sema &Actions = P.getActions();
4410+
Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc,
4411+
/*DiscardedValue*/ false);
4412+
if (Tail.isUsable()) {
4413+
Data.DepModOrTailExpr = Tail.get();
4414+
Token CurTok = P.getCurToken();
4415+
if (CurTok.isNot(tok::r_paren) && CurTok.isNot(tok::comma)) {
4416+
P.Diag(CurTok, diag::err_expected_punc) << "step expression";
4417+
}
4418+
return true;
4419+
}
4420+
return false;
4421+
}
4422+
44044423
/// Parses clauses with list.
44054424
bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
44064425
OpenMPClauseKind Kind,
@@ -4763,19 +4782,76 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
47634782
if (NeedRParenForLinear)
47644783
LinearT.consumeClose();
47654784

4766-
// Parse ':' linear-step (or ':' alignment).
4785+
// Parse ':' linear modifiers (val, uval, ref or step(step-size))
4786+
// or parse ':' alignment.
47674787
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
4788+
bool StepFound = false;
4789+
bool ModifierFound = false;
47684790
if (MustHaveTail) {
47694791
Data.ColonLoc = Tok.getLocation();
47704792
SourceLocation ELoc = ConsumeToken();
4771-
ExprResult Tail = ParseAssignmentExpression();
4772-
Tail =
4773-
Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
4774-
if (Tail.isUsable())
4775-
Data.DepModOrTailExpr = Tail.get();
4776-
else
4777-
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4778-
StopBeforeMatch);
4793+
4794+
if (getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
4795+
while (Tok.isNot(tok::r_paren)) {
4796+
if (Tok.is(tok::identifier)) {
4797+
// identifier could be a linear kind (val, uval, ref) or step
4798+
// modifier or step size
4799+
OpenMPLinearClauseKind LinKind =
4800+
static_cast<OpenMPLinearClauseKind>(getOpenMPSimpleClauseType(
4801+
Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
4802+
getLangOpts()));
4803+
4804+
if (LinKind == OMPC_LINEAR_step) {
4805+
if (StepFound)
4806+
Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
4807+
4808+
BalancedDelimiterTracker StepT(*this, tok::l_paren,
4809+
tok::annot_pragma_openmp_end);
4810+
SourceLocation StepModifierLoc = ConsumeToken();
4811+
// parse '('
4812+
if (StepT.consumeOpen())
4813+
Diag(StepModifierLoc, diag::err_expected_lparen_after) << "step";
4814+
4815+
// parse step size expression
4816+
StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation());
4817+
if (StepFound)
4818+
Data.StepModifierLoc = StepModifierLoc;
4819+
4820+
// parse ')'
4821+
StepT.consumeClose();
4822+
} else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
4823+
if (ModifierFound)
4824+
Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
4825+
4826+
Data.ExtraModifier = LinKind;
4827+
Data.ExtraModifierLoc = ConsumeToken();
4828+
ModifierFound = true;
4829+
} else {
4830+
StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation());
4831+
}
4832+
} else {
4833+
// parse an integer expression as step size
4834+
StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation());
4835+
}
4836+
4837+
if (Tok.is(tok::comma))
4838+
ConsumeToken();
4839+
if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
4840+
break;
4841+
}
4842+
if (!StepFound && !ModifierFound)
4843+
Diag(ELoc, diag::err_expected_expression);
4844+
} else {
4845+
// for OMPC_aligned and OMPC_linear (with OpenMP <= 5.1)
4846+
ExprResult Tail = ParseAssignmentExpression();
4847+
Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc,
4848+
/*DiscardedValue*/ false);
4849+
if (Tail.isUsable())
4850+
Data.DepModOrTailExpr = Tail.get();
4851+
else
4852+
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4853+
StopBeforeMatch);
4854+
}
47794855
}
47804856

47814857
// Parse ')'.
@@ -4787,8 +4863,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
47874863
ExitScope();
47884864
return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
47894865
Vars.empty()) ||
4790-
(MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId ||
4791-
IsInvalidMapperModifier || InvalidIterator;
4866+
(MustHaveTail && !Data.DepModOrTailExpr && StepFound) ||
4867+
InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
47924868
}
47934869

47944870
/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18049,7 +18049,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
1804918049
Res = ActOnOpenMPLinearClause(
1805018050
VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
1805118051
static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
18052-
ColonLoc, EndLoc);
18052+
ColonLoc, Data.StepModifierLoc, EndLoc);
1805318053
break;
1805418054
case OMPC_aligned:
1805518055
Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
@@ -20134,7 +20134,7 @@ OMPClause *Sema::ActOnOpenMPInReductionClause(
2013420134
bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
2013520135
SourceLocation LinLoc) {
2013620136
if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
20137-
LinKind == OMPC_LINEAR_unknown) {
20137+
LinKind == OMPC_LINEAR_unknown || LinKind == OMPC_LINEAR_step) {
2013820138
Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
2013920139
return true;
2014020140
}
@@ -20186,12 +20186,19 @@ bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
2018620186
OMPClause *Sema::ActOnOpenMPLinearClause(
2018720187
ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
2018820188
SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
20189-
SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
20189+
SourceLocation LinLoc, SourceLocation ColonLoc,
20190+
SourceLocation StepModifierLoc, SourceLocation EndLoc) {
2019020191
SmallVector<Expr *, 8> Vars;
2019120192
SmallVector<Expr *, 8> Privates;
2019220193
SmallVector<Expr *, 8> Inits;
2019320194
SmallVector<Decl *, 4> ExprCaptures;
2019420195
SmallVector<Expr *, 4> ExprPostUpdates;
20196+
// OpenMP 5.2 [Section 5.4.6, linear clause]
20197+
// step-simple-modifier is exclusive, can't be used with 'val', 'uval', or
20198+
// 'ref'
20199+
if (LinLoc.isValid() && StepModifierLoc.isInvalid() && Step &&
20200+
getLangOpts().OpenMP >= 52)
20201+
Diag(Step->getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
2019520202
if (CheckOpenMPLinearModifier(LinKind, LinLoc))
2019620203
LinKind = OMPC_LINEAR_val;
2019720204
for (Expr *RefExpr : VarList) {
@@ -20311,8 +20318,8 @@ OMPClause *Sema::ActOnOpenMPLinearClause(
2031120318
}
2031220319

2031320320
return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
20314-
ColonLoc, EndLoc, Vars, Privates, Inits,
20315-
StepExpr, CalcStepExpr,
20321+
ColonLoc, StepModifierLoc, EndLoc, Vars,
20322+
Privates, Inits, StepExpr, CalcStepExpr,
2031620323
buildPreInits(Context, ExprCaptures),
2031720324
buildPostUpdate(*this, ExprPostUpdates));
2031820325
}

clang/lib/Sema/TreeTransform.h

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,16 +1908,14 @@ class TreeTransform {
19081908
///
19091909
/// By default, performs semantic analysis to build the new OpenMP clause.
19101910
/// Subclasses may override this routine to provide different behavior.
1911-
OMPClause *RebuildOMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
1912-
SourceLocation StartLoc,
1913-
SourceLocation LParenLoc,
1914-
OpenMPLinearClauseKind Modifier,
1915-
SourceLocation ModifierLoc,
1916-
SourceLocation ColonLoc,
1917-
SourceLocation EndLoc) {
1911+
OMPClause *RebuildOMPLinearClause(
1912+
ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1913+
SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1914+
SourceLocation ModifierLoc, SourceLocation ColonLoc,
1915+
SourceLocation StepModifierLoc, SourceLocation EndLoc) {
19181916
return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc,
19191917
Modifier, ModifierLoc, ColonLoc,
1920-
EndLoc);
1918+
StepModifierLoc, EndLoc);
19211919
}
19221920

19231921
/// Build a new OpenMP 'aligned' clause.
@@ -10287,7 +10285,8 @@ TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
1028710285
return nullptr;
1028810286
return getDerived().RebuildOMPLinearClause(
1028910287
Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10290-
C->getModifierLoc(), C->getColonLoc(), C->getEndLoc());
10288+
C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
10289+
C->getEndLoc());
1029110290
}
1029210291

1029310292
template <typename Derived>

0 commit comments

Comments
 (0)