Skip to content

Commit 7e3bd1e

Browse files
committed
Add looprange clause
1 parent 204d902 commit 7e3bd1e

File tree

22 files changed

+921
-43
lines changed

22 files changed

+921
-43
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,106 @@ class OMPFullClause final : public OMPNoChildClause<llvm::omp::OMPC_full> {
11431143
static OMPFullClause *CreateEmpty(const ASTContext &C);
11441144
};
11451145

1146+
/// This class represents the 'looprange' clause in the
1147+
/// '#pragma omp fuse' directive
1148+
///
1149+
/// \code {c}
1150+
/// #pragma omp fuse looprange(1,2)
1151+
/// {
1152+
/// for(int i = 0; i < 64; ++i)
1153+
/// for(int j = 0; j < 256; j+=2)
1154+
/// for(int k = 127; k >= 0; --k)
1155+
/// \endcode
1156+
class OMPLoopRangeClause final : public OMPClause {
1157+
friend class OMPClauseReader;
1158+
1159+
explicit OMPLoopRangeClause()
1160+
: OMPClause(llvm::omp::OMPC_looprange, {}, {}) {}
1161+
1162+
/// Location of '('
1163+
SourceLocation LParenLoc;
1164+
1165+
/// Location of 'first'
1166+
SourceLocation FirstLoc;
1167+
1168+
/// Location of 'count'
1169+
SourceLocation CountLoc;
1170+
1171+
/// Expr associated with 'first' argument
1172+
Expr *First = nullptr;
1173+
1174+
/// Expr associated with 'count' argument
1175+
Expr *Count = nullptr;
1176+
1177+
/// Set 'first'
1178+
void setFirst(Expr *First) { this->First = First; }
1179+
1180+
/// Set 'count'
1181+
void setCount(Expr *Count) { this->Count = Count; }
1182+
1183+
/// Set location of '('.
1184+
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
1185+
1186+
/// Set location of 'first' argument
1187+
void setFirstLoc(SourceLocation Loc) { FirstLoc = Loc; }
1188+
1189+
/// Set location of 'count' argument
1190+
void setCountLoc(SourceLocation Loc) { CountLoc = Loc; }
1191+
1192+
public:
1193+
/// Build an AST node for a 'looprange' clause
1194+
///
1195+
/// \param StartLoc Starting location of the clause.
1196+
/// \param LParenLoc Location of '('.
1197+
/// \param ModifierLoc Modifier location.
1198+
/// \param
1199+
static OMPLoopRangeClause *
1200+
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
1201+
SourceLocation FirstLoc, SourceLocation CountLoc,
1202+
SourceLocation EndLoc, Expr *First, Expr *Count);
1203+
1204+
/// Build an empty 'looprange' node for deserialization
1205+
///
1206+
/// \param C Context of the AST.
1207+
static OMPLoopRangeClause *CreateEmpty(const ASTContext &C);
1208+
1209+
/// Returns the location of '('
1210+
SourceLocation getLParenLoc() const { return LParenLoc; }
1211+
1212+
/// Returns the location of 'first'
1213+
SourceLocation getFirstLoc() const { return FirstLoc; }
1214+
1215+
/// Returns the location of 'count'
1216+
SourceLocation getCountLoc() const { return CountLoc; }
1217+
1218+
/// Returns the argument 'first' or nullptr if not set
1219+
Expr *getFirst() const { return cast_or_null<Expr>(First); }
1220+
1221+
/// Returns the argument 'count' or nullptr if not set
1222+
Expr *getCount() const { return cast_or_null<Expr>(Count); }
1223+
1224+
child_range children() {
1225+
return child_range(reinterpret_cast<Stmt **>(&First),
1226+
reinterpret_cast<Stmt **>(&Count) + 1);
1227+
}
1228+
1229+
const_child_range children() const {
1230+
auto Children = const_cast<OMPLoopRangeClause *>(this)->children();
1231+
return const_child_range(Children.begin(), Children.end());
1232+
}
1233+
1234+
child_range used_children() {
1235+
return child_range(child_iterator(), child_iterator());
1236+
}
1237+
const_child_range used_children() const {
1238+
return const_child_range(const_child_iterator(), const_child_iterator());
1239+
}
1240+
1241+
static bool classof(const OMPClause *T) {
1242+
return T->getClauseKind() == llvm::omp::OMPC_looprange;
1243+
}
1244+
};
1245+
11461246
/// Representation of the 'partial' clause of the '#pragma omp unroll'
11471247
/// directive.
11481248
///

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3400,6 +3400,14 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFullClause(OMPFullClause *C) {
34003400
return true;
34013401
}
34023402

