Skip to content

Commit 34ac92a

Browse files
committed
Add looprange clause
1 parent fb91129 commit 34ac92a

File tree

22 files changed

+919
-36
lines changed

22 files changed

+919
-36
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
@@ -3410,6 +3410,14 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFullClause(OMPFullClause *C) {
34103410
return true;
34113411
}
34123412

3413+
template <typename Derived>
3414+
bool RecursiveASTVisitor<Derived>::VisitOMPLoopRangeClause(
3415+
OMPLoopRangeClause *C) {
3416+
TRY_TO(TraverseStmt(C->getFirst()));
3417+
TRY_TO(TraverseStmt(C->getCount()));
3418+
return true;
3419+
}
3420+
34133421
template <typename Derived>
34143422
bool RecursiveASTVisitor<Derived>::VisitOMPPartialClause(OMPPartialClause *C) {
34153423
TRY_TO(TraverseStmt(C->getFactor()));

clang/include/clang/AST/StmtOpenMP.h

Lines changed: 8 additions & 1 deletion
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

@@ -5804,6 +5806,7 @@ class OMPReverseDirective final : public OMPLoopTransformationDirective {
58045806
: OMPLoopTransformationDirective(OMPReverseDirectiveClass,
58055807
llvm::omp::OMPD_reverse, StartLoc,
58065808
EndLoc, NumLoops) {
5809+
// Reverse produces a single top-level canonical loop nest
58075810
setNumGeneratedLoops(NumLoops);
58085811
setNumGeneratedLoopNests(1);
58095812
}
@@ -5877,6 +5880,8 @@ class OMPInterchangeDirective final : public OMPLoopTransformationDirective {
58775880
: OMPLoopTransformationDirective(OMPInterchangeDirectiveClass,
58785881
llvm::omp::OMPD_interchange, StartLoc,
58795882
EndLoc, NumLoops) {
5883+
// Interchange produces a single top-level canonical loop
5884+
// nest, with the exact same amount of total loops
58805885
setNumGeneratedLoops(NumLoops);
58815886
setNumGeneratedLoopNests(1);
58825887
}
@@ -5995,8 +6000,10 @@ class OMPFuseDirective final : public OMPLoopTransformationDirective {
59956000
/// \param C Context of the AST
59966001
/// \param NumClauses Number of clauses to allocate
59976002
/// \param NumLoops Number of associated loops to allocate
6003+
/// \param NumLoopNests Number of top level loops to allocate
59986004
static OMPFuseDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5999-
unsigned NumLoops);
6005+
unsigned NumLoops,
6006+
unsigned NumLoopNests);
60006007

60016008
/// Gets the associated loops after the transformation. This is the de-sugared
60026009
/// 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
@@ -11620,6 +11620,11 @@ def err_omp_not_a_loop_sequence : Error <
1162011620
"statement after '#pragma omp %0' must be a loop sequence containing canonical loops or loop-generating constructs">;
1162111621
def err_omp_empty_loop_sequence : Error <
1162211622
"loop sequence after '#pragma omp %0' must contain at least 1 canonical loop or loop-generating construct">;
11623+
def err_omp_invalid_looprange : Error <
11624+
"loop range in '#pragma omp %0' exceeds the number of available loops: "
11625+
"range end '%1' is greater than the total number of loops '%2'">;
11626+
def warn_omp_redundant_fusion : Warning <
11627+
"loop range in '#pragma omp %0' contains only a single loop, resulting in redundant fusion">;
1162311628
def err_omp_not_for : Error<
1162411629
"%select{statement after '#pragma omp %1' must be a for loop|"
1162511630
"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
@@ -6735,6 +6735,9 @@ class Parser : public CodeCompletionHandler {
67356735
OpenMPClauseKind Kind,
67366736
bool ParseOnly);
67376737

6738+
/// Parses the 'looprange' clause of a '#pragma omp fuse' directive.
6739+
OMPClause *ParseOpenMPLoopRangeClause();
6740+
67386741
/// Parses the 'sizes' clause of a '#pragma omp tile' directive.
67396742
OMPClause *ParseOpenMPSizesClause();
67406743

clang/include/clang/Sema/SemaOpenMP.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,12 @@ class SemaOpenMP : public SemaBase {
922922
SourceLocation StartLoc,
923923
SourceLocation LParenLoc,
924924
SourceLocation EndLoc);
925+
926+
/// Called on well-form 'looprange' clause after parsing its arguments.
927+
OMPClause *
928+
ActOnOpenMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
929+
SourceLocation LParenLoc, SourceLocation FirstLoc,
930+
SourceLocation CountLoc, SourceLocation EndLoc);
925931
/// Called on well-formed 'ordered' clause.
926932
OMPClause *
927933
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
@@ -527,10 +527,13 @@ OMPFuseDirective *OMPFuseDirective::Create(
527527

528528
OMPFuseDirective *OMPFuseDirective::CreateEmpty(const ASTContext &C,
529529
unsigned NumClauses,
530-
unsigned NumLoops) {
531-
return createEmptyDirective<OMPFuseDirective>(
530+
unsigned NumLoops,
531+
unsigned NumLoopNests) {
532+
OMPFuseDirective *Dir = createEmptyDirective<OMPFuseDirective>(
532533
C, NumClauses, /*HasAssociatedStmt=*/true, TransformedStmtOffset + 1,
533534
SourceLocation(), SourceLocation(), NumLoops);
535+
Dir->setNumGeneratedLoopNests(NumLoopNests);
536+
return Dir;
534537
}
535538

536539
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)