Skip to content

Commit 80865c0

Browse files
[Clang][OpenMP] Add reverse directive (#92916)
Add the reverse directive which will be introduced in the upcoming OpenMP 6.0 specification. A preview has been published in [Technical Report 12](https://www.openmp.org/wp-content/uploads/openmp-TR12.pdf). --------- Co-authored-by: Alexey Bataev <[email protected]>
1 parent 26cb88e commit 80865c0

30 files changed

+2799
-3
lines changed

clang/include/clang-c/Index.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,10 @@ enum CXCursorKind {
21462146
*/
21472147
CXCursor_OMPScopeDirective = 306,
21482148

2149+
/** OpenMP reverse directive.
2150+
*/
2151+
CXCursor_OMPReverseDirective = 307,
2152+
21492153
/** OpenACC Compute Construct.
21502154
*/
21512155
CXCursor_OpenACCComputeConstruct = 320,

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3032,6 +3032,9 @@ DEF_TRAVERSE_STMT(OMPTileDirective,
30323032
DEF_TRAVERSE_STMT(OMPUnrollDirective,
30333033
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
30343034

3035+
DEF_TRAVERSE_STMT(OMPReverseDirective,
3036+
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
3037+
30353038
DEF_TRAVERSE_STMT(OMPForDirective,
30363039
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
30373040

clang/include/clang/AST/StmtOpenMP.h

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,8 +1007,9 @@ class OMPLoopTransformationDirective : public OMPLoopBasedDirective {
10071007
Stmt *getPreInits() const;
10081008

10091009
static bool classof(const Stmt *T) {
1010-
return T->getStmtClass() == OMPTileDirectiveClass ||
1011-
T->getStmtClass() == OMPUnrollDirectiveClass;
1010+
Stmt::StmtClass C = T->getStmtClass();
1011+
return C == OMPTileDirectiveClass || C == OMPUnrollDirectiveClass ||
1012+
C == OMPReverseDirectiveClass;
10121013
}
10131014
};
10141015

@@ -5711,6 +5712,70 @@ class OMPUnrollDirective final : public OMPLoopTransformationDirective {
57115712
}
57125713
};
57135714

5715+
/// Represents the '#pragma omp reverse' loop transformation directive.
5716+
///
5717+
/// \code
5718+
/// #pragma omp reverse
5719+
/// for (int i = 0; i < n; ++i)
5720+
/// ...
5721+
/// \endcode
5722+
class OMPReverseDirective final : public OMPLoopTransformationDirective {
5723+
friend class ASTStmtReader;
5724+
friend class OMPExecutableDirective;
5725+
5726+
/// Offsets of child members.
5727+
enum {
5728+
PreInitsOffset = 0,
5729+
TransformedStmtOffset,
5730+
};
5731+
5732+
explicit OMPReverseDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5733+
: OMPLoopTransformationDirective(OMPReverseDirectiveClass,
5734+
llvm::omp::OMPD_reverse, StartLoc,
5735+
EndLoc, 1) {}
5736+
5737+
void setPreInits(Stmt *PreInits) {
5738+
Data->getChildren()[PreInitsOffset] = PreInits;
5739+
}
5740+
5741+
void setTransformedStmt(Stmt *S) {
5742+
Data->getChildren()[TransformedStmtOffset] = S;
5743+
}
5744+
5745+
public:
5746+
/// Create a new AST node representation for '#pragma omp reverse'.
5747+
///
5748+
/// \param C Context of the AST.
5749+
/// \param StartLoc Location of the introducer (e.g. the 'omp' token).
5750+
/// \param EndLoc Location of the directive's end (e.g. the tok::eod).
5751+
/// \param AssociatedStmt The outermost associated loop.
5752+
/// \param TransformedStmt The loop nest after tiling, or nullptr in
5753+
/// dependent contexts.
5754+
/// \param PreInits Helper preinits statements for the loop nest.
5755+
static OMPReverseDirective *
5756+
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5757+
Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits);
5758+
5759+
/// Build an empty '#pragma omp reverse' AST node for deserialization.
5760+
///
5761+
/// \param C Context of the AST.
5762+
/// \param NumClauses Number of clauses to allocate.
5763+
static OMPReverseDirective *CreateEmpty(const ASTContext &C);
5764+
5765+
/// Gets/sets the associated loops after the transformation, i.e. after
5766+
/// de-sugaring.
5767+
Stmt *getTransformedStmt() const {
5768+
return Data->getChildren()[TransformedStmtOffset];
5769+
}
5770+
5771+
/// Return preinits statement.
5772+
Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5773+
5774+
static bool classof(const Stmt *T) {
5775+
return T->getStmtClass() == OMPReverseDirectiveClass;
5776+
}
5777+
};
5778+
57145779
/// This represents '#pragma omp scan' directive.
57155780
///
57165781
/// \code

clang/include/clang/Basic/StmtNodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ def OMPSimdDirective : StmtNode<OMPLoopDirective>;
230230
def OMPLoopTransformationDirective : StmtNode<OMPLoopBasedDirective, 1>;
231231
def OMPTileDirective : StmtNode<OMPLoopTransformationDirective>;
232232
def OMPUnrollDirective : StmtNode<OMPLoopTransformationDirective>;
233+
def OMPReverseDirective : StmtNode<OMPLoopTransformationDirective>;
233234
def OMPForDirective : StmtNode<OMPLoopDirective>;
234235
def OMPForSimdDirective : StmtNode<OMPLoopDirective>;
235236
def OMPSectionsDirective : StmtNode<OMPExecutableDirective>;

clang/include/clang/Sema/SemaOpenMP.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@ class SemaOpenMP : public SemaBase {
423423
StmtResult ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
424424
Stmt *AStmt, SourceLocation StartLoc,
425425
SourceLocation EndLoc);
426+
/// Called on well-formed '#pragma omp reverse'.
427+
StmtResult ActOnOpenMPReverseDirective(Stmt *AStmt, SourceLocation StartLoc,
428+
SourceLocation EndLoc);
426429
/// Called on well-formed '\#pragma omp for' after parsing
427430
/// of the associated statement.
428431
StmtResult

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,6 +1895,7 @@ enum StmtCode {
18951895
STMT_OMP_SIMD_DIRECTIVE,
18961896
STMT_OMP_TILE_DIRECTIVE,
18971897
STMT_OMP_UNROLL_DIRECTIVE,
1898+
STMT_OMP_REVERSE_DIRECTIVE,
18981899
STMT_OMP_FOR_DIRECTIVE,
18991900
STMT_OMP_FOR_SIMD_DIRECTIVE,
19001901
STMT_OMP_SECTIONS_DIRECTIVE,

clang/lib/AST/StmtOpenMP.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,24 @@ OMPUnrollDirective *OMPUnrollDirective::CreateEmpty(const ASTContext &C,
449449
SourceLocation(), SourceLocation());
450450
}
451451

452+
OMPReverseDirective *
453+
OMPReverseDirective::Create(const ASTContext &C, SourceLocation StartLoc,
454+
SourceLocation EndLoc, Stmt *AssociatedStmt,
455+
Stmt *TransformedStmt, Stmt *PreInits) {
456+
OMPReverseDirective *Dir = createDirective<OMPReverseDirective>(
457+
C, std::nullopt, AssociatedStmt, TransformedStmtOffset + 1, StartLoc,
458+
EndLoc);
459+
Dir->setTransformedStmt(TransformedStmt);
460+
Dir->setPreInits(PreInits);
461+
return Dir;
462+
}
463+
464+
OMPReverseDirective *OMPReverseDirective::CreateEmpty(const ASTContext &C) {
465+
return createEmptyDirective<OMPReverseDirective>(
466+
C, /*NumClauses=*/0, /*HasAssociatedStmt=*/true,
467+
TransformedStmtOffset + 1, SourceLocation(), SourceLocation());
468+
}
469+
452470
OMPForSimdDirective *
453471
OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
454472
SourceLocation EndLoc, unsigned CollapsedNum,

clang/lib/AST/StmtPrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,11 @@ void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) {
763763
PrintOMPExecutableDirective(Node);
764764
}
765765

766+
void StmtPrinter::VisitOMPReverseDirective(OMPReverseDirective *Node) {
767+
Indent() << "#pragma omp reverse";
768+
PrintOMPExecutableDirective(Node);
769+
}
770+
766771
void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
767772
Indent() << "#pragma omp for";
768773
PrintOMPExecutableDirective(Node);

clang/lib/AST/StmtProfile.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,10 @@ void StmtProfiler::VisitOMPUnrollDirective(const OMPUnrollDirective *S) {
985985
VisitOMPLoopTransformationDirective(S);
986986
}
987987

988+
void StmtProfiler::VisitOMPReverseDirective(const OMPReverseDirective *S) {
989+
VisitOMPLoopTransformationDirective(S);
990+
}
991+
988992
void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
989993
VisitOMPLoopDirective(S);
990994
}

clang/lib/Basic/OpenMPKinds.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {
684684
}
685685

686686
bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind) {
687-
return DKind == OMPD_tile || DKind == OMPD_unroll;
687+
return DKind == OMPD_tile || DKind == OMPD_unroll || DKind == OMPD_reverse;
688688
}
689689

690690
bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) {

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
222222
case Stmt::OMPUnrollDirectiveClass:
223223
EmitOMPUnrollDirective(cast<OMPUnrollDirective>(*S));
224224
break;
225+
case Stmt::OMPReverseDirectiveClass:
226+
EmitOMPReverseDirective(cast<OMPReverseDirective>(*S));
227+
break;
225228
case Stmt::OMPForDirectiveClass:
226229
EmitOMPForDirective(cast<OMPForDirective>(*S));
227230
break;

clang/lib/CodeGen/CGStmtOpenMP.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ class OMPLoopScope : public CodeGenFunction::RunCleanupsScope {
187187
PreInits = Tile->getPreInits();
188188
} else if (const auto *Unroll = dyn_cast<OMPUnrollDirective>(&S)) {
189189
PreInits = Unroll->getPreInits();
190+
} else if (const auto *Reverse = dyn_cast<OMPReverseDirective>(&S)) {
191+
PreInits = Reverse->getPreInits();
190192
} else {
191193
llvm_unreachable("Unknown loop-based directive kind.");
192194
}
@@ -2762,6 +2764,12 @@ void CodeGenFunction::EmitOMPTileDirective(const OMPTileDirective &S) {
27622764
EmitStmt(S.getTransformedStmt());
27632765
}
27642766

2767+
void CodeGenFunction::EmitOMPReverseDirective(const OMPReverseDirective &S) {
2768+
// Emit the de-sugared statement.
2769+
OMPTransformDirectiveScopeRAII ReverseScope(*this, &S);
2770+
EmitStmt(S.getTransformedStmt());
2771+
}
2772+
27652773
void CodeGenFunction::EmitOMPUnrollDirective(const OMPUnrollDirective &S) {
27662774
bool UseOMPIRBuilder = CGM.getLangOpts().OpenMPIRBuilder;
27672775

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3817,6 +3817,7 @@ class CodeGenFunction : public CodeGenTypeCache {
38173817
void EmitOMPSimdDirective(const OMPSimdDirective &S);
38183818
void EmitOMPTileDirective(const OMPTileDirective &S);
38193819
void EmitOMPUnrollDirective(const OMPUnrollDirective &S);
3820+
void EmitOMPReverseDirective(const OMPReverseDirective &S);
38203821
void EmitOMPForDirective(const OMPForDirective &S);
38213822
void EmitOMPForSimdDirective(const OMPForSimdDirective &S);
38223823
void EmitOMPSectionsDirective(const OMPSectionsDirective &S);

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2885,6 +2885,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
28852885
}
28862886
break;
28872887
}
2888+
case OMPD_reverse:
28882889
case OMPD_declare_target: {
28892890
SourceLocation DTLoc = ConsumeAnyToken();
28902891
bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);

clang/lib/Sema/SemaExceptionSpec.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
14661466
case Stmt::OMPSimdDirectiveClass:
14671467
case Stmt::OMPTileDirectiveClass:
14681468
case Stmt::OMPUnrollDirectiveClass:
1469+
case Stmt::OMPReverseDirectiveClass:
14691470
case Stmt::OMPSingleDirectiveClass:
14701471
case Stmt::OMPTargetDataDirectiveClass:
14711472
case Stmt::OMPTargetDirectiveClass:

0 commit comments

Comments
 (0)