Skip to content

Commit b15caff

Browse files
committed
[Clang][OpenMP] Add reverse directive
1 parent d6057c4 commit b15caff

30 files changed

+2800
-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
@@ -3021,6 +3021,9 @@ DEF_TRAVERSE_STMT(OMPTileDirective,
30213021
DEF_TRAVERSE_STMT(OMPUnrollDirective,
30223022
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
30233023

3024+
DEF_TRAVERSE_STMT(OMPReverseDirective,
3025+
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
3026+
30243027
DEF_TRAVERSE_STMT(OMPForDirective,
30253028
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
30263029

clang/include/clang/AST/StmtOpenMP.h

Lines changed: 70 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,73 @@ 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 Clauses The directive's clauses.
5752+
/// \param AssociatedStmt The outermost associated loop.
5753+
/// \param TransformedStmt The loop nest after tiling, or nullptr in
5754+
/// dependent contexts.
5755+
/// \param PreInits Helper preinits statements for the loop nest.
5756+
static OMPReverseDirective *
5757+
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5758+
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
5759+
Stmt *TransformedStmt, Stmt *PreInits);
5760+
5761+
/// Build an empty '#pragma omp reverse' AST node for deserialization.
5762+
///
5763+
/// \param C Context of the AST.
5764+
/// \param NumClauses Number of clauses to allocate.
5765+
static OMPReverseDirective *CreateEmpty(const ASTContext &C,
5766+
unsigned NumClauses);
5767+
5768+
/// Gets/sets the associated loops after the transformation, i.e. after
5769+
/// de-sugaring.
5770+
Stmt *getTransformedStmt() const {
5771+
return Data->getChildren()[TransformedStmtOffset];
5772+
}
5773+
5774+
/// Return preinits statement.
5775+
Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5776+
5777+
static bool classof(const Stmt *T) {
5778+
return T->getStmtClass() == OMPReverseDirectiveClass;
5779+
}
5780+
};
5781+
57145782
/// This represents '#pragma omp scan' directive.
57155783
///
57165784
/// \code

clang/include/clang/Basic/StmtNodes.td

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

clang/include/clang/Sema/SemaOpenMP.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,11 @@ class SemaOpenMP : public SemaBase {
422422
StmtResult ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
423423
Stmt *AStmt, SourceLocation StartLoc,
424424
SourceLocation EndLoc);
425+
/// Called on well-formed '#pragma omp reverse' after parsing of its clauses
426+
/// and the associated statement.
427+
StmtResult ActOnOpenMPReverseDirective(ArrayRef<OMPClause *> Clauses,
428+
Stmt *AStmt, SourceLocation StartLoc,
429+
SourceLocation EndLoc);
425430
/// Called on well-formed '\#pragma omp for' after parsing
426431
/// of the associated statement.
427432
StmtResult

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,6 +1856,7 @@ enum StmtCode {
18561856
STMT_OMP_SIMD_DIRECTIVE,
18571857
STMT_OMP_TILE_DIRECTIVE,
18581858
STMT_OMP_UNROLL_DIRECTIVE,
1859+
STMT_OMP_REVERSE_DIRECTIVE,
18591860
STMT_OMP_FOR_DIRECTIVE,
18601861
STMT_OMP_FOR_SIMD_DIRECTIVE,
18611862
STMT_OMP_SECTIONS_DIRECTIVE,

clang/lib/AST/StmtOpenMP.cpp

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

452+
OMPReverseDirective *
453+
OMPReverseDirective::Create(const ASTContext &C, SourceLocation StartLoc,
454+
SourceLocation EndLoc,
455+
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
456+
Stmt *TransformedStmt, Stmt *PreInits) {
457+
OMPReverseDirective *Dir = createDirective<OMPReverseDirective>(
458+
C, Clauses, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc);
459+
Dir->setTransformedStmt(TransformedStmt);
460+
Dir->setPreInits(PreInits);
461+
return Dir;
462+
}
463+
464+
OMPReverseDirective *OMPReverseDirective::CreateEmpty(const ASTContext &C,
465+
unsigned NumClauses) {
466+
return createEmptyDirective<OMPReverseDirective>(
467+
C, NumClauses, /*HasAssociatedStmt=*/true, TransformedStmtOffset + 1,
468+
SourceLocation(), SourceLocation());
469+
}
470+
452471
OMPForSimdDirective *
453472
OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
454473
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: 2 additions & 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) {
@@ -808,6 +808,7 @@ void clang::getOpenMPCaptureRegions(
808808
break;
809809
case OMPD_tile:
810810
case OMPD_unroll:
811+
case OMPD_reverse:
811812
// loop transformations do not introduce captures.
812813
break;
813814
case OMPD_threadprivate:

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
@@ -3807,6 +3807,7 @@ class CodeGenFunction : public CodeGenTypeCache {
38073807
void EmitOMPSimdDirective(const OMPSimdDirective &S);
38083808
void EmitOMPTileDirective(const OMPTileDirective &S);
38093809
void EmitOMPUnrollDirective(const OMPUnrollDirective &S);
3810+
void EmitOMPReverseDirective(const OMPReverseDirective &S);
38103811
void EmitOMPForDirective(const OMPForDirective &S);
38113812
void EmitOMPForSimdDirective(const OMPForSimdDirective &S);
38123813
void EmitOMPSectionsDirective(const OMPSectionsDirective &S);

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,6 +2384,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
23842384
case OMPD_simd:
23852385
case OMPD_tile:
23862386
case OMPD_unroll:
2387+
case OMPD_reverse:
23872388
case OMPD_task:
23882389
case OMPD_taskyield:
23892390
case OMPD_barrier:
@@ -2802,6 +2803,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
28022803
case OMPD_simd:
28032804
case OMPD_tile:
28042805
case OMPD_unroll:
2806+
case OMPD_reverse:
28052807
case OMPD_for:
28062808
case OMPD_for_simd:
28072809
case OMPD_sections:

clang/lib/Sema/SemaExceptionSpec.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
14861486
case Stmt::OMPSimdDirectiveClass:
14871487
case Stmt::OMPTileDirectiveClass:
14881488
case Stmt::OMPUnrollDirectiveClass:
1489+
case Stmt::OMPReverseDirectiveClass:
14891490
case Stmt::OMPSingleDirectiveClass:
14901491
case Stmt::OMPTargetDataDirectiveClass:
14911492
case Stmt::OMPTargetDirectiveClass:

0 commit comments

Comments
 (0)