[Mlir-commits] [flang] [mlir] [Flang][OpenACC] add loop annotations to acc.loop (PR #216769)
Scott Manley
llvmlistbot at llvm.org
Tue Aug 18 04:33:36 PDT 2026
================
@@ -0,0 +1,156 @@
+//===-- Lower/Support/LoopAnnotation.cpp ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Lower/Support/LoopAnnotation.h"
+#include "flang/Common/idioms.h"
+#include "flang/Parser/parse-tree.h"
+#include "mlir/IR/BuiltinAttributes.h"
+
+static mlir::LLVM::LoopUnrollAttr
+genLoopUnrollAttr(mlir::MLIRContext *context,
+ std::optional<std::uint64_t> directiveArg) {
+ mlir::BoolAttr falseAttr = mlir::BoolAttr::get(context, false);
+ mlir::BoolAttr trueAttr = mlir::BoolAttr::get(context, true);
+ mlir::IntegerAttr countAttr;
+ mlir::BoolAttr fullUnrollAttr;
+ bool shouldUnroll = true;
+ if (directiveArg.has_value()) {
+ auto unrollingFactor = directiveArg.value();
+ if (unrollingFactor == 0 || unrollingFactor == 1) {
+ shouldUnroll = false;
+ } else {
+ countAttr = mlir::IntegerAttr::get(mlir::IntegerType::get(context, 64),
+ unrollingFactor);
+ }
+ } else {
+ fullUnrollAttr = trueAttr;
+ }
+
+ mlir::BoolAttr disableAttr = shouldUnroll ? falseAttr : trueAttr;
+ return mlir::LLVM::LoopUnrollAttr::get(context, /*disable=*/disableAttr,
+ /*count=*/countAttr, {},
+ /*full=*/fullUnrollAttr, {}, {}, {});
+}
+
+static mlir::LLVM::LoopUnrollAndJamAttr
+genLoopUnrollAndJamAttr(mlir::MLIRContext *context,
+ std::optional<std::uint64_t> count) {
+ mlir::BoolAttr falseAttr = mlir::BoolAttr::get(context, false);
+ mlir::BoolAttr trueAttr = mlir::BoolAttr::get(context, true);
+ mlir::IntegerAttr countAttr;
+ bool shouldUnroll = true;
+ if (count.has_value()) {
+ auto unrollingFactor = count.value();
+ if (unrollingFactor == 0 || unrollingFactor == 1) {
+ shouldUnroll = false;
+ } else {
+ countAttr = mlir::IntegerAttr::get(mlir::IntegerType::get(context, 64),
+ unrollingFactor);
+ }
+ }
+
+ mlir::BoolAttr disableAttr = shouldUnroll ? falseAttr : trueAttr;
+ return mlir::LLVM::LoopUnrollAndJamAttr::get(context, /*disable=*/disableAttr,
+ /*count*/ countAttr, {}, {}, {},
+ {}, {});
+}
+
+static mlir::LLVM::LoopVectorizeAttr
+genLoopVectorizeAttr(mlir::MLIRContext *context, mlir::BoolAttr disableAttr,
+ mlir::BoolAttr scalableEnable,
+ mlir::IntegerAttr vectorWidth) {
+ mlir::LLVM::LoopVectorizeAttr va;
+ if (disableAttr)
+ va = mlir::LLVM::LoopVectorizeAttr::get(context,
+ /*disable=*/disableAttr,
+ /*predicate=*/{},
+ /*scalableEnable=*/scalableEnable,
+ /*vectorWidth=*/vectorWidth, {}, {},
+ {});
+ return va;
+}
+
+mlir::LLVM::LoopAnnotationAttr Fortran::lower::genLoopAnnotationAttr(
+ mlir::MLIRContext *context,
+ llvm::ArrayRef<const Fortran::parser::CompilerDirective *> dirs) {
+ mlir::BoolAttr disableVecAttr;
+ mlir::BoolAttr scalableEnable;
+ mlir::IntegerAttr vectorWidth;
+ mlir::LLVM::LoopUnrollAttr ua;
+ mlir::LLVM::LoopUnrollAndJamAttr uja;
+ llvm::SmallVector<mlir::LLVM::AccessGroupAttr> aga;
+ bool hasAttrs = false;
+ for (const auto *dir : dirs) {
+ Fortran::common::visit(
+ Fortran::common::visitors{
+ [&](const Fortran::parser::CompilerDirective::VectorAlways &) {
+ disableVecAttr = mlir::BoolAttr::get(context, false);
+ hasAttrs = true;
+ },
+ [&](const Fortran::parser::CompilerDirective::VectorLength &vl) {
+ using Kind =
+ Fortran::parser::CompilerDirective::VectorLength::Kind;
+ Kind kind = std::get<Kind>(vl.t);
+ uint64_t length = std::get<uint64_t>(vl.t);
+ disableVecAttr = mlir::BoolAttr::get(context, false);
+ if (length != 0)
+ vectorWidth = mlir::IntegerAttr::get(
+ mlir::IntegerType::get(context, 64), length);
+ switch (kind) {
+ case Kind::Scalable:
+ scalableEnable = mlir::BoolAttr::get(context, true);
+ break;
+ case Kind::Fixed:
+ scalableEnable = mlir::BoolAttr::get(context, false);
+ break;
+ case Kind::Auto:
+ break;
+ }
+ hasAttrs = true;
+ },
+ [&](const Fortran::parser::CompilerDirective::Unroll &u) {
+ ua = genLoopUnrollAttr(context, u.v);
+ hasAttrs = true;
+ },
+ [&](const Fortran::parser::CompilerDirective::UnrollAndJam &u) {
+ uja = genLoopUnrollAndJamAttr(context, u.v);
+ hasAttrs = true;
+ },
+ [&](const Fortran::parser::CompilerDirective::NoVector &) {
+ disableVecAttr = mlir::BoolAttr::get(context, true);
+ hasAttrs = true;
+ },
+ [&](const Fortran::parser::CompilerDirective::NoUnroll &) {
+ ua = genLoopUnrollAttr(context, /*directiveArg=*/0);
+ hasAttrs = true;
+ },
+ [&](const Fortran::parser::CompilerDirective::NoUnrollAndJam &) {
+ uja = genLoopUnrollAndJamAttr(context, /*count=*/0);
+ hasAttrs = true;
+ },
+ [&](const Fortran::parser::CompilerDirective::IVDep &) {
----------------
rscottmanley wrote:
Yes, I had this same thought. ivdep on acc loop is a separate PR
https://github.com/llvm/llvm-project/pull/216769
More information about the Mlir-commits
mailing list