Skip to content

Commit 07abc54

Browse files
committed
[flang] Implement !DIR$ UNROLL_AND_JAM [N]
1 parent 62bcbe6 commit 07abc54

File tree

10 files changed

+97
-5
lines changed

10 files changed

+97
-5
lines changed

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ class ParseTreeDumper {
209209
NODE(CompilerDirective, Unrecognized)
210210
NODE(CompilerDirective, VectorAlways)
211211
NODE(CompilerDirective, Unroll)
212+
NODE(CompilerDirective, UnrollAndJam)
212213
NODE(parser, ComplexLiteralConstant)
213214
NODE(parser, ComplexPart)
214215
NODE(parser, ComponentArraySpec)

flang/include/flang/Parser/parse-tree.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3349,6 +3349,7 @@ struct StmtFunctionStmt {
33493349
// !DIR$ IGNORE_TKR [ [(tkrdmac...)] name ]...
33503350
// !DIR$ LOOP COUNT (n1[, n2]...)
33513351
// !DIR$ name[=value] [, name[=value]]... = can be :
3352+
// !DIR$ UNROLL_AND_JAM [N]
33523353
// !DIR$ <anything else>
33533354
struct CompilerDirective {
33543355
UNION_CLASS_BOILERPLATE(CompilerDirective);
@@ -3371,10 +3372,13 @@ struct CompilerDirective {
33713372
struct Unroll {
33723373
WRAPPER_CLASS_BOILERPLATE(Unroll, std::optional<std::uint64_t>);
33733374
};
3375+
struct UnrollAndJam {
3376+
WRAPPER_CLASS_BOILERPLATE(UnrollAndJam, std::optional<std::uint64_t>);
3377+
};
33743378
EMPTY_CLASS(Unrecognized);
33753379
CharBlock source;
33763380
std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>,
3377-
VectorAlways, std::list<NameValue>, Unroll, Unrecognized>
3381+
VectorAlways, std::list<NameValue>, Unroll, UnrollAndJam, Unrecognized>
33783382
u;
33793383
};
33803384

flang/lib/Lower/Bridge.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2177,6 +2177,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
21772177
mlir::BoolAttr t = mlir::BoolAttr::get(builder->getContext(), true);
21782178
mlir::LLVM::LoopVectorizeAttr va;
21792179
mlir::LLVM::LoopUnrollAttr ua;
2180+
mlir::LLVM::LoopUnrollAndJamAttr uja;
21802181
bool has_attrs = false;
21812182
for (const auto *dir : dirs) {
21822183
Fortran::common::visit(
@@ -2198,12 +2199,23 @@ class FirConverter : public Fortran::lower::AbstractConverter {
21982199
{}, /*full*/ u.v.has_value() ? f : t, {}, {}, {});
21992200
has_attrs = true;
22002201
},
2202+
[&](const Fortran::parser::CompilerDirective::UnrollAndJam &u) {
2203+
mlir::IntegerAttr countAttr;
2204+
if (u.v.has_value()) {
2205+
countAttr = builder->getIntegerAttr(builder->getI64Type(),
2206+
u.v.value());
2207+
}
2208+
uja = mlir::LLVM::LoopUnrollAndJamAttr::get(
2209+
builder->getContext(), /*disable=*/f, /*count*/ countAttr,
2210+
{}, {}, {}, {}, {});
2211+
has_attrs = true;
2212+
},
22012213
[&](const auto &) {}},
22022214
dir->u);
22032215
}
22042216
mlir::LLVM::LoopAnnotationAttr la = mlir::LLVM::LoopAnnotationAttr::get(
2205-
builder->getContext(), {}, /*vectorize=*/va, {}, /*unroll*/ ua, {}, {},
2206-
{}, {}, {}, {}, {}, {}, {}, {}, {});
2217+
builder->getContext(), {}, /*vectorize=*/va, {}, /*unroll*/ ua,
2218+
/*unroll_and_jam*/ uja, {}, {}, {}, {}, {}, {}, {}, {}, {}, {});
22072219
if (has_attrs)
22082220
info.doLoop.setLoopAnnotationAttr(la);
22092221
}
@@ -2859,6 +2871,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
28592871
[&](const Fortran::parser::CompilerDirective::Unroll &) {
28602872
attachDirectiveToLoop(dir, &eval);
28612873
},
2874+
[&](const Fortran::parser::CompilerDirective::UnrollAndJam &) {
2875+
attachDirectiveToLoop(dir, &eval);
2876+
},
28622877
[&](const auto &) {}},
28632878
dir.u);
28642879
}

