Skip to content

Commit c309abd

Browse files
authored
[flang] Implement !DIR$ NOVECTOR and !DIR$ NOUNROLL[_AND_JAM] (#133885)
Hi, This patch implements support for the following directives : - `!DIR$ NOUNROLL_AND_JAM` to disable unrolling and jamming on a DO LOOP. - `!DIR$ NOUNROLL` to disable unrolling on a DO LOOP. - `!DIR$ NOVECTOR` to disable vectorization on a DO LOOP.
1 parent 842785a commit c309abd

File tree

13 files changed

+136
-3
lines changed

13 files changed

+136
-3
lines changed

flang/docs/Directives.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ A list of non-standard directives supported by Flang
5050
integer that specifying the unrolling factor. When `N` is `0` or `1`, the loop
5151
should not be unrolled at all. If `N` is omitted the optimizer will
5252
selects the number of times to unroll the loop.
53+
* `!dir$ novector` disabling vectorization on the following loop.
54+
* `!dir$ nounroll` disabling unrolling on the following loop.
55+
* `!dir$ nounroll_and_jam` disabling unrolling and jamming on the following loop.
5356

5457
# Directive Details
5558

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ class ParseTreeDumper {
210210
NODE(CompilerDirective, VectorAlways)
211211
NODE(CompilerDirective, Unroll)
212212
NODE(CompilerDirective, UnrollAndJam)
213+
NODE(CompilerDirective, NoVector)
214+
NODE(CompilerDirective, NoUnroll)
215+
NODE(CompilerDirective, NoUnrollAndJam)
213216
NODE(parser, ComplexLiteralConstant)
214217
NODE(parser, ComplexPart)
215218
NODE(parser, ComponentArraySpec)

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3351,6 +3351,9 @@ struct StmtFunctionStmt {
33513351
// !DIR$ name[=value] [, name[=value]]... = can be :
33523352
// !DIR$ UNROLL [N]
33533353
// !DIR$ UNROLL_AND_JAM [N]
3354+
// !DIR$ NOVECTOR
3355+
// !DIR$ NOUNROLL
3356+
// !DIR$ NOUNROLL_AND_JAM
33543357
// !DIR$ <anything else>
33553358
struct CompilerDirective {
33563359
UNION_CLASS_BOILERPLATE(CompilerDirective);
@@ -3376,10 +3379,14 @@ struct CompilerDirective {
33763379
struct UnrollAndJam {
33773380
WRAPPER_CLASS_BOILERPLATE(UnrollAndJam, std::optional<std::uint64_t>);
33783381
};
3382+
EMPTY_CLASS(NoVector);
3383+
EMPTY_CLASS(NoUnroll);
3384+
EMPTY_CLASS(NoUnrollAndJam);
33793385
EMPTY_CLASS(Unrecognized);
33803386
CharBlock source;
33813387
std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>,
3382-
VectorAlways, std::list<NameValue>, Unroll, UnrollAndJam, Unrecognized>
3388+
VectorAlways, std::list<NameValue>, Unroll, UnrollAndJam, Unrecognized,
3389+
NoVector, NoUnroll, NoUnrollAndJam>
33833390
u;
33843391
};
33853392

flang/lib/Lower/Bridge.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,6 +2268,23 @@ class FirConverter : public Fortran::lower::AbstractConverter {
22682268
uja = genLoopUnrollAndJamAttr(u.v);
22692269
has_attrs = true;
22702270
},
2271+
[&](const Fortran::parser::CompilerDirective::NoVector &u) {
2272+
mlir::BoolAttr trueAttr =
2273+
mlir::BoolAttr::get(builder->getContext(), true);
2274+
va = mlir::LLVM::LoopVectorizeAttr::get(builder->getContext(),
2275+
/*disable=*/trueAttr,
2276+
{}, {}, {}, {}, {}, {});
2277+
has_attrs = true;
2278+
},
2279+
[&](const Fortran::parser::CompilerDirective::NoUnroll &u) {
2280+
ua = genLoopUnrollAttr(/*unrollingFactor=*/0);
2281+
has_attrs = true;
2282+
},
2283+
[&](const Fortran::parser::CompilerDirective::NoUnrollAndJam &u) {
2284+
uja = genLoopUnrollAndJamAttr(/*unrollingFactor=*/0);
2285+
has_attrs = true;
2286+
},
2287+
22712288
[&](const auto &) {}},
22722289
dir->u);
22732290
}
@@ -2932,6 +2949,15 @@ class FirConverter : public Fortran::lower::AbstractConverter {
29322949
[&](const Fortran::parser::CompilerDirective::UnrollAndJam &) {
29332950
attachDirectiveToLoop(dir, &eval);
29342951
},
2952+
[&](const Fortran::parser::CompilerDirective::NoVector &) {
2953+
attachDirectiveToLoop(dir, &eval);
2954+
},
2955+
[&](const Fortran::parser::CompilerDirective::NoUnroll &) {
2956+
attachDirectiveToLoop(dir, &eval);
2957+
},
2958+
[&](const Fortran::parser::CompilerDirective::NoUnrollAndJam &) {
2959+
attachDirectiveToLoop(dir, &eval);
2960+
},
29352961
[&](const auto &) {}},
29362962
dir.u);
29372963
}

