[Clang][OpenMP] Add reverse directive by Meinersbur · Pull Request #92916 · llvm/llvm-project (original) (raw)

Conversation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})

@Meinersbur

Add the reverse directive which will be introduced in the upcoming OpenMP 6.0 specification. A preview has been published in Technical Report 12.

This is the reverse directive part extracted out of #92030 which included reverse and interchange.

@Meinersbur

@Meinersbur

@llvmbot

@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-clang-modules

Author: Michael Kruse (Meinersbur)

Changes

Add the reverse directive which will be introduced in the upcoming OpenMP 6.0 specification. A preview has been published in Technical Report 12.

This is the reverse directive part extracted out of #92030 which included reverse and interchange.


Patch is 144.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92916.diff

30 Files Affected:

diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 365b607c74117..c7d63818ece23 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2146,6 +2146,10 @@ enum CXCursorKind { */ CXCursor_OMPScopeDirective = 306,

+DEF_TRAVERSE_STMT(OMPReverseDirective,

diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index f735fa5643aec..4be2e2d3a4605 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -1007,8 +1007,9 @@ class OMPLoopTransformationDirective : public OMPLoopBasedDirective { Stmt *getPreInits() const;

static bool classof(const Stmt *T) {

@@ -5711,6 +5712,73 @@ class OMPUnrollDirective final : public OMPLoopTransformationDirective { } };

+/// Represents the '#pragma omp reverse' loop transformation directive. +/// +/// \code +/// #pragma omp reverse +/// for (int i = 0; i < n; ++i) +/// ... +/// \endcode +class OMPReverseDirective final : public OMPLoopTransformationDirective {

}

+OMPReverseDirective * +OMPReverseDirective::Create(const ASTContext &C, SourceLocation StartLoc,

+} + OMPForSimdDirective * OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index be2d5a2eb6b46..64b481f680311 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -763,6 +763,11 @@ void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) { PrintOMPExecutableDirective(Node); }

+void StmtPrinter::VisitOMPReverseDirective(OMPReverseDirective *Node) {

+void StmtProfiler::VisitOMPReverseDirective(const OMPReverseDirective *S) {

bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) { @@ -808,6 +808,7 @@ void clang::getOpenMPCaptureRegions( break; case OMPD_tile: case OMPD_unroll:

case Stmt::OMPForDirectiveClass: EmitOMPForDirective(cast(*S)); break; diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 6410f9e102c90..ad6c044aa483b 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -187,6 +187,8 @@ class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { PreInits = Tile->getPreInits(); } else if (const auto *Unroll = dyn_cast(&S)) { PreInits = Unroll->getPreInits();

+void CodeGenFunction::EmitOMPReverseDirective(const OMPReverseDirective &S) {

diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 5f3ee7eb943f9..ac738e1e82886 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3807,6 +3807,7 @@ class CodeGenFunction : public CodeGenTypeCache { void EmitOMPSimdDirective(const OMPSimdDirective &S); void EmitOMPTileDirective(const OMPTileDirective &S); void EmitOMPUnrollDirective(const OMPUnrollDirective &S);

case OMPD_for: Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); @@ -15121,6 +15126,8 @@ bool SemaOpenMP::checkTransformableLoopNest( DependentPreInits = Dir->getPreInits(); else if (auto *Dir = dyn_cast(Transform)) DependentPreInits = Dir->getPreInits();

@@ -15746,6 +15753,189 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses, buildPreInits(Context, PreInits)); }

+StmtResult +SemaOpenMP::ActOnOpenMPReverseDirective(ArrayRef<OMPClause *> Clauses,

[truncated]

@llvmbot

@llvm/pr-subscribers-clang

Author: Michael Kruse (Meinersbur)

Changes

Add the reverse directive which will be introduced in the upcoming OpenMP 6.0 specification. A preview has been published in Technical Report 12.

This is the reverse directive part extracted out of #92030 which included reverse and interchange.


Patch is 144.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92916.diff

30 Files Affected:

diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 365b607c74117..c7d63818ece23 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2146,6 +2146,10 @@ enum CXCursorKind { */ CXCursor_OMPScopeDirective = 306,

+DEF_TRAVERSE_STMT(OMPReverseDirective,

diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index f735fa5643aec..4be2e2d3a4605 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -1007,8 +1007,9 @@ class OMPLoopTransformationDirective : public OMPLoopBasedDirective { Stmt *getPreInits() const;

static bool classof(const Stmt *T) {

@@ -5711,6 +5712,73 @@ class OMPUnrollDirective final : public OMPLoopTransformationDirective { } };

+/// Represents the '#pragma omp reverse' loop transformation directive. +/// +/// \code +/// #pragma omp reverse +/// for (int i = 0; i < n; ++i) +/// ... +/// \endcode +class OMPReverseDirective final : public OMPLoopTransformationDirective {

}

+OMPReverseDirective * +OMPReverseDirective::Create(const ASTContext &C, SourceLocation StartLoc,

+} + OMPForSimdDirective * OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index be2d5a2eb6b46..64b481f680311 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -763,6 +763,11 @@ void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) { PrintOMPExecutableDirective(Node); }

+void StmtPrinter::VisitOMPReverseDirective(OMPReverseDirective *Node) {

+void StmtProfiler::VisitOMPReverseDirective(const OMPReverseDirective *S) {

bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) { @@ -808,6 +808,7 @@ void clang::getOpenMPCaptureRegions( break; case OMPD_tile: case OMPD_unroll:

case Stmt::OMPForDirectiveClass: EmitOMPForDirective(cast(*S)); break; diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 6410f9e102c90..ad6c044aa483b 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -187,6 +187,8 @@ class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { PreInits = Tile->getPreInits(); } else if (const auto *Unroll = dyn_cast(&S)) { PreInits = Unroll->getPreInits();

+void CodeGenFunction::EmitOMPReverseDirective(const OMPReverseDirective &S) {

diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 5f3ee7eb943f9..ac738e1e82886 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3807,6 +3807,7 @@ class CodeGenFunction : public CodeGenTypeCache { void EmitOMPSimdDirective(const OMPSimdDirective &S); void EmitOMPTileDirective(const OMPTileDirective &S); void EmitOMPUnrollDirective(const OMPUnrollDirective &S);

case OMPD_for: Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); @@ -15121,6 +15126,8 @@ bool SemaOpenMP::checkTransformableLoopNest( DependentPreInits = Dir->getPreInits(); else if (auto *Dir = dyn_cast(Transform)) DependentPreInits = Dir->getPreInits();

@@ -15746,6 +15753,189 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses, buildPreInits(Context, PreInits)); }

+StmtResult +SemaOpenMP::ActOnOpenMPReverseDirective(ArrayRef<OMPClause *> Clauses,

[truncated]

alexey-bataev

@Meinersbur

@Meinersbur

alexey-bataev

@Meinersbur

@Meinersbur

@Meinersbur

… users/meinersbur/clang_openmp_reverse

Base automatically changed from users/meinersbur/clang_openmp_unroll-tile_foreach to main

May 22, 2024 12:30

@Meinersbur

@Meinersbur

@Meinersbur

@Meinersbur

@Meinersbur

@Meinersbur

#92916 has been accepted, but waiting for this PR.

alexey-bataev

Comment on lines 15920 to 15925

SmallVector<Stmt *> BodyStmts;
BodyStmts.push_back(InitReversed.get());
llvm::append_range(BodyStmts, LoopHelper.Updates);
if (auto *CXXRangeFor = dyn_cast(LoopStmt))
BodyStmts.push_back(CXXRangeFor->getLoopVarStmt());
BodyStmts.push_back(Body);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SmallVector<Stmt *> BodyStmts;
BodyStmts.push_back(InitReversed.get());
llvm::append_range(BodyStmts, LoopHelper.Updates);
if (auto *CXXRangeFor = dyn_cast(LoopStmt))
BodyStmts.push_back(CXXRangeFor->getLoopVarStmt());
BodyStmts.push_back(Body);
SmallVector<Stmt *> BodyStmts(LoopHelper.Updates.size() + 2 + (isa(LoopStmt) ? 1 : 0));
BodyStmts.front() = InitReversed.get();
llvm::copy(LoopHelper.Updates, std::next(BodyStmts.begin());
if (auto *CXXRangeFor = dyn_cast(LoopStmt))
BodyStmts[LoopHelper.Updates.size() + 1] = CXXRangeFor->getLoopVarStmt();
BodyStmts.back() = Body;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree with this change. It makes it harder to read, more difficult for size computation and indices to stay consistent when changed, and all for avoiding a possible reallocation that most will not happen anyway because it stays within the SmallVector's small size.

For my 64 bit system, small size is 6. LoopHelper.Updates.size() will be 1 (reverse applies to one loop, i.e. just one loop counter). That is, the size will be either 3 or 4.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It reduces memory fragmentation. Better to preallocate the buffer, if the size is known

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entire vector is on the stack; there is no memory fragmentation. reserve() would also be able to do a pre-allocation without manual iterator calculation.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it is not not on a stack. It is on stack only in some preallocated (small) cases, otherwise it is dynamically allocated

@Meinersbur

alexey-bataev

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG with a nit

@Meinersbur @alexey-bataev

Co-authored-by: Alexey Bataev a.bataev@outlook.com

@Meinersbur Meinersbur deleted the users/meinersbur/clang_openmp_reverse branch

July 18, 2024 08:35

Labels