flang/lib/Parser/Fortran-parsers.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,11 +1308,14 @@ constexpr auto vectorAlways{
13081308
"VECTOR ALWAYS" >> construct<CompilerDirective::VectorAlways>()};
13091309
constexpr auto unroll{
13101310
"UNROLL" >> construct<CompilerDirective::Unroll>(maybe(digitString64))};
1311+
constexpr auto unrollAndJam{"UNROLL_AND_JAM" >>
1312+
construct<CompilerDirective::UnrollAndJam>(maybe(digitString64))};
13111313
TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
13121314
sourced((construct<CompilerDirective>(ignore_tkr) ||
13131315
construct<CompilerDirective>(loopCount) ||
13141316
construct<CompilerDirective>(assumeAligned) ||
13151317
construct<CompilerDirective>(vectorAlways) ||
1318+
construct<CompilerDirective>(unrollAndJam) ||
13161319
construct<CompilerDirective>(unroll) ||
13171320
construct<CompilerDirective>(
13181321
many(construct<CompilerDirective::NameValue>(

flang/lib/Parser/unparse.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,6 +1851,10 @@ class UnparseVisitor {
18511851
Word("!DIR$ UNROLL");
18521852
Walk(" ", unroll.v);
18531853
},
1854+
[&](const CompilerDirective::UnrollAndJam &unrollAndJam) {
1855+
Word("!DIR$ UNROLL_AND_JAM");
1856+
Walk(" ", unrollAndJam.v);
1857+
},
18541858
[&](const CompilerDirective::Unrecognized &) {
18551859
Word("!DIR$ ");
18561860
Word(x.source.ToString());

flang/lib/Semantics/canonicalize-directives.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ bool CanonicalizeDirectives(
5656
static bool IsExecutionDirective(const parser::CompilerDirective &dir) {
5757
return std::holds_alternative<parser::CompilerDirective::VectorAlways>(
5858
dir.u) ||
59-
std::holds_alternative<parser::CompilerDirective::Unroll>(dir.u);
59+
std::holds_alternative<parser::CompilerDirective::Unroll>(dir.u) ||
60+
std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(dir.u);
6061
}
6162

6263
void CanonicalizationOfDirectives::Post(parser::SpecificationPart &spec) {
@@ -115,6 +116,9 @@ void CanonicalizationOfDirectives::Post(parser::Block &block) {
115116
[&](parser::CompilerDirective::Unroll &) {
116117
CheckLoopDirective(*dir, block, it);
117118
},
119+
[&](parser::CompilerDirective::UnrollAndJam &) {
120+
CheckLoopDirective(*dir, block, it);
121+
},
118122
[&](auto &) {}},
119123
dir->u);
120124
}

flang/lib/Semantics/resolve-names.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9459,7 +9459,8 @@ void ResolveNamesVisitor::Post(const parser::AssignedGotoStmt &x) {
94599459

94609460
void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) {
94619461
if (std::holds_alternative<parser::CompilerDirective::VectorAlways>(x.u) ||
9462-
std::holds_alternative<parser::CompilerDirective::Unroll>(x.u)) {
9462+
std::holds_alternative<parser::CompilerDirective::Unroll>(x.u) ||
9463+
std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(x.u)) {
94639464
return;
94649465
}
94659466
if (const auto *tkr{
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
! RUN: %flang_fc1 -emit-llvm -o - %s | FileCheck %s
2+
3+
! CHECK-LABEL: unroll_and_jam_dir
4+
subroutine unroll_and_jam_dir
5+
integer :: a(10)
6+
!dir$ unroll_and_jam 4
7+
! CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[ANNOTATION:.*]]
8+
do i=1,10
9+
a(i)=i
10+
end do
11+
end subroutine unroll_and_jam_dir
12+
13+
! CHECK: ![[ANNOTATION]] = distinct !{![[ANNOTATION]], ![[UNROLL_AND_JAM:.*]], ![[UNROLL_AND_JAM_COUNT:.*]]}
14+
! CHECK: ![[UNROLL_AND_JAM]] = !{!"llvm.loop.unroll_and_jam.enable"}
15+
! CHECK: ![[UNROLL_AND_JAM_COUNT]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}

flang/test/Lower/unroll_and_jam.f90

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck %s
2+
3+
! CHECK: #loop_unroll_and_jam = #llvm.loop_unroll_and_jam<disable = false>
4+
! CHECK: #loop_unroll_and_jam1 = #llvm.loop_unroll_and_jam<disable = false, count = 2 : i64>
5+
! CHECK: #loop_annotation = #llvm.loop_annotation<unrollAndJam = #loop_unroll_and_jam>
6+
! CHECK: #loop_annotation1 = #llvm.loop_annotation<unrollAndJam = #loop_unroll_and_jam1>
7+
8+
! CHECK-LABEL: unroll_and_jam_dir
9+
subroutine unroll_and_jam_dir
10+
integer :: a(10)
11+
!dir$ unroll_and_jam
12+
!CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation}
13+
do i=1,10
14+
a(i)=i
15+
end do
16+
17+
!dir$ unroll_and_jam 2
18+
!CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation1}
19+
do i=1,10
20+
a(i)=i
21+
end do
22+
end subroutine unroll_and_jam_dir
23+
24+
25+
! CHECK-LABEL: intermediate_directive
26+
subroutine intermediate_directive
27+
integer :: a(10)
28+
!dir$ unroll_and_jam
29+
!dir$ unknown
30+
!CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation}
31+
do i=1,10
32+
a(i)=i
33+
end do
34+
end subroutine intermediate_directive

flang/test/Parser/compiler-directives.f90

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,14 @@ subroutine unroll
4646
do i=1,10
4747
enddo
4848
end subroutine
49+
50+
subroutine unroll_and_jam
51+
!dir$ unroll_and_jam
52+
! CHECK: !DIR$ UNROLL_AND_JAM
53+
do i=1,10
54+
enddo
55+
!dir$ unroll_and_jam 2
56+
! CHECK: !DIR$ UNROLL_AND_JAM 2
57+
do i=1,10
58+
enddo
59+
end subroutine

0 commit comments

Comments
 (0)