Skip to content

Commit b0de656

Browse files
David PaganAaronBallman
authored andcommitted
Initial parsing/sema for 'align' clause
Added basic parsing/sema/serialization support for 'align' clause for use with 'allocate' directive.
1 parent b702276 commit b0de656

File tree

20 files changed

+405
-18
lines changed

20 files changed

+405
-18
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,81 @@ class OMPAllocatorClause : public OMPClause {
322322
}
323323
};
324324

325+
/// This represents the 'align' clause in the '#pragma omp allocate'
326+
/// directive.
327+
///
328+
/// \code
329+
/// #pragma omp allocate(a) allocator(omp_default_mem_alloc) align(8)
330+
/// \endcode
331+
/// In this example directive '#pragma omp allocate' has simple 'allocator'
332+
/// clause with the allocator 'omp_default_mem_alloc' and align clause with
333+
/// value of 8.
334+
class OMPAlignClause final : public OMPClause {
335+
friend class OMPClauseReader;
336+
337+
/// Location of '('.
338+
SourceLocation LParenLoc;
339+
340+
/// Alignment specified with align clause.
341+
Stmt *Alignment = nullptr;
342+
343+
/// Set alignment value.
344+
void setAlignment(Expr *A) { Alignment = A; }
345+
346+
/// Sets the location of '('.
347+
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
348+
349+
/// Build 'align' clause with the given alignment
350+
///
351+
/// \param A Alignment value.
352+
/// \param StartLoc Starting location of the clause.
353+
/// \param LParenLoc Location of '('.
354+
/// \param EndLoc Ending location of the clause.
355+
OMPAlignClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
356+
SourceLocation EndLoc)
357+
: OMPClause(llvm::omp::OMPC_align, StartLoc, EndLoc),
358+
LParenLoc(LParenLoc), Alignment(A) {}
359+
360+
/// Build an empty clause.
361+
OMPAlignClause()
362+
: OMPClause(llvm::omp::OMPC_align, SourceLocation(), SourceLocation()) {}
363+
364+
public:
365+
/// Build 'align' clause with the given alignment
366+
///
367+
/// \param A Alignment value.
368+
/// \param StartLoc Starting location of the clause.
369+
/// \param LParenLoc Location of '('.
370+
/// \param EndLoc Ending location of the clause.
371+
static OMPAlignClause *Create(const ASTContext &C, Expr *A,
372+
SourceLocation StartLoc,
373+
SourceLocation LParenLoc,
374+
SourceLocation EndLoc);
375+
376+
/// Returns the location of '('.
377+
SourceLocation getLParenLoc() const { return LParenLoc; }
378+
379+
/// Returns alignment
380+
Expr *getAlignment() const { return cast_or_null<Expr>(Alignment); }
381+
382+
child_range children() { return child_range(&Alignment, &Alignment + 1); }
383+
384+
const_child_range children() const {
385+
return const_child_range(&Alignment, &Alignment + 1);
386+
}
387+
388+
child_range used_children() {
389+
return child_range(child_iterator(), child_iterator());
390+
}
391+
const_child_range used_children() const {
392+
return const_child_range(const_child_iterator(), const_child_iterator());
393+
}
394+
395+
static bool classof(const OMPClause *T) {
396+
return T->getClauseKind() == llvm::omp::OMPC_align;
397+
}
398+
};
399+
325400
/// This represents clause 'allocate' in the '#pragma omp ...' directives.
326401
///
327402
/// \code

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3093,6 +3093,12 @@ RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
30933093
return true;
30943094
}
30953095

3096+
template <typename Derived>
3097+
bool RecursiveASTVisitor<Derived>::VisitOMPAlignClause(OMPAlignClause *C) {
3098+
TRY_TO(TraverseStmt(C->getAlignment()));
3099+
return true;
3100+
}
3101+
30963102
template <typename Derived>
30973103
bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
30983104
TRY_TO(TraverseStmt(C->getSafelen()));

