diff options
Diffstat (limited to 'flang')
| -rw-r--r-- | flang/docs/Directives.md | 3 | ||||
| -rw-r--r-- | flang/include/flang/Parser/dump-parse-tree.h | 1 | ||||
| -rw-r--r-- | flang/include/flang/Parser/parse-tree.h | 8 | ||||
| -rw-r--r-- | flang/lib/Lower/Bridge.cpp | 3 | ||||
| -rw-r--r-- | flang/lib/Parser/Fortran-parsers.cpp | 4 | ||||
| -rw-r--r-- | flang/lib/Parser/unparse.cpp | 4 | ||||
| -rw-r--r-- | flang/lib/Semantics/resolve-names.cpp | 1 | ||||
| -rw-r--r-- | flang/test/Parser/prefetch.f90 | 80 |
8 files changed, 103 insertions, 1 deletions
diff --git a/flang/docs/Directives.md b/flang/docs/Directives.md index 2f16a8d..d157b5d3 100644 --- a/flang/docs/Directives.md +++ b/flang/docs/Directives.md @@ -52,6 +52,9 @@ A list of non-standard directives supported by Flang integer that specifying the unrolling factor. When `N` is `0` or `1`, the loop should not be unrolled at all. If `N` is omitted the optimizer will selects the number of times to unroll the loop. +* `!dir$ prefetch designator[, designator]...`, where the designator list can be + a variable or an array reference. This directive is used to insert a hint to + the code generator to prefetch instructions for memory references. * `!dir$ novector` disabling vectorization on the following loop. * `!dir$ nounroll` disabling unrolling on the following loop. * `!dir$ nounroll_and_jam` disabling unrolling and jamming on the following loop. diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index b242402..1c4d2da 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -218,6 +218,7 @@ public: NODE(CompilerDirective, NoVector) NODE(CompilerDirective, NoUnroll) NODE(CompilerDirective, NoUnrollAndJam) + NODE(CompilerDirective, Prefetch) NODE(parser, ComplexLiteralConstant) NODE(parser, ComplexPart) NODE(parser, ComponentArraySpec) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 32e444f..cd9429b 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3360,6 +3360,7 @@ struct StmtFunctionStmt { // !DIR$ NOVECTOR // !DIR$ NOUNROLL // !DIR$ NOUNROLL_AND_JAM +// !DIR$ PREFETCH designator[, designator]... // !DIR$ FORCEINLINE // !DIR$ INLINE // !DIR$ NOINLINE @@ -3388,6 +3389,10 @@ struct CompilerDirective { struct UnrollAndJam { WRAPPER_CLASS_BOILERPLATE(UnrollAndJam, std::optional<std::uint64_t>); }; + struct Prefetch { + WRAPPER_CLASS_BOILERPLATE( + Prefetch, std::list<common::Indirection<Designator>>); + }; EMPTY_CLASS(NoVector); EMPTY_CLASS(NoUnroll); EMPTY_CLASS(NoUnrollAndJam); @@ -3398,7 +3403,8 @@ struct CompilerDirective { CharBlock source; std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>, VectorAlways, std::list<NameValue>, Unroll, UnrollAndJam, Unrecognized, - NoVector, NoUnroll, NoUnrollAndJam, ForceInline, Inline, NoInline> + NoVector, NoUnroll, NoUnrollAndJam, ForceInline, Inline, NoInline, + Prefetch> u; }; diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 0f4b39a..5779bcd 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -3275,6 +3275,9 @@ private: [&](const Fortran::parser::CompilerDirective::NoInline &) { attachInliningDirectiveToStmt(dir, &eval); }, + [&](const Fortran::parser::CompilerDirective::Prefetch &prefetch) { + TODO(getCurrentLocation(), "!$dir prefetch"); + }, [&](const auto &) {}}, dir.u); } diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp index ea6a1ea..cdc9b0a 100644 --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -1297,6 +1297,7 @@ TYPE_PARSER(construct<StatOrErrmsg>("STAT =" >> statVariable) || // !DIR$ LOOP COUNT (n1[, n2]...) // !DIR$ name[=value] [, name[=value]]... // !DIR$ UNROLL [n] +// !DIR$ PREFETCH designator[, designator]... // !DIR$ <anything else> constexpr auto ignore_tkr{ "IGNORE_TKR" >> optionalList(construct<CompilerDirective::IgnoreTKR>( @@ -1311,6 +1312,8 @@ constexpr auto vectorAlways{ "VECTOR ALWAYS" >> construct<CompilerDirective::VectorAlways>()}; constexpr auto unroll{ "UNROLL" >> construct<CompilerDirective::Unroll>(maybe(digitString64))}; +constexpr auto prefetch{"PREFETCH" >> + construct<CompilerDirective::Prefetch>(nonemptyList(indirect(designator)))}; constexpr auto unrollAndJam{"UNROLL_AND_JAM" >> construct<CompilerDirective::UnrollAndJam>(maybe(digitString64))}; constexpr auto novector{"NOVECTOR" >> construct<CompilerDirective::NoVector>()}; @@ -1329,6 +1332,7 @@ TYPE_PARSER(beginDirective >> "DIR$ "_tok >> construct<CompilerDirective>(vectorAlways) || construct<CompilerDirective>(unrollAndJam) || construct<CompilerDirective>(unroll) || + construct<CompilerDirective>(prefetch) || construct<CompilerDirective>(novector) || construct<CompilerDirective>(nounrollAndJam) || construct<CompilerDirective>(nounroll) || diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 6bb14a43..dc0f083 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -1855,6 +1855,10 @@ public: Word("!DIR$ UNROLL"); Walk(" ", unroll.v); }, + [&](const CompilerDirective::Prefetch &prefetch) { + Word("!DIR$ PREFETCH"); + Walk(" ", prefetch.v); + }, [&](const CompilerDirective::UnrollAndJam &unrollAndJam) { Word("!DIR$ UNROLL_AND_JAM"); Walk(" ", unrollAndJam.v); diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index a2062ef..09ec951 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -10065,6 +10065,7 @@ void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) { std::holds_alternative<parser::CompilerDirective::NoUnrollAndJam>(x.u) || std::holds_alternative<parser::CompilerDirective::ForceInline>(x.u) || std::holds_alternative<parser::CompilerDirective::Inline>(x.u) || + std::holds_alternative<parser::CompilerDirective::Prefetch>(x.u) || std::holds_alternative<parser::CompilerDirective::NoInline>(x.u)) { return; } diff --git a/flang/test/Parser/prefetch.f90 b/flang/test/Parser/prefetch.f90 new file mode 100644 index 0000000..1013a09 --- /dev/null +++ b/flang/test/Parser/prefetch.f90 @@ -0,0 +1,80 @@ +!RUN: %flang_fc1 -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s -check-prefix=UNPARSE +!RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s -check-prefix=TREE + +subroutine test_prefetch_01(a, b) + integer, intent(in) :: a + integer, intent(inout) :: b(5) + integer :: i = 2 + integer :: res + +!TREE: | | DeclarationConstruct -> SpecificationConstruct -> CompilerDirective -> Prefetch -> Designator -> DataRef -> Name = 'a' + +!UNPARSE: !DIR$ PREFETCH a + !dir$ prefetch a + b(1) = a + +!TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> CompilerDirective -> Prefetch -> Designator -> DataRef -> Name = 'b' + +!UNPARSE: !DIR$ PREFETCH b + !dir$ prefetch b + res = sum(b) + +!TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> CompilerDirective -> Prefetch -> Designator -> DataRef -> Name = 'a' +!TREE: | | Designator -> DataRef -> ArrayElement +!TREE: | | | DataRef -> Name = 'b' +!TREE: | | | SectionSubscript -> SubscriptTriplet +!TREE: | | | | Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '3' +!TREE: | | | | Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '5' + +!UNPARSE: !DIR$ PREFETCH a, b(3:5) + !dir$ prefetch a, b(3:5) + res = a + b(4) + +!TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> CompilerDirective -> Prefetch -> Designator -> DataRef -> Name = 'res' +!TREE: | | Designator -> DataRef -> ArrayElement +!TREE: | | | DataRef -> Name = 'b' +!TREE: | | | SectionSubscript -> Integer -> Expr -> Add +!TREE: | | | | Expr -> Designator -> DataRef -> Name = 'i' +!TREE: | | | | Expr -> LiteralConstant -> IntLiteralConstant = '2' + +!UNPARSE: !DIR$ PREFETCH res, b(i+2) + !dir$ prefetch res, b(i+2) + res = res + b(i+2) +end subroutine + +subroutine test_prefetch_02(n, a) + integer, intent(in) :: n + integer, intent(in) :: a(n) + type :: t + real, allocatable :: x(:, :) + end type t + type(t) :: p + + do i = 1, n +!TREE: | | | | ExecutionPartConstruct -> ExecutableConstruct -> CompilerDirective -> Prefetch -> Designator -> DataRef -> ArrayElement +!TREE: | | | | | DataRef -> StructureComponent +!TREE: | | | | | | DataRef -> Name = 'p' +!TREE: | | | | | | Name = 'x' +!TREE: | | | | | SectionSubscript -> Integer -> Expr -> Designator -> DataRef -> Name = 'i' +!TREE: | | | | | SectionSubscript -> SubscriptTriplet +!TREE: | | | | Designator -> DataRef -> Name = 'a' + +!UNPARSE: !DIR$ PREFETCH p%x(i,:), a + !dir$ prefetch p%x(i, :), a + do j = 1, n +!TREE: | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> CompilerDirective -> Prefetch -> Designator -> DataRef -> ArrayElement +!TREE: | | | | | | | DataRef -> StructureComponent +!TREE: | | | | | | | | DataRef -> Name = 'p' +!TREE: | | | | | | | | Name = 'x' +!TREE: | | | | | | | SectionSubscript -> Integer -> Expr -> Designator -> DataRef -> Name = 'i' +!TREE: | | | | | | | SectionSubscript -> Integer -> Expr -> Designator -> DataRef -> Name = 'j' +!TREE: | | | | | | Designator -> DataRef -> ArrayElement +!TREE: | | | | | | | DataRef -> Name = 'a' +!TREE: | | | | | | | SectionSubscript -> Integer -> Expr -> Designator -> DataRef -> Name = 'i' + +!UNPARSE: !DIR$ PREFETCH p%x(i,j), a(i) + !dir$ prefetch p%x(i, j), a(i) + p%x(i, j) = p%x(i, j) ** a(j) + end do + end do +end subroutine |
