[flang-commits] [flang] [llvm] [Flang] Adding lowering for the allocation and deallocation of coarrays (PR #182110)
via flang-commits
flang-commits at lists.llvm.org
Wed Feb 18 11:48:01 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Jean-Didier PAILLEUX (JDPailleux)
<details>
<summary>Changes</summary>
This PR add support of coarray allocation and deallocation in Flang and adds two new operations to MIF:
- `mif::AllocaCoarrayOp` : Allocates a coarray using `prif_allocate_coarray` PRIF procedure.
- `mif::DeallocaCoarrayOp` : Deallocates a coarray using `prif_deallocate_coarray` PRIF procedure
However, allocation for coarrays with ALLOCATABLE and/or POINTER components is not yet supported because PRIF has procedures (`prif_(de)allocate`) for this. This will be added in a future PR.
Another PR which add support of some basic intrinsics with a coarray as an argument will follow after this one.
---
Patch is 164.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/182110.diff
22 Files Affected:
- (modified) flang-rt/lib/runtime/CMakeLists.txt (+1)
- (added) flang-rt/lib/runtime/coarray.cpp (+38)
- (modified) flang/include/flang/Lower/MultiImageFortran.h (+19)
- (added) flang/include/flang/Optimizer/Builder/MIFCommon.h (+26)
- (modified) flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td (+56)
- (modified) flang/include/flang/Optimizer/Transforms/MIFOpConversion.h (+3-1)
- (added) flang/include/flang/Runtime/coarray.h (+24)
- (modified) flang/lib/Lower/Allocatable.cpp (+54-8)
- (modified) flang/lib/Lower/ConvertVariable.cpp (+31)
- (modified) flang/lib/Lower/MultiImageFortran.cpp (+130)
- (modified) flang/lib/Optimizer/Builder/CMakeLists.txt (+1)
- (added) flang/lib/Optimizer/Builder/MIFCommon.cpp (+63)
- (modified) flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt (+1)
- (modified) flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp (+63)
- (modified) flang/lib/Optimizer/Transforms/MIFOpConversion.cpp (+387-11)
- (modified) flang/test/Fir/MIF/change_team.mlir (+28-26)
- (added) flang/test/Fir/MIF/coarray-alloc.mlir (+157)
- (modified) flang/test/Fir/MIF/form_team.mlir (+33-30)
- (modified) flang/test/Fir/MIF/get_team.mlir (+51-49)
- (modified) flang/test/Fir/MIF/sync_team.mlir (+28-26)
- (modified) flang/test/Fir/MIF/team_number.mlir (+19-17)
- (added) flang/test/Lower/MIF/coarray_allocation.f90 (+63)
``````````diff
diff --git a/flang-rt/lib/runtime/CMakeLists.txt b/flang-rt/lib/runtime/CMakeLists.txt
index 787d0dbbfb5ca..ea1e671aaf5b7 100644
--- a/flang-rt/lib/runtime/CMakeLists.txt
+++ b/flang-rt/lib/runtime/CMakeLists.txt
@@ -23,6 +23,7 @@ set(supported_sources
assign.cpp
buffer.cpp
character.cpp
+ coarray.cpp
connection.cpp
copy.cpp
derived-api.cpp
diff --git a/flang-rt/lib/runtime/coarray.cpp b/flang-rt/lib/runtime/coarray.cpp
new file mode 100644
index 0000000000000..11589efc16b72
--- /dev/null
+++ b/flang-rt/lib/runtime/coarray.cpp
@@ -0,0 +1,38 @@
+//===-- runtime/coarray.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/Runtime/coarray.h"
+#include "flang-rt/runtime/descriptor.h"
+#include "flang-rt/runtime/type-info.h"
+
+namespace Fortran::runtime {
+
+extern "C" {
+RT_EXT_API_GROUP_BEGIN
+
+void RTDEF(ComputeLastUcobound)(
+ int num_images, const Descriptor &lcobounds, const Descriptor &ucobounds) {
+ int corank = ucobounds.GetDimension(0).Extent();
+ int64_t *lcobounds_ptr = (int64_t *)lcobounds.raw().base_addr;
+ int64_t *ucobounds_ptr = (int64_t *)ucobounds.raw().base_addr;
+ int64_t index = 1;
+ for (int i = 0; i < corank - 1; i++) {
+ index *= ucobounds_ptr[i] - lcobounds_ptr[i] + 1;
+ }
+ if (corank == 1)
+ ucobounds_ptr[0] = num_images - lcobounds_ptr[0] + 1;
+ else if (index < num_images)
+ ucobounds_ptr[corank - 1] =
+ (num_images / index) + (num_images % index != 0);
+ else
+ ucobounds_ptr[corank - 1] = lcobounds_ptr[corank - 1];
+}
+
+RT_EXT_API_GROUP_END
+}
+} // namespace Fortran::runtime
diff --git a/flang/include/flang/Lower/MultiImageFortran.h b/flang/include/flang/Lower/MultiImageFortran.h
index 82d415a219ae9..f029133c046cd 100644
--- a/flang/include/flang/Lower/MultiImageFortran.h
+++ b/flang/include/flang/Lower/MultiImageFortran.h
@@ -59,6 +59,25 @@ void genEndChangeTeamStmt(AbstractConverter &, pft::Evaluation &eval,
void genFormTeamStatement(AbstractConverter &, pft::Evaluation &eval,
const parser::FormTeamStmt &);
+//===----------------------------------------------------------------------===//
+// COARRAY utils
+//===----------------------------------------------------------------------===//
+
+mlir::DenseI64ArrayAttr genLowerCoBounds(AbstractConverter &converter,
+ mlir::Location loc,
+ const semantics::Symbol &sym);
+
+mlir::DenseI64ArrayAttr genUpperCoBounds(AbstractConverter &converter,
+ mlir::Location loc,
+ const semantics::Symbol &sym);
+
+mlir::Value genAllocateCoarray(
+ AbstractConverter &converter, mlir::Location loc,
+ const semantics::Symbol &sym, mlir::Value addr,
+ const std::optional<Fortran::parser::AllocateCoarraySpec> &allocSpec =
+ std::nullopt,
+ mlir::Value errMsg = {}, bool hasStat = false);
+
//===----------------------------------------------------------------------===//
// COARRAY expressions
//===----------------------------------------------------------------------===//
diff --git a/flang/include/flang/Optimizer/Builder/MIFCommon.h b/flang/include/flang/Optimizer/Builder/MIFCommon.h
new file mode 100644
index 0000000000000..6339c3255d5d8
--- /dev/null
+++ b/flang/include/flang/Optimizer/Builder/MIFCommon.h
@@ -0,0 +1,26 @@
+//===-- MIFCommon.h -------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_TRANSFORMS_MIFCOMMON_H_
+#define FORTRAN_OPTIMIZER_TRANSFORMS_MIFCOMMON_H_
+
+#include "flang/Lower/AbstractConverter.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
+#include "flang/Runtime/coarray.h"
+#include "mlir/IR/BuiltinOps.h"
+
+static constexpr llvm::StringRef coarrayHandleSuffix = "_coarray_handle";
+
+namespace mif {
+
+std::string getFullUniqName(mlir::Value addr);
+
+} // namespace mif
+
+#endif // FORTRAN_OPTIMIZER_TRANSFORMS_MIFCOMMON_H_
diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
index 0d95123b0f9e5..5a432c04361d6 100644
--- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
+++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
@@ -17,6 +17,7 @@
include "flang/Optimizer/Dialect/MIF/MIFDialect.td"
include "flang/Optimizer/Dialect/FIRTypes.td"
include "flang/Optimizer/Dialect/FIRAttr.td"
+include "mlir/IR/BuiltinAttributes.td"
class mif_Op<string mnemonic, list<Trait> traits>
: Op<MIFDialect, mnemonic, traits>;
@@ -425,4 +426,59 @@ def mif_TeamNumberOp : mif_Op<"team_number", []> {
}];
}
+//===----------------------------------------------------------------------===//
+// Allocation and Deallocation
+//===----------------------------------------------------------------------===//
+
+def mif_AllocCoarrayOp
+ : mif_Op<"alloc_coarray", [AttrSizedOperandSegments,
+ MemoryEffects<[MemAlloc<DefaultResource>]>]> {
+ let summary = "Perform the allocation of a coarray and provide a "
+ "corresponding coarray descriptor";
+
+ let description = [{
+ This operation allocates a coarray and provides the corresponding
+ coarray descriptor. This call is collective over the current team.
+ }];
+
+ let arguments = (ins StrAttr:$uniq_name,
+ Arg<fir_ReferenceType, "", [MemRead, MemWrite]>:$box,
+ DenseI64ArrayAttr:$lcobounds, DenseI64ArrayAttr:$ucobounds,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let builders = [OpBuilder<(ins "mlir::Value":$box, "llvm::StringRef":$symName,
+ "mlir::DenseI64ArrayAttr":$lcobounds,
+ "mlir::DenseI64ArrayAttr":$ucobounds, "mlir::Value":$stat,
+ "mlir::Value":$errmsg)>,
+ OpBuilder<(ins "mlir::Value":$box, "llvm::StringRef":$symName,
+ "mlir::DenseI64ArrayAttr":$lcobounds,
+ "mlir::DenseI64ArrayAttr":$ucobounds)>];
+
+ let hasVerifier = 1;
+ let assemblyFormat = [{
+ $box
+ (`stat` $stat^ )?
+ (`errmsg` $errmsg^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
+def mif_DeallocCoarrayOp
+ : mif_Op<"dealloc_coarray", [AttrSizedOperandSegments,
+ MemoryEffects<[MemFree<DefaultResource>]>]> {
+ let summary = "Perform the deallocation of a coarray";
+ let description = [{
+ This call releases memory allocated by `mif_AllocCoarrayOp` for a coarray.
+ }];
+ let arguments = (ins Arg<fir_ReferenceType, "", [MemFree]>:$coarray,
+ Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
+ Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
+
+ let assemblyFormat = [{
+ $coarray (`stat` $stat^ )? (`errmsg` $errmsg^ )?
+ attr-dict `:` functional-type(operands, results)
+ }];
+}
+
#endif // FORTRAN_DIALECT_MIF_MIF_OPS
diff --git a/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h b/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
index 93c724748102c..6b9e71496e847 100644
--- a/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
+++ b/flang/include/flang/Optimizer/Transforms/MIFOpConversion.h
@@ -20,7 +20,9 @@ class LLVMTypeConverter;
namespace mif {
/// Patterns that convert MIF operations to runtime calls.
-void populateMIFOpConversionPatterns(mlir::RewritePatternSet &patterns);
+void populateMIFOpConversionPatterns(const fir::LLVMTypeConverter &converter,
+ mlir::DataLayout &dl,
+ mlir::RewritePatternSet &patterns);
} // namespace mif
diff --git a/flang/include/flang/Runtime/coarray.h b/flang/include/flang/Runtime/coarray.h
new file mode 100644
index 0000000000000..4519179489147
--- /dev/null
+++ b/flang/include/flang/Runtime/coarray.h
@@ -0,0 +1,24 @@
+//===-- include/flang/Runtime/coarray.h --------------------------*- C++-*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_RUNTIME_COARRAY_H
+#define FORTRAN_RUNTIME_COARRAY_H
+
+#include "flang/Runtime/descriptor-consts.h"
+#include "flang/Runtime/entry-names.h"
+
+namespace Fortran::runtime {
+// class Descriptor;
+extern "C" {
+
+void RTDECL(ComputeLastUcobound)(
+ int num_images, const Descriptor &lcobounds, const Descriptor &ucobounds);
+}
+} // namespace Fortran::runtime
+
+#endif // FORTRAN_RUNTIME_COARRAY_H
diff --git a/flang/lib/Lower/Allocatable.cpp b/flang/lib/Lower/Allocatable.cpp
index 1912027f8742d..839a54c651e23 100644
--- a/flang/lib/Lower/Allocatable.cpp
+++ b/flang/lib/Lower/Allocatable.cpp
@@ -18,6 +18,7 @@
#include "flang/Lower/ConvertVariable.h"
#include "flang/Lower/IterationSpace.h"
#include "flang/Lower/Mangler.h"
+#include "flang/Lower/MultiImageFortran.h"
#include "flang/Lower/OpenACC.h"
#include "flang/Lower/PFTBuilder.h"
#include "flang/Lower/Runtime.h"
@@ -29,6 +30,7 @@
#include "flang/Optimizer/Dialect/CUF/CUFOps.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/Support/FatalError.h"
#include "flang/Optimizer/Support/InternalNames.h"
@@ -325,11 +327,12 @@ class AllocateStmtHelper {
struct Allocation {
const Fortran::parser::Allocation &alloc;
const Fortran::semantics::DeclTypeSpec &type;
- bool hasCoarraySpec() const {
+ const std::optional<Fortran::parser::AllocateCoarraySpec> &
+ getCoarraySpec() const {
return std::get<std::optional<Fortran::parser::AllocateCoarraySpec>>(
- alloc.t)
- .has_value();
+ alloc.t);
}
+ bool hasCoarraySpec() const { return getCoarraySpec().has_value(); }
const Fortran::parser::AllocateObject &getAllocObj() const {
return std::get<Fortran::parser::AllocateObject>(alloc.t);
}
@@ -478,6 +481,29 @@ class AllocateStmtHelper {
!box.isPointer();
unsigned allocatorIdx = Fortran::lower::getAllocatorIdx(alloc.getSymbol());
+ const Fortran::lower::SomeExpr *expr =
+ Fortran::semantics::GetExpr(alloc.getAllocObj());
+ std::optional<Fortran::evaluate::DataRef> dataRef =
+ !expr ? std::nullopt : Fortran::evaluate::ExtractDataRef(expr);
+ bool isCoarrayAllocate = alloc.hasCoarraySpec();
+
+ if (isCoarrayAllocate) {
+ errorManager.genStatCheck(builder, loc);
+ genAllocateObjectInit(box, allocatorIdx);
+ Fortran::lower::StatementContext stmtCtx;
+ genSetType(alloc, box, loc);
+ genSetDeferredLengthParameters(alloc, box);
+ genAllocateObjectBounds(alloc, box);
+ mlir::Value stat;
+ stat = Fortran::lower::genAllocateCoarray(
+ converter, loc, alloc.getSymbol(), box.getAddr(),
+ alloc.getCoarraySpec(), errorManager.errMsgAddr);
+ fir::factory::syncMutableBoxFromIRBox(builder, loc, box);
+ postAllocationAction(alloc, box);
+ errorManager.assignStat(builder, loc, stat);
+ return;
+ }
+
if (inlineAllocation &&
((isCudaAllocate && isCudaDeviceContext) || !isCudaAllocate)) {
// Pointers must use PointerAllocate so that their deallocations
@@ -501,8 +527,6 @@ class AllocateStmtHelper {
// Generate a sequence of runtime calls.
errorManager.genStatCheck(builder, loc);
genAllocateObjectInit(box, allocatorIdx);
- if (alloc.hasCoarraySpec())
- TODO(loc, "coarray: allocation of a coarray object");
if (alloc.type.IsPolymorphic())
genSetType(alloc, box, loc);
genSetDeferredLengthParameters(alloc, box);
@@ -884,13 +908,32 @@ genDeallocate(fir::FirOpBuilder &builder,
Fortran::lower::AbstractConverter &converter, mlir::Location loc,
const fir::MutableBoxValue &box, ErrorManager &errorManager,
mlir::Value declaredTypeDesc = {},
- const Fortran::semantics::Symbol *symbol = nullptr) {
+ const Fortran::semantics::Symbol *symbol = nullptr,
+ const Fortran::lower::SomeExpr *allocExpr = nullptr) {
bool isCudaSymbol = symbol && Fortran::semantics::HasCUDAAttr(*symbol);
bool isCudaDeviceContext = cuf::isCUDADeviceContext(builder.getRegion());
bool inlineDeallocation =
!box.isDerived() && !box.isPolymorphic() && !box.hasAssumedRank() &&
!box.isUnlimitedPolymorphic() && !errorManager.hasStatSpec() &&
!useAllocateRuntime && !box.isPointer();
+
+ std::optional<Fortran::evaluate::DataRef> dataRef =
+ !allocExpr ? std::nullopt : Fortran::evaluate::ExtractDataRef(allocExpr);
+ bool isCoarraySymbol = symbol && Fortran::evaluate::IsCoarray(*symbol);
+
+ // Deallocate coarray
+ if (isCoarraySymbol) {
+ mlir::Value ret = builder.createTemporary(loc, builder.getI32Type());
+ mif::DeallocCoarrayOp::create(builder, loc, box.getAddr(), ret,
+ errorManager.errMsgAddr);
+ ret = fir::LoadOp::create(builder, loc, ret);
+ fir::factory::syncMutableBoxFromIRBox(builder, loc, box);
+ if (symbol)
+ postDeallocationAction(converter, builder, *symbol);
+ errorManager.assignStat(builder, loc, ret);
+ return ret;
+ }
+
// Deallocate intrinsic types inline.
if (inlineDeallocation &&
((isCudaSymbol && isCudaDeviceContext) || !isCudaSymbol)) {
@@ -975,6 +1018,8 @@ void Fortran::lower::genDeallocateStmt(
for (const Fortran::parser::AllocateObject &allocateObject :
std::get<std::list<Fortran::parser::AllocateObject>>(stmt.t)) {
const Fortran::semantics::Symbol &symbol = unwrapSymbol(allocateObject);
+ const Fortran::lower::SomeExpr *allocExpr =
+ Fortran::semantics::GetExpr(allocateObject);
fir::MutableBoxValue box =
genMutableBoxValue(converter, loc, allocateObject);
mlir::Value declaredTypeDesc = {};
@@ -987,8 +1032,9 @@ void Fortran::lower::genDeallocateStmt(
Fortran::lower::getTypeDescAddr(converter, loc, *derivedTypeSpec);
}
}
- mlir::Value beginOpValue = genDeallocate(
- builder, converter, loc, box, errorManager, declaredTypeDesc, &symbol);
+ mlir::Value beginOpValue =
+ genDeallocate(builder, converter, loc, box, errorManager,
+ declaredTypeDesc, &symbol, allocExpr);
preDeallocationAction(converter, builder, beginOpValue, symbol);
}
builder.restoreInsertionPoint(insertPt);
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 0ededb364bfea..2e308324d09ae 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -21,6 +21,7 @@
#include "flang/Lower/ConvertExprToHLFIR.h"
#include "flang/Lower/ConvertProcedureDesignator.h"
#include "flang/Lower/Mangler.h"
+#include "flang/Lower/MultiImageFortran.h"
#include "flang/Lower/PFTBuilder.h"
#include "flang/Lower/StatementContext.h"
#include "flang/Lower/Support/Utils.h"
@@ -36,6 +37,7 @@
#include "flang/Optimizer/Dialect/FIRAttr.h"
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/Support/FatalError.h"
@@ -1132,6 +1134,23 @@ static void instantiateLocal(Fortran::lower::AbstractConverter &converter,
});
}
}
+ if (Fortran::evaluate::IsCoarray(var.getSymbol()) &&
+ !Fortran::semantics::IsAllocatableOrPointer(var.getSymbol()) &&
+ !Fortran::semantics::IsDummy(var.getSymbol())) {
+ mlir::Location loc = converter.getCurrentLocation();
+ fir::ExtendedValue exv =
+ converter.getSymbolExtendedValue(var.getSymbol(), &symMap);
+ auto *sym = &var.getSymbol();
+ const Fortran::semantics::Scope &owner = sym->owner();
+ if (owner.kind() != Fortran::semantics::Scope::Kind::MainProgram) {
+ auto *converterPtr = &converter;
+ converter.getFctCtx().attachCleanup([converterPtr, builder, loc, exv]() {
+ mif::DeallocCoarrayOp::create(*builder, loc, fir::getBase(exv),
+ /*stat*/ mlir::Value{},
+ /*errmsg*/ mlir::Value{});
+ });
+ }
+ }
if (std::optional<VariableCleanUp> cleanup =
needDeallocationOrFinalization(var)) {
auto *builder = &converter.getFirOpBuilder();
@@ -2186,6 +2205,11 @@ void Fortran::lower::mapSymbolAttributes(
}
if (isDummy) {
+ if (Fortran::evaluate::IsCoarray(sym))
+ // Operation in MIF dialect to create an alias of the coarray not
+ // yet supported (by using the procedure provided by PRIF).
+ TODO(loc, "coarray dummy argument not yet supported.");
+
mlir::Value dummyArg = symMap.lookupSymbol(sym).getAddr();
if (lowerToBoxValue(sym, dummyArg, converter)) {
llvm::SmallVector<mlir::Value> lbounds;
@@ -2480,6 +2504,13 @@ void Fortran::lower::mapSymbolAttributes(
}
}
+ if (Fortran::evaluate::IsCoarray(sym)) {
+ Fortran::lower::genAllocateCoarray(converter, loc, sym, addr);
+ ::genDeclareSymbol(converter, symMap, sym, addr, len, extents, lbounds,
+ replace);
+ return;
+ }
+
// Allocate or extract raw address for the entity
if (!addr) {
if (arg) {
diff --git a/flang/lib/Lower/MultiImageFortran.cpp b/flang/lib/Lower/MultiImageFortran.cpp
index 4f5b6a500d24f..a498a10f3e74b 100644
--- a/flang/lib/Lower/MultiImageFortran.cpp
+++ b/flang/lib/Lower/MultiImageFortran.cpp
@@ -15,6 +15,7 @@
#include "flang/Lower/AbstractConverter.h"
#include "flang/Lower/SymbolMap.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/MIFCommon.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/expression.h"
@@ -257,6 +258,135 @@ void Fortran::lower::genFormTeamStatement(
errMsgAddr);
}
+//===----------------------------------------------------------------------===//
+// COARRAY utils
+//===----------------------------------------------------------------------===//
+
+mlir::DenseI64ArrayAttr
+Fortran::lower::genLowerCoBounds(Fortran::lower::AbstractConverter &converter,
+ mlir::Location loc,
+ const Fortran::semantics::Symbol &sym) {
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ mlir::DenseI64ArrayAttr lcobounds;
+
+ if (Fortran::semantics::IsAllocatableOrObjectPointer(&sym))
+ return {};
+ if (const auto *object =
+ sym.GetUltimate()
+ .detailsIf<Fortran::semantics::ObjectEntityDetails>()) {
+ llvm::SmallVector<std::int64_t> lcbs;
+ for (const Fortran::semantics::ShapeSpec &cobounds : object->coshape()) {
+ if (auto lb = cobounds.lbound().GetExplicit()) {
+ if (auto constant = Fortran::evaluate::ToInt64(*lb))
+ lcbs.push_back(*constant);
+ else
+ lcbs.push_back(1); // default lcobounds
+ }
+ }
+ lcobounds = mlir::DenseI64ArrayAttr::get(builder.getContext(), lcbs);
+ }
+ return lcobounds;
+}
+
+mlir::DenseI64ArrayAttr
+Fortran::lower::genUpperCoBounds(Fortran::lower::AbstractConverter &converter,
+ mlir::Location loc,
+ const Fortran::semantics::Symbol &sym) {
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder(...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/182110
More information about the flang-commits
mailing list