clang/include/clang/Basic/Attr.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3683,7 +3683,8 @@ def OMPAllocateDecl : InheritableAttr {
36833683
"OMPCGroupMemAlloc", "OMPPTeamMemAlloc", "OMPThreadMemAlloc",
36843684
"OMPUserDefinedMemAlloc"
36853685
]>,
3686-
ExprArgument<"Allocator">
3686+
ExprArgument<"Allocator">,
3687+
ExprArgument<"Alignment">
36873688
];
36883689
let Documentation = [Undocumented];
36893690
}

clang/include/clang/Sema/Sema.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11034,6 +11034,10 @@ class Sema final {
1103411034
SourceLocation StartLoc,
1103511035
SourceLocation LParenLoc,
1103611036
SourceLocation EndLoc);
11037+
/// Called on well-formed 'align' clause.
11038+
OMPClause *ActOnOpenMPAlignClause(Expr *Alignment, SourceLocation StartLoc,
11039+
SourceLocation LParenLoc,
11040+
SourceLocation EndLoc);
1103711041
/// Called on well-formed 'safelen' clause.
1103811042
OMPClause *ActOnOpenMPSafelenClause(Expr *Length,
1103911043
SourceLocation StartLoc,

clang/lib/AST/DeclPrinter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,10 +1662,11 @@ void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
16621662
Out << ")";
16631663
}
16641664
if (!D->clauselist_empty()) {
1665-
Out << " ";
16661665
OMPClausePrinter Printer(Out, Policy);
1667-
for (OMPClause *C : D->clauselists())
1666+
for (OMPClause *C : D->clauselists()) {
1667+
Out << " ";
16681668
Printer.Visit(C);
1669+
}
16691670
}
16701671
}
16711672

clang/lib/AST/OpenMPClause.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,13 @@ OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
629629
return new (Mem) OMPAlignedClause(NumVars);
630630
}
631631

632+
OMPAlignClause *OMPAlignClause::Create(const ASTContext &C, Expr *A,
633+
SourceLocation StartLoc,
634+
SourceLocation LParenLoc,
635+
SourceLocation EndLoc) {
636+
return new (C) OMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
637+
}
638+
632639
void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
633640
assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
634641
"not the same as the "
@@ -1622,6 +1629,12 @@ void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
16221629
OS << ")";
16231630
}
16241631

1632+
void OMPClausePrinter::VisitOMPAlignClause(OMPAlignClause *Node) {
1633+
OS << "align(";
1634+
Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
1635+
OS << ")";
1636+
}
1637+
16251638
void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
16261639
OS << "safelen(";
16271640
Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);

clang/lib/AST/StmtProfile.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,11 @@ void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
452452
Profiler->VisitStmt(C->getNumThreads());
453453
}
454454

