[flang] [llvm] [Flang] Adding lowering for the allocation and deallocation of coarrays (PR #182110)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 3 06:55:13 PST 2026
================
@@ -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();
+ mlir::DenseI64ArrayAttr ucobounds;
+
+ if (Fortran::semantics::IsAllocatableOrObjectPointer(&sym))
+ return {};
+ if (const auto *object =
+ sym.GetUltimate()
+ .detailsIf<Fortran::semantics::ObjectEntityDetails>()) {
+ llvm::SmallVector<std::int64_t> ucbs;
+ for (const Fortran::semantics::ShapeSpec &cobounds : object->coshape()) {
+ if (cobounds.ubound().isStar()) {
+ ucbs.push_back(-1);
+ } else if (auto ub = cobounds.ubound().GetExplicit()) {
+ if (auto constant = Fortran::evaluate::ToInt64(*ub))
+ ucbs.push_back(*constant);
+ else {
+ if (auto lb = cobounds.lbound().GetExplicit()) {
+ if (auto constant2 = Fortran::evaluate::ToInt64(*lb))
+ ucbs.push_back(*constant2);
+ else
+ ucbs.push_back(1); // use lcobound as default value
+ }
+ }
+ }
+ }
+ ucobounds = mlir::DenseI64ArrayAttr::get(builder.getContext(), ucbs);
+ }
+ return ucobounds;
+}
+
+static std::tuple<mlir::DenseI64ArrayAttr, mlir::DenseI64ArrayAttr>
+genCoBoundsAttrs(Fortran::lower::AbstractConverter &converter,
+ mlir::Location loc,
+ const Fortran::parser::AllocateCoarraySpec &allocSpec) {
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ llvm::SmallVector<std::int64_t> lcbs, ucbs;
+
+ const std::list<Fortran::parser::AllocateCoshapeSpec> &coshapeSpecs =
+ std::get<0>(allocSpec.t);
+ for (const Fortran::parser::AllocateCoshapeSpec &coshapeSpec : coshapeSpecs) {
+ std::int64_t lb;
+ if (const std::optional<Fortran::parser::BoundExpr> &lbExpr =
+ std::get<0>(coshapeSpec.t))
+ lb = *Fortran::evaluate::ToInt64(Fortran::semantics::GetExpr(*lbExpr));
+ else
+ lb = 1;
+ lcbs.push_back(lb);
+ ucbs.push_back(*Fortran::evaluate::ToInt64(
+ Fortran::semantics::GetExpr(std::get<1>(coshapeSpec.t))));
----------------
jeanPerier wrote:
I do not think cobounds in allocate statement have to be constant expressions:
```
subroutine test()
real, allocatable :: co[:, :]
integer :: n
n = 100
allocate(co[n,*])
end
```
`evaluate::ToInt64` is only extracting constants. You will need to evaluate them.
https://github.com/llvm/llvm-project/pull/182110
More information about the llvm-commits
mailing list