diff --git a/flang/docs/Directives.md b/flang/docs/Directives.md index f356f762b13a2..dc6db1a044dcd 100644 --- a/flang/docs/Directives.md +++ b/flang/docs/Directives.md @@ -39,6 +39,8 @@ A list of non-standard directives supported by Flang * `!dir$ vector always` forces vectorization on the following loop regardless of cost model decisions. The loop must still be vectorizable. [This directive currently only works on plain do loops without labels]. +* `!dir$ ivdep` tells vectorization to ignore the dependency analysis of the + following loop. # Directive Details diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 37c3370b48a08..2e026e6427a6b 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -203,6 +203,7 @@ class ParseTreeDumper { NODE(parser, CompilerDirective) NODE(CompilerDirective, AssumeAligned) NODE(CompilerDirective, IgnoreTKR) + NODE(CompilerDirective, IgnoreVectorDep) NODE(CompilerDirective, LoopCount) NODE(CompilerDirective, NameValue) NODE(CompilerDirective, Unrecognized) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 548fcc81984b2..660cd49224301 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3342,10 +3342,12 @@ struct CompilerDirective { TUPLE_CLASS_BOILERPLATE(NameValue); std::tuple> t; }; + EMPTY_CLASS(IgnoreVectorDep); EMPTY_CLASS(Unrecognized); CharBlock source; - std::variant, LoopCount, std::list, - VectorAlways, std::list, Unrecognized> + std::variant, IgnoreVectorDep, LoopCount, + std::list, VectorAlways, std::list, + Unrecognized> u; }; diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp index 0bdc4c4e033c7..91f8a4c984135 100644 --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -1266,12 +1266,15 @@ TYPE_PARSER(construct("STAT =" >> statVariable) || // Directives, extensions, and deprecated statements // !DIR$ IGNORE_TKR [ [(tkrdmac...)] name ]... // !DIR$ LOOP COUNT (n1[, n2]...) +// !DIR$ IVDEP // !DIR$ name[=value] [, name[=value]]... // !DIR$ constexpr auto ignore_tkr{ "IGNORE_TKR" >> optionalList(construct( maybe(parenthesized(many(letter))), name))}; -constexpr auto loopCount{ +constexpr auto ignoreVectorDep{ + "IVDEP" >> construct()}; +const constexpr auto loopCount{ "LOOP COUNT" >> construct( parenthesized(nonemptyList(digitString64)))}; constexpr auto assumeAligned{"ASSUME_ALIGNED" >> @@ -1283,6 +1286,7 @@ TYPE_PARSER(beginDirective >> "DIR$ "_tok >> sourced((construct(ignore_tkr) || construct(loopCount) || construct(assumeAligned) || + construct(ignoreVectorDep) || construct(vectorAlways) || construct( many(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 2511a5dda9d09..74b9101f8a160 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -1826,6 +1826,9 @@ class UnparseVisitor { Word("!DIR$ IGNORE_TKR"); // emitted even if tkr list is empty Walk(" ", tkr, ", "); }, + [&](const CompilerDirective::IgnoreVectorDep &) { + Word("!DIR$ IVDEP"); + }, [&](const CompilerDirective::LoopCount &lcount) { Walk("!DIR$ LOOP COUNT (", lcount.v, ", ", ")"); }, diff --git a/flang/test/Parser/compiler-directives.f90 b/flang/test/Parser/compiler-directives.f90 index 246eaf985251c..3eac51b6df6d2 100644 --- a/flang/test/Parser/compiler-directives.f90 +++ b/flang/test/Parser/compiler-directives.f90 @@ -35,3 +35,10 @@ subroutine vector_always do i=1,10 enddo end subroutine + +subroutine ignore_vector_dep + !dir$ ivdep + ! CHECK: !DIR$ IVDEP + do i=1,10 + enddo +end subroutine