455+
void OMPClauseProfiler::VisitOMPAlignClause(const OMPAlignClause *C) {
456+
if (C->getAlignment())
457+
Profiler->VisitStmt(C->getAlignment());
458+
}
459+
455460
void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) {
456461
if (C->getSafelen())
457462
Profiler->VisitStmt(C->getSafelen());

clang/lib/CodeGen/CGStmtOpenMP.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5993,6 +5993,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
59935993
case OMPC_append_args:
59945994
case OMPC_memory_order:
59955995
case OMPC_bind:
5996+
case OMPC_align:
59965997
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
59975998
}
59985999
}

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,6 +3105,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
31053105
case OMPC_nocontext:
31063106
case OMPC_filter:
31073107
case OMPC_partial:
3108+
case OMPC_align:
31083109
// OpenMP [2.5, Restrictions]
31093110
// At most one num_threads clause can appear on the directive.
31103111
// OpenMP [2.8.1, simd construct, Restrictions]
@@ -3362,6 +3363,9 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
33623363
/// detach-clause:
33633364
/// 'detach' '(' event-handler-expression ')'
33643365
///
3366+
/// align-clause
3367+
/// 'align' '(' positive-integer-constant ')'
3368+
///
33653369
OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
33663370
bool ParseOnly) {
33673371
SourceLocation Loc = ConsumeToken();

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3130,16 +3130,22 @@ static bool checkPreviousOMPAllocateAttribute(
31303130
static void
31313131
applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
31323132
OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3133-
Expr *Allocator, SourceRange SR) {
3133+
Expr *Allocator, Expr *Alignment, SourceRange SR) {
31343134
if (VD->hasAttr<OMPAllocateDeclAttr>())
31353135
return;
3136+
if (Alignment &&
3137+
(Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3138+
Alignment->isInstantiationDependent() ||
3139+
Alignment->containsUnexpandedParameterPack()))
3140+
// Apply later when we have a usable value.
3141+
return;
31363142
if (Allocator &&
31373143
(Allocator->isTypeDependent() || Allocator->isValueDependent() ||
31383144
Allocator->isInstantiationDependent() ||
31393145
Allocator->containsUnexpandedParameterPack()))
31403146
return;
31413147
auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3142-
Allocator, SR);
3148+
Allocator, Alignment, SR);
31433149
VD->addAttr(A);
31443150
if (ASTMutationListener *ML = S.Context.getASTMutationListener())
31453151
ML->DeclarationMarkedOpenMPAllocate(VD, A);
@@ -3148,7 +3154,8 @@ applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
31483154
Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
31493155
SourceLocation Loc, ArrayRef<Expr *> VarList,
31503156
ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3151-
assert(Clauses.size() <= 1 && "Expected at most one clause.");
3157+
assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3158+
Expr *Alignment = nullptr;
31523159
Expr *Allocator = nullptr;
31533160
if (Clauses.empty()) {
31543161
// OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
@@ -3159,7 +3166,13 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
31593166
!DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
31603167
targetDiag(Loc, diag::err_expected_allocator_clause);
31613168
} else {
3162-
Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3169+
for (const OMPClause *C : Clauses)
3170+
if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3171+
Allocator = AC->getAllocator();
3172+
else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3173+
Alignment = AC->getAlignment();
3174+
else
3175+
llvm_unreachable("Unexpected clause on allocate directive");
31633176
}
31643177
OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
31653178
getAllocatorKind(*this, DSAStack, Allocator);
@@ -3200,7 +3213,7 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
32003213
}
32013214

32023215
Vars.push_back(RefExpr);
3203-
applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3216+
applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
32043217
DE->getSourceRange());
32053218
}
32063219
if (Vars.empty())
@@ -5228,8 +5241,10 @@ static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
52285241
if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
52295242
AllocatorKind, AC->getAllocator()))
52305243
continue;
5244+
// Placeholder until allocate clause supports align modifier.
5245+
Expr *Alignment = nullptr;
52315246
applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5232-
E->getSourceRange());
5247+
Alignment, E->getSourceRange());
52335248
}
52345249
}
52355250
}
@@ -13415,6 +13430,9 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
1341513430
case OMPC_partial:
1341613431
Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
1341713432
break;
13433+
case OMPC_align:
13434+
Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
13435+
break;
1341813436
case OMPC_device:
1341913437
case OMPC_if:
1342013438
case OMPC_default:
@@ -14528,7 +14546,7 @@ ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
1452814546
<< E->getSourceRange();
1452914547
return ExprError();
1453014548
}
14531-
if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
14549+
if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
1453214550
Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
1453314551
<< E->getSourceRange();
1453414552
return ExprError();
@@ -14953,6 +14971,17 @@ OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
1495314971
FactorExpr);
1495414972
}
1495514973

14974+
OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
14975+
SourceLocation LParenLoc,
14976+
SourceLocation EndLoc) {
14977+
ExprResult AlignVal;
14978+
AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
14979+
if (AlignVal.isInvalid())
14980+
return nullptr;
14981+
return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
14982+
EndLoc);
14983+
}
14984+
1495614985
OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
1495714986
OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
1495814987
SourceLocation StartLoc, SourceLocation LParenLoc,

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3371,12 +3371,23 @@ Decl *TemplateDeclInstantiator::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
33713371
SmallVector<OMPClause *, 4> Clauses;
33723372
// Copy map clauses from the original mapper.
33733373
for (OMPClause *C : D->clauselists()) {
3374-
auto *AC = cast<OMPAllocatorClause>(C);
3375-
ExprResult NewE = SemaRef.SubstExpr(AC->getAllocator(), TemplateArgs);
3376-
if (!NewE.isUsable())
3377-
continue;
3378-
OMPClause *IC = SemaRef.ActOnOpenMPAllocatorClause(
3379-
NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc());
3374+
OMPClause *IC = nullptr;
3375+
if (auto *AC = dyn_cast<OMPAllocatorClause>(C)) {
3376+
ExprResult NewE = SemaRef.SubstExpr(AC->getAllocator(), TemplateArgs);
3377+
if (!NewE.isUsable())
3378+
continue;
3379+
IC = SemaRef.ActOnOpenMPAllocatorClause(
3380+
NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc());
3381+
} else if (auto *AC = dyn_cast<OMPAlignClause>(C)) {
3382+
ExprResult NewE = SemaRef.SubstExpr(AC->getAlignment(), TemplateArgs);
3383+
if (!NewE.isUsable())
3384+
continue;
3385+
IC = SemaRef.ActOnOpenMPAlignClause(NewE.get(), AC->getBeginLoc(),
3386+
AC->getLParenLoc(), AC->getEndLoc());
3387+
// If align clause value ends up being invalid, this can end up null.
3388+
if (!IC)
3389+
continue;
3390+
}
33803391
Clauses.push_back(IC);
33813392
}
33823393

