Skip to content

Commit 0029229

Browse files
committed
[flang] Implement !DIR$ IVDEP directive
1 parent f9cdd22 commit 0029229

File tree

11 files changed

+93
-14
lines changed

11 files changed

+93
-14
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ class ParseTreeDumper {
206206
NODE(parser, CompilerDirective)
207207
NODE(CompilerDirective, AssumeAligned)
208208
NODE(CompilerDirective, IgnoreTKR)
209+
NODE(CompilerDirective, IVDep)
209210
NODE(CompilerDirective, LoopCount)
210211
NODE(CompilerDirective, NameValue)
211212
NODE(CompilerDirective, Unrecognized)

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3354,6 +3354,7 @@ struct StmtFunctionStmt {
33543354
// !DIR$ NOVECTOR
33553355
// !DIR$ NOUNROLL
33563356
// !DIR$ NOUNROLL_AND_JAM
3357+
// !DIR$ IVDEP
33573358
// !DIR$ <anything else>
33583359
struct CompilerDirective {
33593360
UNION_CLASS_BOILERPLATE(CompilerDirective);
@@ -3382,11 +3383,12 @@ struct CompilerDirective {
33823383
EMPTY_CLASS(NoVector);
33833384
EMPTY_CLASS(NoUnroll);
33843385
EMPTY_CLASS(NoUnrollAndJam);
3386+
EMPTY_CLASS(IVDep);
33853387
EMPTY_CLASS(Unrecognized);
33863388
CharBlock source;
33873389
std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>,
33883390
VectorAlways, std::list<NameValue>, Unroll, UnrollAndJam, Unrecognized,
3389-
NoVector, NoUnroll, NoUnrollAndJam>
3391+
NoVector, NoUnroll, NoUnrollAndJam, IVDep>
33903392
u;
33913393
};
33923394

flang/lib/Lower/Bridge.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,22 +2428,33 @@ class FirConverter : public Fortran::lower::AbstractConverter {
24282428
{}, {}, {}, {});
24292429
}
24302430

2431+
// Enabling loop vectorization attribute.
2432+
mlir::LLVM::LoopVectorizeAttr
2433+
genLoopVectorizeAttr(mlir::BoolAttr disableAttr,
2434+
mlir::BoolAttr ivdepEnableAttr) {
2435+
mlir::LLVM::LoopVectorizeAttr va;
2436+
if (disableAttr || ivdepEnableAttr)
2437+
va = mlir::LLVM::LoopVectorizeAttr::get(builder->getContext(),
2438+
/*disable=*/disableAttr, {}, {},
2439+
/*ivdepEnable*/ ivdepEnableAttr,
2440+
{}, {}, {}, {});
2441+
return va;
2442+
}
2443+
24312444
void addLoopAnnotationAttr(
24322445
IncrementLoopInfo &info,
24332446
llvm::SmallVectorImpl<const Fortran::parser::CompilerDirective *> &dirs) {
2434-
mlir::LLVM::LoopVectorizeAttr va;
2447+
mlir::BoolAttr disableVecAttr, ivdepEnableAttr;
24352448
mlir::LLVM::LoopUnrollAttr ua;
24362449
mlir::LLVM::LoopUnrollAndJamAttr uja;
2450+
llvm::SmallVector<mlir::LLVM::AccessGroupAttr> aga;
24372451
bool has_attrs = false;
24382452
for (const auto *dir : dirs) {
24392453
Fortran::common::visit(
24402454
Fortran::common::visitors{
24412455
[&](const Fortran::parser::CompilerDirective::VectorAlways &) {
2442-
mlir::BoolAttr falseAttr =
2456+
disableVecAttr =
24432457
mlir::BoolAttr::get(builder->getContext(), false);
2444-
va = mlir::LLVM::LoopVectorizeAttr::get(builder->getContext(),
2445-
/*disable=*/falseAttr,
2446-
{}, {}, {}, {}, {}, {});
24472458
has_attrs = true;
24482459
},
24492460
[&](const Fortran::parser::CompilerDirective::Unroll &u) {
@@ -2455,11 +2466,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
24552466
has_attrs = true;
24562467
},
24572468
[&](const Fortran::parser::CompilerDirective::NoVector &u) {
2458-
mlir::BoolAttr trueAttr =
2469+
disableVecAttr =
24592470
mlir::BoolAttr::get(builder->getContext(), true);
2460-
va = mlir::LLVM::LoopVectorizeAttr::get(builder->getContext(),
2461-
/*disable=*/trueAttr,
2462-
{}, {}, {}, {}, {}, {});
24632471
has_attrs = true;
24642472
},
24652473
[&](const Fortran::parser::CompilerDirective::NoUnroll &u) {
@@ -2470,10 +2478,16 @@ class FirConverter : public Fortran::lower::AbstractConverter {
24702478
uja = genLoopUnrollAndJamAttr(/*unrollingFactor=*/0);
24712479
has_attrs = true;
24722480
},
2473-
2481+
[&](const Fortran::parser::CompilerDirective::IVDep &iv) {
2482+
ivdepEnableAttr =
2483+
mlir::BoolAttr::get(builder->getContext(), true);
2484+
has_attrs = true;
2485+
},
24742486
[&](const auto &) {}},
24752487
dir->u);
24762488
}
2489+
mlir::LLVM::LoopVectorizeAttr va =
2490+
genLoopVectorizeAttr(disableVecAttr, ivdepEnableAttr);
24772491
mlir::LLVM::LoopAnnotationAttr la = mlir::LLVM::LoopAnnotationAttr::get(
24782492
builder->getContext(), {}, /*vectorize=*/va, {}, /*unroll*/ ua,
24792493
/*unroll_and_jam*/ uja, {}, {}, {}, {}, {}, {}, {}, {}, {}, {});
@@ -3178,6 +3192,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
31783192
[&](const Fortran::parser::CompilerDirective::NoUnrollAndJam &) {
31793193
attachDirectiveToLoop(dir, &eval);
31803194
},
3195+
[&](const Fortran::parser::CompilerDirective::IVDep &) {
3196+
attachDirectiveToLoop(dir, &eval);
3197+
},
31813198
[&](const auto &) {}},
31823199
dir.u);
31833200
}

flang/lib/Optimizer/Builder/HLFIRTools.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ hlfir::LoopNest hlfir::genLoopNest(mlir::Location loc,
983983
if (!couldVectorize) {
984984
mlir::LLVM::LoopVectorizeAttr va{mlir::LLVM::LoopVectorizeAttr::get(
985985
builder.getContext(),
986-
/*disable=*/builder.getBoolAttr(true), {}, {}, {}, {}, {}, {})};
986+
/*disable=*/builder.getBoolAttr(true), {}, {}, {}, {}, {}, {}, {})};
987987
mlir::LLVM::LoopAnnotationAttr la = mlir::LLVM::LoopAnnotationAttr::get(
988988
builder.getContext(), {}, /*vectorize=*/va, {}, /*unroll*/ {},
989989
/*unroll_and_jam*/ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {});

flang/lib/Parser/Fortran-parsers.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,7 @@ TYPE_PARSER(construct<StatOrErrmsg>("STAT =" >> statVariable) ||
12941294
// !DIR$ LOOP COUNT (n1[, n2]...)
12951295
// !DIR$ name[=value] [, name[=value]]...
12961296
// !DIR$ UNROLL [n]
1297+
// !DIR$ IVDEP
12971298
// !DIR$ <anything else>
12981299
constexpr auto ignore_tkr{
12991300
"IGNORE_TKR" >> optionalList(construct<CompilerDirective::IgnoreTKR>(
@@ -1314,6 +1315,7 @@ constexpr auto novector{"NOVECTOR" >> construct<CompilerDirective::NoVector>()};
13141315
constexpr auto nounroll{"NOUNROLL" >> construct<CompilerDirective::NoUnroll>()};
13151316
constexpr auto nounrollAndJam{
13161317
"NOUNROLL_AND_JAM" >> construct<CompilerDirective::NoUnrollAndJam>()};
1318+
constexpr auto ivdep{"IVDEP" >> construct<CompilerDirective::IVDep>()};
13171319
TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
13181320
sourced((construct<CompilerDirective>(ignore_tkr) ||
13191321
construct<CompilerDirective>(loopCount) ||
@@ -1324,6 +1326,7 @@ TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
13241326
construct<CompilerDirective>(novector) ||
13251327
construct<CompilerDirective>(nounrollAndJam) ||
13261328
construct<CompilerDirective>(nounroll) ||
1329+
construct<CompilerDirective>(ivdep) ||
13271330
construct<CompilerDirective>(
13281331
many(construct<CompilerDirective::NameValue>(
13291332
name, maybe(("="_tok || ":"_tok) >> digitString64))))) /

flang/lib/Parser/unparse.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,6 +1867,7 @@ class UnparseVisitor {
18671867
[&](const CompilerDirective::NoUnrollAndJam &) {
18681868
Word("!DIR$ NOUNROLL_AND_JAM");
18691869
},
1870+
[&](const CompilerDirective::IVDep &) { Word("!DIR$ IVDEP"); },
18701871
[&](const CompilerDirective::Unrecognized &) {
18711872
Word("!DIR$ ");
18721873
Word(x.source.ToString());

flang/lib/Semantics/canonicalize-directives.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ static bool IsExecutionDirective(const parser::CompilerDirective &dir) {
6060
std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(dir.u) ||
6161
std::holds_alternative<parser::CompilerDirective::NoVector>(dir.u) ||
6262
std::holds_alternative<parser::CompilerDirective::NoUnroll>(dir.u) ||
63-
std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(dir.u);
63+
std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(
64+
dir.u) ||
65+
std::holds_alternative<parser::CompilerDirective::IVDep>(dir.u);
6466
}
6567

6668
void CanonicalizationOfDirectives::Post(parser::SpecificationPart &spec) {
@@ -131,6 +133,9 @@ void CanonicalizationOfDirectives::Post(parser::Block &block) {
131133
[&](parser::CompilerDirective::NoUnrollAndJam &) {
132134
CheckLoopDirective(*dir, block, it);
133135
},
136+
[&](parser::CompilerDirective::IVDep &) {
137+
CheckLoopDirective(*dir, block, it);
138+
},
134139
[&](auto &) {}},
135140
dir->u);
136141
}

flang/lib/Semantics/resolve-names.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9957,7 +9957,8 @@ void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) {
99579957
std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(x.u) ||
99589958
std::holds_alternative<parser::CompilerDirective::NoVector>(x.u) ||
99599959
std::holds_alternative<parser::CompilerDirective::NoUnroll>(x.u) ||
9960-
std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(x.u)) {
9960+
std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(x.u) ||
9961+
std::holds_alternative<parser::CompilerDirective::IVDep>(x.u)) {
99619962
return;
99629963
}
99639964
if (const auto *tkr{

flang/test/Integration/ivdep.f90

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
! RUN: %flang_fc1 -emit-llvm -o - %s | FileCheck %s
2+
3+
! CHECK-LABEL: ivdep
4+
subroutine ivdep
5+
integer :: a(10)
6+
!dir$ ivdep
7+
! CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}
8+
! CHECK-NOT: !llvm.loop
9+
! CHECK: br label {{.*}}, !llvm.loop ![[ANNOTATION:.*]]
10+
do i=1,10
11+
a(i)=i
12+
end do
13+
end subroutine ivdep
14+
15+
! CHECK: ![[ANNOTATION]] = distinct !{![[ANNOTATION]], ![[IVDEP:.*]]}
16+
! CHECK: ![[IVDEP]] = !{!"llvm.loop.vectorize.ivdep.enable", i1 true}

flang/test/Lower/ivdep.f90

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck %s
2+
3+
! CHECK: #loop_vectorize = #llvm.loop_vectorize<ivdepEnable = true>
4+
! CHECK: #loop_annotation = #llvm.loop_annotation<vectorize = #loop_vectorize>
5+
6+
! CHECK-LABEL: @_QPivdep
7+
subroutine ivdep
8+
integer :: a(10)
9+
!dir$ ivdep
10+
!CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation}
11+
do i=1,10
12+
a(i)=i
13+
end do
14+
end subroutine ivdep
15+
16+
17+
! CHECK-LABEL: @_QPintermediate_directive
18+
subroutine intermediate_directive
19+
integer :: a(10)
20+
!dir$ ivdep
21+
!dir$ unknown
22+
!CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation}
23+
do i=1,10
24+
a(i)=i
25+
end do
26+
end subroutine intermediate_directive

0 commit comments

Comments
 (0)