flang/lib/Parser/Fortran-parsers.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,13 +1310,20 @@ constexpr auto unroll{
13101310
"UNROLL" >> construct<CompilerDirective::Unroll>(maybe(digitString64))};
13111311
constexpr auto unrollAndJam{"UNROLL_AND_JAM" >>
13121312
construct<CompilerDirective::UnrollAndJam>(maybe(digitString64))};
1313+
constexpr auto novector{"NOVECTOR" >> construct<CompilerDirective::NoVector>()};
1314+
constexpr auto nounroll{"NOUNROLL" >> construct<CompilerDirective::NoUnroll>()};
1315+
constexpr auto nounrollAndJam{
1316+
"NOUNROLL_AND_JAM" >> construct<CompilerDirective::NoUnrollAndJam>()};
13131317
TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
13141318
sourced((construct<CompilerDirective>(ignore_tkr) ||
13151319
construct<CompilerDirective>(loopCount) ||
13161320
construct<CompilerDirective>(assumeAligned) ||
13171321
construct<CompilerDirective>(vectorAlways) ||
13181322
construct<CompilerDirective>(unrollAndJam) ||
13191323
construct<CompilerDirective>(unroll) ||
1324+
construct<CompilerDirective>(novector) ||
1325+
construct<CompilerDirective>(nounrollAndJam) ||
1326+
construct<CompilerDirective>(nounroll) ||
13201327
construct<CompilerDirective>(
13211328
many(construct<CompilerDirective::NameValue>(
13221329
name, maybe(("="_tok || ":"_tok) >> digitString64))))) /

flang/lib/Parser/unparse.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,6 +1855,15 @@ class UnparseVisitor {
18551855
Word("!DIR$ UNROLL_AND_JAM");
18561856
Walk(" ", unrollAndJam.v);
18571857
},
1858+
[&](const CompilerDirective::NoVector &) {
1859+
Word("!DIR$ NOVECTOR");
1860+
},
1861+
[&](const CompilerDirective::NoUnroll &) {
1862+
Word("!DIR$ NOUNROLL");
1863+
},
1864+
[&](const CompilerDirective::NoUnrollAndJam &) {
1865+
Word("!DIR$ NOUNROLL_AND_JAM");
1866+
},
18581867
[&](const CompilerDirective::Unrecognized &) {
18591868
Word("!DIR$ ");
18601869
Word(x.source.ToString());

flang/lib/Semantics/canonicalize-directives.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ static bool IsExecutionDirective(const parser::CompilerDirective &dir) {
5757
return std::holds_alternative<parser::CompilerDirective::VectorAlways>(
5858
dir.u) ||
5959
std::holds_alternative<parser::CompilerDirective::Unroll>(dir.u) ||
60-
std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(dir.u);
60+
std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(dir.u) ||
61+
std::holds_alternative<parser::CompilerDirective::NoVector>(dir.u) ||
62+
std::holds_alternative<parser::CompilerDirective::NoUnroll>(dir.u) ||
63+
std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(dir.u);
6164
}
6265

6366
void CanonicalizationOfDirectives::Post(parser::SpecificationPart &spec) {
@@ -119,6 +122,15 @@ void CanonicalizationOfDirectives::Post(parser::Block &block) {
119122
[&](parser::CompilerDirective::UnrollAndJam &) {
120123
CheckLoopDirective(*dir, block, it);
121124
},
125+
[&](parser::CompilerDirective::NoVector &) {
126+
CheckLoopDirective(*dir, block, it);
127+
},
128+
[&](parser::CompilerDirective::NoUnroll &) {
129+
CheckLoopDirective(*dir, block, it);
130+
},
131+
[&](parser::CompilerDirective::NoUnrollAndJam &) {
132+
CheckLoopDirective(*dir, block, it);
133+
},
122134
[&](auto &) {}},
123135
dir->u);
124136
}

flang/lib/Semantics/resolve-names.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9573,7 +9573,10 @@ void ResolveNamesVisitor::Post(const parser::AssignedGotoStmt &x) {
95739573
void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) {
95749574
if (std::holds_alternative<parser::CompilerDirective::VectorAlways>(x.u) ||
95759575
std::holds_alternative<parser::CompilerDirective::Unroll>(x.u) ||
9576-
std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(x.u)) {
9576+
std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(x.u) ||
9577+
std::holds_alternative<parser::CompilerDirective::NoVector>(x.u) ||
9578+
std::holds_alternative<parser::CompilerDirective::NoUnroll>(x.u) ||
9579+
std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(x.u)) {
95779580
return;
95789581
}
95799582
if (const auto *tkr{

flang/test/Integration/unroll_and_jam.f90

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ subroutine unroll_and_jam_dir_1
3030
end do
3131
end subroutine unroll_and_jam_dir_1
3232

33+
! CHECK-LABEL: nounroll_and_jam_dir
34+
subroutine nounroll_and_jam_dir
35+
integer :: a(10)
36+
!dir$ nounroll_and_jam
37+
! CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[ANNOTATION_DISABLE]]
38+
do i=1,10
39+
a(i)=i
40+
end do
41+
end subroutine nounroll_and_jam_dir
42+
3343
! CHECK-LABEL: unroll_and_jam_dir_no_factor
3444
subroutine unroll_and_jam_dir_no_factor
3545
integer :: a(10)

flang/test/Integration/vector-always.f90

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,17 @@ subroutine vector_always
1010
end do
1111
end subroutine vector_always
1212

13+
! CHECK-LABEL: no_vector
14+
subroutine no_vector
15+
integer :: a(10)
16+
!dir$ novector
17+
! CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[ANNOTATION2:.*]]
18+
do i=1,10
19+
a(i)=i
20+
end do
21+
end subroutine no_vector
22+
1323
! CHECK: ![[ANNOTATION]] = distinct !{![[ANNOTATION]], ![[VECTORIZE:.*]]}
1424
! CHECK: ![[VECTORIZE]] = !{!"llvm.loop.vectorize.enable", i1 true}
25+
! CHECK: ![[ANNOTATION2]] = distinct !{![[ANNOTATION2]], ![[VECTORIZE2:.*]]}
26+
! CHECK: ![[VECTORIZE2]] = !{!"llvm.loop.vectorize.enable", i1 false}

flang/test/Lower/unroll_and_jam.f90

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
! CHECK: #loop_unroll_and_jam = #llvm.loop_unroll_and_jam<disable = false>
44
! CHECK: #loop_unroll_and_jam1 = #llvm.loop_unroll_and_jam<disable = false, count = 2 : i64>
5+
! CHECK: #loop_unroll_and_jam2 = #llvm.loop_unroll_and_jam<disable = true>
56
! CHECK: #loop_annotation = #llvm.loop_annotation<unrollAndJam = #loop_unroll_and_jam>
67
! CHECK: #loop_annotation1 = #llvm.loop_annotation<unrollAndJam = #loop_unroll_and_jam1>
8+
! CHECK: #loop_annotation2 = #llvm.loop_annotation<unrollAndJam = #loop_unroll_and_jam2>
79

810
! CHECK-LABEL: unroll_and_jam_dir
911
subroutine unroll_and_jam_dir
@@ -32,3 +34,14 @@ subroutine intermediate_directive
3234
a(i)=i
3335
end do
3436
end subroutine intermediate_directive
37+
38+
39+
! CHECK-LABEL: nounroll_and_jam_dir
40+
subroutine nounroll_and_jam_dir
41+
integer :: a(10)
42+
!dir$ nounroll_and_jam
43+
!CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation2}
44+
do i=1,10
45+
a(i)=i
46+
end do
47+
end subroutine nounroll_and_jam_dir

flang/test/Lower/vector-always.f90

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck %s
22

33
! CHECK: #loop_vectorize = #llvm.loop_vectorize<disable = false>
4+
! CHECK: #loop_vectorize1 = #llvm.loop_vectorize<disable = true>
45
! CHECK: #loop_annotation = #llvm.loop_annotation<vectorize = #loop_vectorize>
6+
! CHECK: #loop_annotation1 = #llvm.loop_annotation<vectorize = #loop_vectorize1>
57

68
! CHECK-LABEL: vector_always
79
subroutine vector_always
@@ -24,3 +26,14 @@ subroutine intermediate_directive
2426
a(i)=i
2527
end do
2628
end subroutine intermediate_directive
29+
30+
31+
! CHECK-LABEL: no_vector
32+
subroutine no_vector
33+
integer :: a(10)
34+
!dir$ novector
35+
!CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation1}
36+
do i=1,10
37+
a(i)=i
38+
end do
39+
end subroutine no_vector

flang/test/Parser/compiler-directives.f90

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ subroutine unroll
4545
! CHECK: !DIR$ UNROLL 2
4646
do i=1,10
4747
enddo
48+
!dir$ nounroll
49+
! CHECK: !DIR$ NOUNROLL
50+
do i=1,10
51+
enddo
4852
end subroutine
4953

5054
subroutine unroll_and_jam
@@ -56,4 +60,15 @@ subroutine unroll_and_jam
5660
! CHECK: !DIR$ UNROLL_AND_JAM 2
5761
do i=1,10
5862
enddo
63+
!dir$ nounroll_and_jam
64+
! CHECK: !DIR$ NOUNROLL_AND_JAM
65+
do i=1,10
66+
enddo
67+
end subroutine
68+
69+
subroutine no_vector
70+
!dir$ novector
71+
! CHECK: !DIR$ NOVECTOR
72+
do i=1,10
73+
enddo
5974
end subroutine

0 commit comments

Comments
 (0)