Skip to content

Commit 8ca8ea2

Browse files
eZWALTrofirrim
authored andcommitted
[Clang][OpenMP][LoopTransformations] Implement "#pragma omp fuse" loop transformation directive and "looprange" clause (llvm#139293)
This change implements the fuse directive, `#pragma omp fuse`, as specified in the OpenMP 6.0, along with the `looprange` clause in clang. This change also adds minimal stubs so flang keeps compiling (a full implementation in flang of this directive is still pending). --------- Co-authored-by: Roger Ferrer Ibanez <[email protected]>
1 parent 8759cf8 commit 8ca8ea2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+5198
-54
lines changed

clang/bindings/python/clang/cindex.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,9 @@ def is_unexposed(self):
14461446
# OpenMP stripe directive.
14471447
OMP_STRIPE_DIRECTIVE = 310
14481448

1449+
# OpenMP fuse directive.
1450+
OMP_FUSE_DIRECTIVE = 311
1451+
14491452
# OpenACC Compute Construct.
14501453
OPEN_ACC_COMPUTE_DIRECTIVE = 320
14511454

clang/docs/OpenMPSupport.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,8 @@ implementation.
482482
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
483483
| loop transformation apply clause | :none:`unclaimed` | :none:`unclaimed` | |
484484
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
485+
| loop fuse transformation | :good:`done` | :none:`unclaimed` | |
486+
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
485487
| workdistribute construct | | :none:`in progress` | @skc7, @mjklemm |
486488
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
487489
| task_iteration | :none:`unclaimed` | :none:`unclaimed` | |

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ OpenMP Support
599599
- Added support for ``defaultmap`` directive implicit-behavior ``storage``.
600600
- Added support for ``defaultmap`` directive implicit-behavior ``private``.
601601
- Added parsing and semantic analysis support for ``groupprivate`` directive.
602+
- Added support for 'omp fuse' directive.
602603

603604
Improvements
604605
^^^^^^^^^^^^

clang/include/clang-c/Index.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,6 +2162,10 @@ enum CXCursorKind {
21622162
*/
21632163
CXCursor_OMPStripeDirective = 310,
21642164

2165+
/** OpenMP fuse directive
2166+
*/
2167+
CXCursor_OMPFuseDirective = 311,
2168+
21652169
/** OpenACC Compute Construct.
21662170
*/
21672171
CXCursor_OpenACCComputeConstruct = 320,

clang/include/clang/AST/OpenMPClause.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,80 @@ class OMPFullClause final : public OMPNoChildClause<llvm::omp::OMPC_full> {
11491149
static OMPFullClause *CreateEmpty(const ASTContext &C);
11501150
};
11511151

1152+
/// This class represents the 'looprange' clause in the
1153+
/// '#pragma omp fuse' directive
1154+
///
1155+
/// \code {c}
1156+
/// #pragma omp fuse looprange(1,2)
1157+
/// {
1158+
/// for(int i = 0; i < 64; ++i)
1159+
/// for(int j = 0; j < 256; j+=2)
1160+
/// for(int k = 127; k >= 0; --k)
1161+
/// \endcode
1162+
class OMPLoopRangeClause final : public OMPClause {
1163+
friend class OMPClauseReader;
1164+
/// Location of '('
1165+
SourceLocation LParenLoc;
1166+
1167+
/// Location of first and count expressions
1168+
SourceLocation FirstLoc, CountLoc;
1169+
1170+
/// Number of looprange arguments (always 2: first, count)
1171+
enum { FirstExpr, CountExpr, NumArgs };
1172+
Stmt *Args[NumArgs] = {nullptr, nullptr};
1173+
1174+
/// Set looprange 'first' expression
1175+
void setFirst(Expr *E) { Args[FirstExpr] = E; }
1176+
1177+
/// Set looprange 'count' expression
1178+
void setCount(Expr *E) { Args[CountExpr] = E; }
1179+
1180+
/// Build an empty clause for deserialization.
1181+
explicit OMPLoopRangeClause()
1182+
: OMPClause(llvm::omp::OMPC_looprange, {}, {}) {}
1183+
1184+
public:
1185+
/// Build a 'looprange' clause AST node.
1186+
static OMPLoopRangeClause *
1187+
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
1188+
SourceLocation FirstLoc, SourceLocation CountLoc,
1189+
SourceLocation EndLoc, Expr *First, Expr *Count);
1190+
1191+
/// Build an empty 'looprange' clause node.
1192+
static OMPLoopRangeClause *CreateEmpty(const ASTContext &C);
1193+
1194+
// Location getters/setters
1195+
SourceLocation getLParenLoc() const { return LParenLoc; }
1196+
SourceLocation getFirstLoc() const { return FirstLoc; }
1197+
SourceLocation getCountLoc() const { return CountLoc; }
1198+
1199+
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
1200+
void setFirstLoc(SourceLocation Loc) { FirstLoc = Loc; }
1201+
void setCountLoc(SourceLocation Loc) { CountLoc = Loc; }
1202+
1203+
/// Get looprange 'first' expression
1204+
Expr *getFirst() const { return cast_or_null<Expr>(Args[FirstExpr]); }
1205+
1206+
/// Get looprange 'count' expression
1207+
Expr *getCount() const { return cast_or_null<Expr>(Args[CountExpr]); }
1208+
1209+
child_range children() { return child_range(Args, Args + NumArgs); }
1210+
const_child_range children() const {
1211+
return const_child_range(Args, Args + NumArgs);
1212+
}
1213+
1214+
child_range used_children() {
1215+
return child_range(child_iterator(), child_iterator());
1216+
}
1217+
const_child_range used_children() const {
1218+
return const_child_range(const_child_iterator(), const_child_iterator());
1219+
}
1220+
1221+
static bool classof(const OMPClause *T) {
1222+
return T->getClauseKind() == llvm::omp::OMPC_looprange;
1223+
}
1224+
};
1225+
11521226
/// Representation of the 'partial' clause of the '#pragma omp unroll'
11531227
/// directive.
11541228
///

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3177,6 +3177,9 @@ DEF_TRAVERSE_STMT(OMPUnrollDirective,
31773177
DEF_TRAVERSE_STMT(OMPReverseDirective,
31783178
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
31793179

3180+
DEF_TRAVERSE_STMT(OMPFuseDirective,
3181+
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
3182+
31803183
DEF_TRAVERSE_STMT(OMPInterchangeDirective,
31813184
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
31823185

@@ -3494,6 +3497,14 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFullClause(OMPFullClause *C) {
34943497
return true;
34953498
}
34963499

3500+
template <typename Derived>
3501+
bool RecursiveASTVisitor<Derived>::VisitOMPLoopRangeClause(
3502+
OMPLoopRangeClause *C) {
3503+
TRY_TO(TraverseStmt(C->getFirst()));
3504+
TRY_TO(TraverseStmt(C->getCount()));
3505+
return true;
3506+
}
3507+
34973508
template <typename Derived>
34983509
bool RecursiveASTVisitor<Derived>::VisitOMPPartialClause(OMPPartialClause *C) {
34993510
TRY_TO(TraverseStmt(C->getFactor()));

0 commit comments

Comments
 (0)