3403+
template <typename Derived>
3404+
bool RecursiveASTVisitor<Derived>::VisitOMPLoopRangeClause(
3405+
OMPLoopRangeClause *C) {
3406+
TRY_TO(TraverseStmt(C->getFirst()));
3407+
TRY_TO(TraverseStmt(C->getCount()));
3408+
return true;
3409+
}
3410+
34033411
template <typename Derived>
34043412
bool RecursiveASTVisitor<Derived>::VisitOMPPartialClause(OMPPartialClause *C) {
34053413
TRY_TO(TraverseStmt(C->getFactor()));

clang/include/clang/AST/StmtOpenMP.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5572,7 +5572,9 @@ class OMPTileDirective final : public OMPLoopTransformationDirective {
55725572
: OMPLoopTransformationDirective(OMPTileDirectiveClass,
55735573
llvm::omp::OMPD_tile, StartLoc, EndLoc,
55745574
NumLoops) {
5575+
// Tiling doubles the original number of loops
55755576
setNumGeneratedLoops(2 * NumLoops);
5577+
// Produces a single top-level canonical loop nest
55765578
setNumGeneratedLoopNests(1);
55775579
}
55785580

@@ -5803,9 +5805,9 @@ class OMPReverseDirective final : public OMPLoopTransformationDirective {
58035805
: OMPLoopTransformationDirective(OMPReverseDirectiveClass,
58045806
llvm::omp::OMPD_reverse, StartLoc,
58055807
EndLoc, 1) {
5806-
5807-
setNumGeneratedLoopNests(1);
5808+
// Reverse produces a single top-level canonical loop nest
58085809
setNumGeneratedLoops(1);
5810+
setNumGeneratedLoopNests(1);
58095811
}
58105812

58115813
void setPreInits(Stmt *PreInits) {
@@ -5873,6 +5875,8 @@ class OMPInterchangeDirective final : public OMPLoopTransformationDirective {
58735875
: OMPLoopTransformationDirective(OMPInterchangeDirectiveClass,
58745876
llvm::omp::OMPD_interchange, StartLoc,
58755877
EndLoc, NumLoops) {
5878+
// Interchange produces a single top-level canonical loop
5879+
// nest, with the exact same amount of total loops
58765880
setNumGeneratedLoops(NumLoops);
58775881
setNumGeneratedLoopNests(1);
58785882
}
@@ -5950,11 +5954,7 @@ class OMPFuseDirective final : public OMPLoopTransformationDirective {
59505954
unsigned NumLoops)
59515955
: OMPLoopTransformationDirective(OMPFuseDirectiveClass,
59525956
llvm::omp::OMPD_fuse, StartLoc, EndLoc,
5953-
NumLoops) {
5954-
setNumGeneratedLoops(1);
5955-
// TODO: After implementing the looprange clause, change this logic
5956-
setNumGeneratedLoopNests(1);
5957-
}
5957+
NumLoops) {}
59585958

59595959
void setPreInits(Stmt *PreInits) {
59605960
Data->getChildren()[PreInitsOffset] = PreInits;
@@ -5990,8 +5990,10 @@ class OMPFuseDirective final : public OMPLoopTransformationDirective {
59905990
/// \param C Context of the AST
59915991
/// \param NumClauses Number of clauses to allocate
59925992
/// \param NumLoops Number of associated loops to allocate
5993+
/// \param NumLoopNests Number of top level loops to allocate
59935994
static OMPFuseDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5994-
unsigned NumLoops);
5995+
unsigned NumLoops,
5996+
unsigned NumLoopNests);
59955997

59965998
/// Gets the associated loops after the transformation. This is the de-sugared
59975999
/// replacement or nulltpr in dependent contexts.

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11566,6 +11566,11 @@ def err_omp_not_a_loop_sequence : Error <
1156611566
"statement after '#pragma omp %0' must be a loop sequence containing canonical loops or loop-generating constructs">;
1156711567
def err_omp_empty_loop_sequence : Error <
1156811568
"loop sequence after '#pragma omp %0' must contain at least 1 canonical loop or loop-generating construct">;
11569+
def err_omp_invalid_looprange : Error <
11570+
"loop range in '#pragma omp %0' exceeds the number of available loops: "
11571+
"range end '%1' is greater than the total number of loops '%2'">;
11572+
def warn_omp_redundant_fusion : Warning <
11573+
"loop range in '#pragma omp %0' contains only a single loop, resulting in redundant fusion">;
1156911574
def err_omp_not_for : Error<
1157011575
"%select{statement after '#pragma omp %1' must be a for loop|"
1157111576
"expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">;

clang/include/clang/Parse/Parser.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6739,6 +6739,9 @@ class Parser : public CodeCompletionHandler {
67396739
OpenMPClauseKind Kind,
67406740
bool ParseOnly);
67416741

6742+
/// Parses the 'looprange' clause of a '#pragma omp fuse' directive.
6743+
OMPClause *ParseOpenMPLoopRangeClause();
6744+
67426745
/// Parses the 'sizes' clause of a '#pragma omp tile' directive.
67436746
OMPClause *ParseOpenMPSizesClause();
67446747

clang/include/clang/Sema/SemaOpenMP.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,12 @@ class SemaOpenMP : public SemaBase {
921921
SourceLocation StartLoc,
922922
SourceLocation LParenLoc,
923923
SourceLocation EndLoc);
924+
925+
/// Called on well-form 'looprange' clause after parsing its arguments.
926+
OMPClause *
927+
ActOnOpenMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
928+
SourceLocation LParenLoc, SourceLocation FirstLoc,
929+
SourceLocation CountLoc, SourceLocation EndLoc);
924930
/// Called on well-formed 'ordered' clause.
925931
OMPClause *
926932
ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc,

clang/lib/AST/OpenMPClause.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,26 @@ OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {
10241024
return new (C) OMPPartialClause();
10251025
}
10261026

1027+
OMPLoopRangeClause *
1028+
OMPLoopRangeClause::Create(const ASTContext &C, SourceLocation StartLoc,
1029+
SourceLocation LParenLoc, SourceLocation EndLoc,
1030+
SourceLocation FirstLoc, SourceLocation CountLoc,
1031+
Expr *First, Expr *Count) {
1032+
OMPLoopRangeClause *Clause = CreateEmpty(C);
1033+
Clause->setLocStart(StartLoc);
1034+
Clause->setLParenLoc(LParenLoc);
1035+
Clause->setLocEnd(EndLoc);
1036+
Clause->setFirstLoc(FirstLoc);
1037+
Clause->setCountLoc(CountLoc);
1038+
Clause->setFirst(First);
1039+
Clause->setCount(Count);
1040+
return Clause;
1041+
}
1042+
1043+
OMPLoopRangeClause *OMPLoopRangeClause::CreateEmpty(const ASTContext &C) {
1044+
return new (C) OMPLoopRangeClause();
1045+
}
1046+
10271047
OMPAllocateClause *OMPAllocateClause::Create(
10281048
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
10291049
Expr *Allocator, Expr *Alignment, SourceLocation ColonLoc,
@@ -1888,6 +1908,21 @@ void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) {
18881908
}
18891909
}
18901910

1911+
void OMPClausePrinter::VisitOMPLoopRangeClause(OMPLoopRangeClause *Node) {
1912+
OS << "looprange";
1913+
1914+
Expr *First = Node->getFirst();
1915+
Expr *Count = Node->getCount();
1916+
1917+
if (First && Count) {
1918+
OS << "(";
1919+
First->printPretty(OS, nullptr, Policy, 0);
1920+
OS << ",";
1921+
Count->printPretty(OS, nullptr, Policy, 0);
1922+
OS << ")";
1923+
}
1924+
}
1925+
18911926
void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
18921927
OS << "allocator(";
18931928
Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);

clang/lib/AST/StmtOpenMP.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,10 +524,13 @@ OMPFuseDirective *OMPFuseDirective::Create(
524524

525525
OMPFuseDirective *OMPFuseDirective::CreateEmpty(const ASTContext &C,
526526
unsigned NumClauses,
527-
unsigned NumLoops) {
528-
return createEmptyDirective<OMPFuseDirective>(
527+
unsigned NumLoops,
528+
unsigned NumLoopNests) {
529+
OMPFuseDirective *Dir = createEmptyDirective<OMPFuseDirective>(
529530
C, NumClauses, /*HasAssociatedStmt=*/true, TransformedStmtOffset + 1,
530531
SourceLocation(), SourceLocation(), NumLoops);
532+
Dir->setNumGeneratedLoopNests(NumLoopNests);
533+
return Dir;
531534
}
532535

533536
OMPForSimdDirective *

clang/lib/AST/StmtProfile.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,13 @@ void OMPClauseProfiler::VisitOMPPartialClause(const OMPPartialClause *C) {
511511
Profiler->VisitExpr(Factor);
512512
}
513513

514+
void OMPClauseProfiler::VisitOMPLoopRangeClause(const OMPLoopRangeClause *C) {
515+
if (const Expr *First = C->getFirst())
516+
Profiler->VisitExpr(First);
517+
if (const Expr *Count = C->getCount())
518+
Profiler->VisitExpr(Count);
519+
}
520+
514521
void OMPClauseProfiler::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
515522
if (C->getAllocator())
516523
Profiler->VisitStmt(C->getAllocator());

clang/lib/Basic/OpenMPKinds.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
248248
case OMPC_affinity:
249249
case OMPC_when:
250250
case OMPC_append_args:
251+
case OMPC_looprange:
251252
break;
252253
default:
253254
break;
@@ -583,6 +584,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
583584
case OMPC_affinity:
584585
case OMPC_when:
585586
case OMPC_append_args:
587+
case OMPC_looprange:
586588
break;
587589
default:
588590
break;

0 commit comments

Comments
 (0)