Skip to content

Commit 044ca73

Browse files
committed
Add looprange clause
1 parent 5e01792 commit 044ca73

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
@@ -1151,6 +1151,106 @@ class OMPFullClause final : public OMPNoChildClause<llvm::omp::OMPC_full> {
11511151
static OMPFullClause *CreateEmpty(const ASTContext &C);
11521152
};
11531153

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

clang/include/clang/AST/RecursiveASTVisitor.h

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

3401+
template <typename Derived>
3402+
bool RecursiveASTVisitor<Derived>::VisitOMPLoopRangeClause(
3403+
OMPLoopRangeClause *C) {
3404+
TRY_TO(TraverseStmt(C->getFirst()));
3405+
TRY_TO(TraverseStmt(C->getCount()));
3406+
return true;
3407+
}
3408+
34013409
template <typename Derived>
34023410
bool RecursiveASTVisitor<Derived>::VisitOMPPartialClause(OMPPartialClause *C) {
34033411
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
@@ -11524,6 +11524,11 @@ def err_omp_not_a_loop_sequence : Error <
1152411524
"statement after '#pragma omp %0' must be a loop sequence containing canonical loops or loop-generating constructs">;
1152511525
def err_omp_empty_loop_sequence : Error <
1152611526
"loop sequence after '#pragma omp %0' must contain at least 1 canonical loop or loop-generating construct">;
11527+
def err_omp_invalid_looprange : Error <
11528+
"loop range in '#pragma omp %0' exceeds the number of available loops: "
11529+
"range end '%1' is greater than the total number of loops '%2'">;
11530+
def warn_omp_redundant_fusion : Warning <
11531+
"loop range in '#pragma omp %0' contains only a single loop, resulting in redundant fusion">;
1152711532
def err_omp_not_for : Error<
1152811533
"%select{statement after '#pragma omp %1' must be a for loop|"
1152911534
"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
@@ -3622,6 +3622,9 @@ class Parser : public CodeCompletionHandler {
36223622
OpenMPClauseKind Kind,
36233623
bool ParseOnly);
36243624

3625+
/// Parses the 'looprange' clause of a '#pragma omp fuse' directive.
3626+
OMPClause *ParseOpenMPLoopRangeClause();
3627+
36253628
/// Parses the 'sizes' clause of a '#pragma omp tile' directive.
36263629
OMPClause *ParseOpenMPSizesClause();
36273630

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)