clang/lib/Sema/TreeTransform.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2269,6 +2269,16 @@ class TreeTransform {
22692269
EndLoc);
22702270
}
22712271

2272+
/// Build a new OpenMP 'align' clause.
2273+
///
2274+
/// By default, performs semantic analysis to build the new OpenMP clause.
2275+
/// Subclasses may override this routine to provide different behavior.
2276+
OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2277+
SourceLocation LParenLoc,
2278+
SourceLocation EndLoc) {
2279+
return getSema().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
2280+
}
2281+
22722282
/// Rebuild the operand to an Objective-C \@synchronized statement.
22732283
///
22742284
/// By default, performs semantic analysis to build the new statement.
@@ -9547,6 +9557,15 @@ TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
95479557
C->getLParenLoc(), C->getEndLoc());
95489558
}
95499559

9560+
template <typename Derived>
9561+
OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
9562+
ExprResult E = getDerived().TransformExpr(C->getAlignment());
9563+
if (E.isInvalid())
9564+
return nullptr;
9565+
return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
9566+
C->getLParenLoc(), C->getEndLoc());
9567+
}
9568+
95509569
template <typename Derived>
95519570
OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
95529571
OMPUnifiedAddressClause *C) {

clang/lib/Serialization/ASTReader.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11974,6 +11974,9 @@ OMPClause *OMPClauseReader::readClause() {
1197411974
case llvm::omp::OMPC_bind:
1197511975
C = OMPBindClause::CreateEmpty(Context);
1197611976
break;
11977+
case llvm::omp::OMPC_align:
11978+
C = new (Context) OMPAlignClause();
11979+
break;
1197711980
#define OMP_CLAUSE_NO_CLASS(Enum, Str) \
1197811981
case llvm::omp::Enum: \
1197911982
break;
@@ -12964,6 +12967,11 @@ void OMPClauseReader::VisitOMPBindClause(OMPBindClause *C) {
1296412967
C->setBindKindLoc(Record.readSourceLocation());
1296512968
}
1296612969

12970+
void OMPClauseReader::VisitOMPAlignClause(OMPAlignClause *C) {
12971+
C->setAlignment(Record.readExpr());
12972+
C->setLParenLoc(Record.readSourceLocation());
12973+
}
12974+
1296712975
OMPTraitInfo *ASTRecordReader::readOMPTraitInfo() {
1296812976
OMPTraitInfo &TI = getContext().getNewOMPTraitInfo();
1296912977
TI.Sets.resize(readUInt32());

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4757,9 +4757,10 @@ void ASTDeclReader::UpdateDecl(Decl *D,
47574757
auto AllocatorKind =
47584758
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(Record.readInt());
47594759
Expr *Allocator = Record.readExpr();
4760+
Expr *Alignment = Record.readExpr();
47604761
SourceRange SR = readSourceRange();
47614762
D->addAttr(OMPAllocateDeclAttr::CreateImplicit(
4762-
Reader.getContext(), AllocatorKind, Allocator, SR,
4763+
Reader.getContext(), AllocatorKind, Allocator, Alignment, SR,
47634764
AttributeCommonInfo::AS_Pragma));
47644765
break;
47654766
}

0 commit comments

Comments
 (0)