[Clang][OpenMP][LoopTransformations] Add support for "#pragma omp fuse" loop transformation directive and "looprange" clause by eZWALT · Pull Request #139293 · llvm/llvm-project (original) (raw)

@llvm/pr-subscribers-clang-modules
@llvm/pr-subscribers-flang-semantics
@llvm/pr-subscribers-flang-parser

@llvm/pr-subscribers-clang

Author: Walter J.T.V (eZWALT)

Changes

This pull request introduces full support for the #pragma omp fuse directive, as specified in the OpenMP 6.0 specification, along with initial support for the looprange clause in Clang.

To enable this functionality, infrastructure for the Loop Sequence construct, also new in OpenMP 6.0, has been implemented. Additionally, a minimal code skeleton has been added to Flang to ensure compatibility and avoid integration issues, although a full implementation in Flang is still pending.

https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-6-0.pdf

P.S. As a follow-up to this loop transformation work, I'm currently preparing a patch that implements the "#pragma omp split" directive, also introduced in OpenMP 6.0.


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

47 Files Affected:

diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst index d6507071d4693..b39f9d3634a63 100644 --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -376,6 +376,8 @@ implementation. +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | loop stripe transformation | :good:done | https://github.com/llvm/llvm-project/pull/119891 | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ +| loop fuse transformation | :good:prototyped | :none:unclaimed | | ++-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | work distribute construct | :none:unclaimed | :none:unclaimed | | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | task_iteration | :none:unclaimed | :none:unclaimed | | diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index d30d15e53802a..00046de62a742 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2162,6 +2162,10 @@ enum CXCursorKind { */ CXCursor_OMPStripeDirective = 310,

+/// This class represents the 'looprange' clause in the +/// '#pragma omp fuse' directive +/// +/// \code {c} +/// #pragma omp fuse looprange(1,2) +/// { +/// for(int i = 0; i < 64; ++i) +/// for(int j = 0; j < 256; j+=2) +/// for(int k = 127; k >= 0; --k) +/// \endcode +class OMPLoopRangeClause final : public OMPClause {

+DEF_TRAVERSE_STMT(OMPFuseDirective,

@@ -3395,6 +3398,14 @@ bool RecursiveASTVisitor::VisitOMPFullClause(OMPFullClause *C) { return true; }

+template +bool RecursiveASTVisitor::VisitOMPLoopRangeClause(

protected: explicit OMPLoopTransformationDirective(StmtClass SC, @@ -973,6 +976,9 @@ class OMPLoopTransformationDirective : public OMPLoopBasedDirective {

/// Set the number of loops generated by this loop transformation. void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }

public: /// Return the number of associated (consumed) loops. @@ -981,6 +987,10 @@ class OMPLoopTransformationDirective : public OMPLoopBasedDirective { /// Return the number of loops generated by this loop transformation. unsigned getNumGeneratedLoops() const { return NumGeneratedLoops; }

@@ -5561,7 +5571,10 @@ class OMPTileDirective final : public OMPLoopTransformationDirective { : OMPLoopTransformationDirective(OMPTileDirectiveClass, llvm::omp::OMPD_tile, StartLoc, EndLoc, NumLoops) {

}

void setPreInits(Stmt *PreInits) { @@ -5639,6 +5652,8 @@ class OMPStripeDirective final : public OMPLoopTransformationDirective { llvm::omp::OMPD_stripe, StartLoc, EndLoc, NumLoops) { setNumGeneratedLoops(2 * NumLoops);

}

void setPreInits(Stmt *PreInits) { @@ -5790,7 +5805,11 @@ class OMPReverseDirective final : public OMPLoopTransformationDirective { explicit OMPReverseDirective(SourceLocation StartLoc, SourceLocation EndLoc) : OMPLoopTransformationDirective(OMPReverseDirectiveClass, llvm::omp::OMPD_reverse, StartLoc,

@@ -5857,7 +5876,10 @@ class OMPInterchangeDirective final : public OMPLoopTransformationDirective { : OMPLoopTransformationDirective(OMPInterchangeDirectiveClass, llvm::omp::OMPD_interchange, StartLoc, EndLoc, NumLoops) {

}

void setPreInits(Stmt *PreInits) { @@ -5908,6 +5930,86 @@ class OMPInterchangeDirective final : public OMPLoopTransformationDirective { } };

+/// Represents the '#pragma omp fuse' loop transformation directive +/// +/// \code{c} +/// #pragma omp fuse +/// { +/// for(int i = 0; i < m1; ++i) {...} +/// for(int j = 0; j < m2; ++j) {...} +/// ... +/// } +/// \endcode + +class OMPFuseDirective final : public OMPLoopTransformationDirective {

diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 6498390fe96f7..ac4cbe3709a0d 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -457,6 +457,13 @@ class SemaOpenMP : public SemaBase { Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); +

[truncated]