Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ class ParseTreeDumper {
NODE(parser, CompilerDirective)
NODE(CompilerDirective, AssumeAligned)
NODE(CompilerDirective, IgnoreTKR)
NODE(CompilerDirective, IVDep)
NODE(CompilerDirective, LoopCount)
NODE(CompilerDirective, NameValue)
NODE(CompilerDirective, Unrecognized)
Expand Down
4 changes: 3 additions & 1 deletion flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3354,6 +3354,7 @@ struct StmtFunctionStmt {
// !DIR$ NOVECTOR
// !DIR$ NOUNROLL
// !DIR$ NOUNROLL_AND_JAM
// !DIR$ IVDEP
// !DIR$ <anything else>
struct CompilerDirective {
UNION_CLASS_BOILERPLATE(CompilerDirective);
Expand Down Expand Up @@ -3382,11 +3383,12 @@ struct CompilerDirective {
EMPTY_CLASS(NoVector);
EMPTY_CLASS(NoUnroll);
EMPTY_CLASS(NoUnrollAndJam);
EMPTY_CLASS(IVDep);
EMPTY_CLASS(Unrecognized);
CharBlock source;
std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>,
VectorAlways, std::list<NameValue>, Unroll, UnrollAndJam, Unrecognized,
NoVector, NoUnroll, NoUnrollAndJam>
NoVector, NoUnroll, NoUnrollAndJam, IVDep>
u;
};

Expand Down
37 changes: 27 additions & 10 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2428,22 +2428,33 @@ class FirConverter : public Fortran::lower::AbstractConverter {
{}, {}, {}, {});
}

// Enabling loop vectorization attribute.
mlir::LLVM::LoopVectorizeAttr
genLoopVectorizeAttr(mlir::BoolAttr disableAttr,
mlir::BoolAttr ivdepEnableAttr) {
mlir::LLVM::LoopVectorizeAttr va;
if (disableAttr || ivdepEnableAttr)
va = mlir::LLVM::LoopVectorizeAttr::get(builder->getContext(),
/*disable=*/disableAttr, {}, {},
/*ivdepEnable*/ ivdepEnableAttr,
{}, {}, {}, {});
return va;
}

void addLoopAnnotationAttr(
IncrementLoopInfo &info,
llvm::SmallVectorImpl<const Fortran::parser::CompilerDirective *> &dirs) {
mlir::LLVM::LoopVectorizeAttr va;
mlir::BoolAttr disableVecAttr, ivdepEnableAttr;
mlir::LLVM::LoopUnrollAttr ua;
mlir::LLVM::LoopUnrollAndJamAttr uja;
llvm::SmallVector<mlir::LLVM::AccessGroupAttr> aga;
bool has_attrs = false;
for (const auto *dir : dirs) {
Fortran::common::visit(
Fortran::common::visitors{
[&](const Fortran::parser::CompilerDirective::VectorAlways &) {
mlir::BoolAttr falseAttr =
disableVecAttr =
mlir::BoolAttr::get(builder->getContext(), false);
va = mlir::LLVM::LoopVectorizeAttr::get(builder->getContext(),
/*disable=*/falseAttr,
{}, {}, {}, {}, {}, {});
has_attrs = true;
},
[&](const Fortran::parser::CompilerDirective::Unroll &u) {
Expand All @@ -2455,11 +2466,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
has_attrs = true;
},
[&](const Fortran::parser::CompilerDirective::NoVector &u) {
mlir::BoolAttr trueAttr =
disableVecAttr =
mlir::BoolAttr::get(builder->getContext(), true);
va = mlir::LLVM::LoopVectorizeAttr::get(builder->getContext(),
/*disable=*/trueAttr,
{}, {}, {}, {}, {}, {});
has_attrs = true;
},
[&](const Fortran::parser::CompilerDirective::NoUnroll &u) {
Expand All @@ -2470,10 +2478,16 @@ class FirConverter : public Fortran::lower::AbstractConverter {
uja = genLoopUnrollAndJamAttr(/*unrollingFactor=*/0);
has_attrs = true;
},

[&](const Fortran::parser::CompilerDirective::IVDep &iv) {
ivdepEnableAttr =
mlir::BoolAttr::get(builder->getContext(), true);
has_attrs = true;
},
[&](const auto &) {}},
dir->u);
}
mlir::LLVM::LoopVectorizeAttr va =
genLoopVectorizeAttr(disableVecAttr, ivdepEnableAttr);
mlir::LLVM::LoopAnnotationAttr la = mlir::LLVM::LoopAnnotationAttr::get(
builder->getContext(), {}, /*vectorize=*/va, {}, /*unroll*/ ua,
/*unroll_and_jam*/ uja, {}, {}, {}, {}, {}, {}, {}, {}, {}, {});
Expand Down Expand Up @@ -3178,6 +3192,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
[&](const Fortran::parser::CompilerDirective::NoUnrollAndJam &) {
attachDirectiveToLoop(dir, &eval);
},
[&](const Fortran::parser::CompilerDirective::IVDep &) {
attachDirectiveToLoop(dir, &eval);
},
[&](const auto &) {}},
dir.u);
}
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Optimizer/Builder/HLFIRTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ hlfir::LoopNest hlfir::genLoopNest(mlir::Location loc,
if (!couldVectorize) {
mlir::LLVM::LoopVectorizeAttr va{mlir::LLVM::LoopVectorizeAttr::get(
builder.getContext(),
/*disable=*/builder.getBoolAttr(true), {}, {}, {}, {}, {}, {})};
/*disable=*/builder.getBoolAttr(true), {}, {}, {}, {}, {}, {}, {})};
mlir::LLVM::LoopAnnotationAttr la = mlir::LLVM::LoopAnnotationAttr::get(
builder.getContext(), {}, /*vectorize=*/va, {}, /*unroll*/ {},
/*unroll_and_jam*/ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {});
Expand Down
3 changes: 3 additions & 0 deletions flang/lib/Parser/Fortran-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,7 @@ TYPE_PARSER(construct<StatOrErrmsg>("STAT =" >> statVariable) ||
// !DIR$ LOOP COUNT (n1[, n2]...)
// !DIR$ name[=value] [, name[=value]]...
// !DIR$ UNROLL [n]
// !DIR$ IVDEP
// !DIR$ <anything else>
constexpr auto ignore_tkr{
"IGNORE_TKR" >> optionalList(construct<CompilerDirective::IgnoreTKR>(
Expand All @@ -1314,6 +1315,7 @@ constexpr auto novector{"NOVECTOR" >> construct<CompilerDirective::NoVector>()};
constexpr auto nounroll{"NOUNROLL" >> construct<CompilerDirective::NoUnroll>()};
constexpr auto nounrollAndJam{
"NOUNROLL_AND_JAM" >> construct<CompilerDirective::NoUnrollAndJam>()};
constexpr auto ivdep{"IVDEP" >> construct<CompilerDirective::IVDep>()};
TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
sourced((construct<CompilerDirective>(ignore_tkr) ||
construct<CompilerDirective>(loopCount) ||
Expand All @@ -1324,6 +1326,7 @@ TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
construct<CompilerDirective>(novector) ||
construct<CompilerDirective>(nounrollAndJam) ||
construct<CompilerDirective>(nounroll) ||
construct<CompilerDirective>(ivdep) ||
construct<CompilerDirective>(
many(construct<CompilerDirective::NameValue>(
name, maybe(("="_tok || ":"_tok) >> digitString64))))) /
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1867,6 +1867,7 @@ class UnparseVisitor {
[&](const CompilerDirective::NoUnrollAndJam &) {
Word("!DIR$ NOUNROLL_AND_JAM");
},
[&](const CompilerDirective::IVDep &) { Word("!DIR$ IVDEP"); },
[&](const CompilerDirective::Unrecognized &) {
Word("!DIR$ ");
Word(x.source.ToString());
Expand Down
7 changes: 6 additions & 1 deletion flang/lib/Semantics/canonicalize-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ static bool IsExecutionDirective(const parser::CompilerDirective &dir) {
std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(dir.u) ||
std::holds_alternative<parser::CompilerDirective::NoVector>(dir.u) ||
std::holds_alternative<parser::CompilerDirective::NoUnroll>(dir.u) ||
std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(dir.u);
std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(
dir.u) ||
std::holds_alternative<parser::CompilerDirective::IVDep>(dir.u);
}

void CanonicalizationOfDirectives::Post(parser::SpecificationPart &spec) {
Expand Down Expand Up @@ -131,6 +133,9 @@ void CanonicalizationOfDirectives::Post(parser::Block &block) {
[&](parser::CompilerDirective::NoUnrollAndJam &) {
CheckLoopDirective(*dir, block, it);
},
[&](parser::CompilerDirective::IVDep &) {
CheckLoopDirective(*dir, block, it);
},
[&](auto &) {}},
dir->u);
}
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9957,7 +9957,8 @@ void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) {
std::holds_alternative<parser::CompilerDirective::UnrollAndJam>(x.u) ||
std::holds_alternative<parser::CompilerDirective::NoVector>(x.u) ||
std::holds_alternative<parser::CompilerDirective::NoUnroll>(x.u) ||
std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(x.u)) {
std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(x.u) ||
std::holds_alternative<parser::CompilerDirective::IVDep>(x.u)) {
return;
}
if (const auto *tkr{
Expand Down
16 changes: 16 additions & 0 deletions flang/test/Integration/ivdep.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
! RUN: %flang_fc1 -emit-llvm -o - %s | FileCheck %s

! CHECK-LABEL: ivdep
subroutine ivdep
integer :: a(10)
!dir$ ivdep
! CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}
! CHECK-NOT: !llvm.loop
! CHECK: br label {{.*}}, !llvm.loop ![[ANNOTATION:.*]]
do i=1,10
a(i)=i
end do
end subroutine ivdep

! CHECK: ![[ANNOTATION]] = distinct !{![[ANNOTATION]], ![[IVDEP:.*]]}
! CHECK: ![[IVDEP]] = !{!"llvm.loop.vectorize.ivdep.enable", i1 true}
26 changes: 26 additions & 0 deletions flang/test/Lower/ivdep.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck %s

! CHECK: #loop_vectorize = #llvm.loop_vectorize<ivdepEnable = true>
! CHECK: #loop_annotation = #llvm.loop_annotation<vectorize = #loop_vectorize>

! CHECK-LABEL: @_QPivdep
subroutine ivdep
integer :: a(10)
!dir$ ivdep
!CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation}
do i=1,10
a(i)=i
end do
end subroutine ivdep


! CHECK-LABEL: @_QPintermediate_directive
subroutine intermediate_directive
integer :: a(10)
!dir$ ivdep
!dir$ unknown
!CHECK: fir.do_loop {{.*}} attributes {loopAnnotation = #loop_annotation}
do i=1,10
a(i)=i
end do
end subroutine intermediate_directive
7 changes: 7 additions & 0 deletions flang/test/Parser/compiler-directives.f90
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,10 @@ subroutine no_vector
do i=1,10
enddo
end subroutine

subroutine ivdep
!dir$ ivdep
! CHECK: !DIR$ IVDEP
do i=1,10
enddo
end subroutine
17 changes: 8 additions & 9 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,14 @@ def LoopVectorizeAttr : LLVM_Attr<"LoopVectorize", "loop_vectorize"> {
the "!llvm.loop.vectorize" metadata.
}];

let parameters = (ins
OptionalParameter<"BoolAttr">:$disable,
OptionalParameter<"BoolAttr">:$predicateEnable,
OptionalParameter<"BoolAttr">:$scalableEnable,
OptionalParameter<"IntegerAttr">:$width,
OptionalParameter<"LoopAnnotationAttr">:$followupVectorized,
OptionalParameter<"LoopAnnotationAttr">:$followupEpilogue,
OptionalParameter<"LoopAnnotationAttr">:$followupAll
);
let parameters = (ins OptionalParameter<"BoolAttr">:$disable,
OptionalParameter<"BoolAttr">:$predicateEnable,
OptionalParameter<"BoolAttr">:$scalableEnable,
OptionalParameter<"BoolAttr">:$ivdepEnable,
OptionalParameter<"IntegerAttr">:$width,
OptionalParameter<"LoopAnnotationAttr">:$followupVectorized,
OptionalParameter<"LoopAnnotationAttr">:$followupEpilogue,
OptionalParameter<"LoopAnnotationAttr">:$followupAll);

let assemblyFormat = "`<` struct(params) `>`";

Expand Down
8 changes: 5 additions & 3 deletions mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ FailureOr<LoopVectorizeAttr> LoopMetadataConversion::convertVectorizeAttr() {
lookupBoolNode("llvm.loop.vectorize.predicate.enable");
FailureOr<BoolAttr> scalableEnable =
lookupBoolNode("llvm.loop.vectorize.scalable.enable");
FailureOr<BoolAttr> ivdepEnable =
lookupBoolNode("llvm.loop.vectorize.ivdep.enable");
FailureOr<IntegerAttr> width = lookupIntNode("llvm.loop.vectorize.width");
FailureOr<LoopAnnotationAttr> followupVec =
lookupFollowupNode("llvm.loop.vectorize.followup_vectorized");
Expand All @@ -299,9 +301,9 @@ FailureOr<LoopVectorizeAttr> LoopMetadataConversion::convertVectorizeAttr() {
FailureOr<LoopAnnotationAttr> followupAll =
lookupFollowupNode("llvm.loop.vectorize.followup_all");

return createIfNonNull<LoopVectorizeAttr>(ctx, enable, predicateEnable,
scalableEnable, width, followupVec,
followupEpi, followupAll);
return createIfNonNull<LoopVectorizeAttr>(
ctx, enable, predicateEnable, scalableEnable, ivdepEnable, width,
followupVec, followupEpi, followupAll);
}

FailureOr<LoopInterleaveAttr> LoopMetadataConversion::convertInterleaveAttr() {
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ void LoopAnnotationConversion::convertLoopOptions(LoopVectorizeAttr options) {
options.getPredicateEnable());
convertBoolNode("llvm.loop.vectorize.scalable.enable",
options.getScalableEnable());
convertBoolNode("llvm.loop.vectorize.ivdep.enable", options.getIvdepEnable());
convertI32Node("llvm.loop.vectorize.width", options.getWidth());
convertFollowupNode("llvm.loop.vectorize.followup_vectorized",
options.getFollowupVectorized());
Expand Down
19 changes: 10 additions & 9 deletions mlir/test/Target/LLVMIR/Import/metadata-loop.ll
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ end:
; // -----

; CHECK-DAG: #[[FOLLOWUP:.*]] = #llvm.loop_annotation<disableNonforced = true>
; CHECK-DAG: #[[VECTORIZE_ATTR:.*]] = #llvm.loop_vectorize<disable = false, predicateEnable = true, scalableEnable = false, width = 16 : i32, followupVectorized = #[[FOLLOWUP]], followupEpilogue = #[[FOLLOWUP]], followupAll = #[[FOLLOWUP]]>
; CHECK-DAG: #[[VECTORIZE_ATTR:.*]] = #llvm.loop_vectorize<disable = false, predicateEnable = true, scalableEnable = false, ivdepEnable = false, width = 16 : i32, followupVectorized = #[[FOLLOWUP]], followupEpilogue = #[[FOLLOWUP]], followupAll = #[[FOLLOWUP]]>
; CHECK-DAG: #[[$ANNOT_ATTR:.*]] = #llvm.loop_annotation<vectorize = #[[VECTORIZE_ATTR]]>

; CHECK-LABEL: @vectorize
Expand All @@ -85,17 +85,18 @@ end:
ret void
}

!1 = distinct !{!1, !2, !3, !4, !5, !6, !7, !8}
!1 = distinct !{!1, !2, !3, !4, !5, !6, !7, !8, !9}
!2 = !{!"llvm.loop.vectorize.enable", i1 1}
!3 = !{!"llvm.loop.vectorize.predicate.enable", i1 1}
!4 = !{!"llvm.loop.vectorize.scalable.enable", i1 0}
!5 = !{!"llvm.loop.vectorize.width", i32 16}
!6 = !{!"llvm.loop.vectorize.followup_vectorized", !9}
!7 = !{!"llvm.loop.vectorize.followup_epilogue", !9}
!8 = !{!"llvm.loop.vectorize.followup_all", !9}

!9 = distinct !{!9, !10}
!10 = !{!"llvm.loop.disable_nonforced"}
!5 = !{!"llvm.loop.vectorize.ivdep.enable", i1 0}
!6 = !{!"llvm.loop.vectorize.width", i32 16}
!7 = !{!"llvm.loop.vectorize.followup_vectorized", !10}
!8 = !{!"llvm.loop.vectorize.followup_epilogue", !10}
!9 = !{!"llvm.loop.vectorize.followup_all", !10}

!10 = distinct !{!10, !11}
!11 = !{!"llvm.loop.disable_nonforced"}

; // -----

Expand Down
5 changes: 3 additions & 2 deletions mlir/test/Target/LLVMIR/loop-metadata.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ llvm.func @isvectorized() {
llvm.func @vectorizeOptions() {
// CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<vectorize = <
disable = false, predicateEnable = true, scalableEnable = false, width = 16 : i32,
disable = false, predicateEnable = true, scalableEnable = false, ivdepEnable = false, width = 16 : i32,
followupVectorized = #followup, followupEpilogue = #followup, followupAll = #followup>
>}
^bb1:
Expand All @@ -54,10 +54,11 @@ llvm.func @vectorizeOptions() {

// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"}
// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]}
// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.scalable.enable", i1 false}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.ivdep.enable", i1 false}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.width", i32 16}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_vectorized", ![[FOLLOWUP]]}
// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_epilogue", ![[FOLLOWUP]]}
Expand Down