[flang-commits] [flang] [flang][acc] Implement cache directive lowering (PR #174897)
Valentin Clement バレンタイン クレメン via flang-commits
flang-commits at lists.llvm.org
Thu Jan 8 10:19:05 PST 2026
================
@@ -4837,12 +4837,180 @@ genACC(Fortran::lower::AbstractConverter &converter,
atomicConstruct.u);
}
+/// Generate acc.bounds for cache directive. Handles:
+/// - Single element: arr(i) or arr(5)
+/// - Full range: arr(lower:upper)
+/// - Missing upper: arr(lower:) - uses array's upper bound
+/// - Missing lower: arr(:upper) - uses array's lower bound
+static void
+genCacheBounds(Fortran::lower::AbstractConverter &converter,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
+ const Fortran::parser::AccObject &accObject,
+ std::stringstream &asFortran,
+ llvm::SmallVectorImpl<mlir::Value> &bounds) {
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ mlir::Location loc = converter.getCurrentLocation();
+ mlir::Type idxTy = builder.getIndexType();
+ mlir::Type boundTy = builder.getType<mlir::acc::DataBoundsType>();
+
+ Fortran::evaluate::ExpressionAnalyzer ea{semanticsContext};
+ Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject);
+
+ std::optional<Fortran::evaluate::DataRef> dataRef;
+ Fortran::semantics::MaybeExpr designator = Fortran::common::visit(
+ [&](auto &&s) { return ea.Analyze(s); }, accObject.u);
+ if (designator)
+ dataRef = Fortran::evaluate::ExtractDataRef(*designator);
+
+ if (!dataRef)
+ return;
+
+ auto *arrayRef = std::get_if<Fortran::evaluate::ArrayRef>(&dataRef->u);
+ if (!arrayRef)
+ return;
+
+ // Helper to generate index value from expression.
+ // Optimize for compile-time constants to generate index type directly.
+ auto genIndex =
+ [&](const Fortran::semantics::MaybeExpr &expr) -> mlir::Value {
+ if (auto constVal = Fortran::evaluate::ToInt64(*expr))
+ return builder.createIntegerConstant(loc, idxTy, *constVal);
+ return builder.createConvert(
+ loc, idxTy, fir::getBase(converter.genExprValue(loc, *expr, stmtCtx)));
+ };
+
+ const auto &subscripts = arrayRef->subscript();
+ int dimension = 0;
+ mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
+ fir::ExtendedValue dataExv = converter.getSymbolExtendedValue(symbol);
+
+ for (const auto &subscript : subscripts) {
+ if (dimension != 0)
+ asFortran << ',';
+
+ mlir::Value lbound, extent;
+ mlir::Value arrayLb =
+ fir::factory::readLowerBound(builder, loc, dataExv, dimension, one);
+ mlir::Value arrayExtent =
+ fir::factory::readExtent(builder, loc, dataExv, dimension);
+
+ const auto *triplet = std::get_if<Fortran::evaluate::Triplet>(&subscript.u);
+
+ if (triplet) {
+ asFortran << ':';
+
+ // OpenACC spec requires at least one of lower or upper bound to be
+ // specified: arr(lower:upper), arr(lower:), or arr(:upper).
+ // arr(:) with both bounds missing is not allowed.
+ Fortran::semantics::MaybeExpr lowerExpr =
+ Fortran::evaluate::AsGenericExpr(triplet->lower());
+ Fortran::semantics::MaybeExpr upperExpr =
+ Fortran::evaluate::AsGenericExpr(triplet->upper());
+
+ if (!lowerExpr && !upperExpr) {
+ llvm::report_fatal_error("OpenACC cache directive requires at least "
+ "one bound to be specified for array section");
+ }
+
+ // OpenACC cache only supports unit stride (default or explicit 1).
+ auto strideVal = Fortran::evaluate::ToInt64(triplet->stride());
+ if (!strideVal || *strideVal != 1) {
+ llvm::report_fatal_error("OpenACC cache directive does not support "
+ "strided array sections");
+ }
+
+ // Compute lower bound (use array lb if not specified).
+ mlir::Value lb = lowerExpr ? genIndex(lowerExpr) : arrayLb;
+
+ // Compute upper bound (use array ub if not specified).
+ mlir::Value ub;
+ if (upperExpr) {
+ ub = genIndex(upperExpr);
+ } else {
+ // arr(lower:) - upper is array's upper bound
+ ub = mlir::arith::AddIOp::create(
+ builder, loc,
+ mlir::arith::SubIOp::create(builder, loc, arrayLb, one),
+ arrayExtent);
+ }
----------------
clementval wrote:
no braces
https://github.com/llvm/llvm-project/pull/174897
More information about the flang-commits
mailing list