Skip to content

Commit db84c08

Browse files
committed
Fix n2f.f90.
Rewrite filter. Add another raiseBaseType method.
1 parent 23d1a17 commit db84c08

File tree

3 files changed

+74
-28
lines changed

3 files changed

+74
-28
lines changed

flang/include/flang/Lower/ConvertExpr.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ createSomeExtendedAddress(mlir::Location loc, AbstractConverter &converter,
6060
/// Create the address of the box.
6161
/// \p expr must be the designator of an allocatable/pointer entity.
6262
fir::MutableBoxValue
63-
createSomeMutableBox(mlir::Location loc, AbstractConverter &converter,
64-
const evaluate::Expr<evaluate::SomeType> &expr,
65-
SymMap &symMap);
63+
createMutableBox(mlir::Location loc, AbstractConverter &converter,
64+
const evaluate::Expr<evaluate::SomeType> &expr,
65+
SymMap &symMap);
6666

6767
/// Lower an array assignment expression.
6868
///
@@ -138,7 +138,8 @@ void createAnyMaskedArrayAssignment(
138138
/// it is not allocated yet or reallocation it if it does not conform
139139
/// with the right hand side.
140140
void createAllocatableArrayAssignment(
141-
AbstractConverter &converter, const fir::MutableBoxValue &lhs,
141+
AbstractConverter &converter,
142+
const evaluate::Expr<evaluate::SomeType> &lhs,
142143
const evaluate::Expr<evaluate::SomeType> &rhs,
143144
ExplicitIterSpace &explicitIterSpace, ImplicitIterSpace &implicitIterSpace,
144145
SymMap &symMap, StatementContext &stmtCtx);

flang/lib/Lower/Bridge.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
315315
fir::MutableBoxValue
316316
genExprMutableBox(mlir::Location loc,
317317
const Fortran::lower::SomeExpr &expr) override final {
318-
return createSomeMutableBox(loc, *this, expr, localSymbols);
318+
return createMutableBox(loc, *this, expr, localSymbols);
319319
}
320320
fir::ExtendedValue genExprBox(const Fortran::lower::SomeExpr &expr,
321321
Fortran::lower::StatementContext &context,
@@ -1703,9 +1703,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
17031703
if (isWholeAllocatable(assign.lhs)) {
17041704
// Assignment to allocatables may require the lhs to be
17051705
// deallocated/reallocated. See Fortran 2018 10.2.1.3 p3
1706-
auto lhs = genExprMutableBox(toLocation(), assign.lhs);
17071706
Fortran::lower::createAllocatableArrayAssignment(
1708-
*this, lhs, assign.rhs, explicitIterSpace, implicitIterSpace,
1707+
*this, assign.lhs, assign.rhs, explicitIterSpace, implicitIterSpace,
17091708
localSymbols, stmtCtx);
17101709
return;
17111710
}

flang/lib/Lower/ConvertExpr.cpp

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,6 +2404,19 @@ class ArrayExprLowering {
24042404
return result;
24052405
}
24062406

2407+
/// In an explicit space, the context may include an implicit subspace. The
2408+
/// RHS of the assignment does not necessarily have rank and can be promoted
2409+
/// from a scalar to an array. In that case, the implicit subscripts must be
2410+
/// removed.
2411+
void removeImplicit() {
2412+
llvm::SmallVector<AccessValue> newIndices;
2413+
const auto size = indices.size();
2414+
for (std::remove_const_t<decltype(size)> i = 0, j = 0; j < size; ++j)
2415+
if (indices[j].access() != AccessKind::Implicit)
2416+
newIndices[i++] = indices[j];
2417+
indices.swap(newIndices);
2418+
}
2419+
24072420
private:
24082421
mlir::Value inArg;
24092422
mlir::Value outRes;
@@ -2480,8 +2493,10 @@ class ArrayExprLowering {
24802493
auto lambda = [=](IterSpace iters) -> ExtValue {
24812494
auto innerArg = iters.innerArgument();
24822495
auto resTy = adjustedArrayElementType(innerArg.getType());
2496+
auto cast = builder.createConvert(loc, fir::unwrapSequenceType(resTy),
2497+
iters.getElement());
24832498
auto arrUpdate = builder.create<fir::ArrayUpdateOp>(
2484-
loc, resTy, innerArg, iters.getElement(), iters.iterVec(),
2499+
loc, resTy, innerArg, cast, iters.iterVec(),
24852500
destination.typeparams());
24862501
return abstractArrayExtValue(arrUpdate);
24872502
};
@@ -2530,7 +2545,7 @@ class ArrayExprLowering {
25302545
static void lowerAllocatableArrayAssignment(
25312546
Fortran::lower::AbstractConverter &converter,
25322547
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx,
2533-
const fir::MutableBoxValue &lhs,
2548+
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &lhs,
25342549
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &rhs,
25352550
Fortran::lower::ExplicitIterSpace &explicitSpace,
25362551
Fortran::lower::ImplicitIterSpace &implicitSpace) {
@@ -2546,11 +2561,15 @@ class ArrayExprLowering {
25462561
/// defines the iteration space of the computation and the lhs is
25472562
/// resized/reallocated to fit if necessary.
25482563
void lowerAllocatableArrayAssignment(
2549-
const fir::MutableBoxValue &mutableBox,
2564+
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &lhs,
25502565
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &rhs) {
25512566
// With assignment to allocatable, we want to lower the rhs first and use
25522567
// its shape to determine if we need to reallocate, etc.
25532568
auto loc = getLoc();
2569+
// FIXME: If the lhs is in an explicit iteration space, the assignment may
2570+
// be to an array of allocatable arrays rather than a single allocatable
2571+
// array.
2572+
auto mutableBox = createMutableBox(loc, converter, lhs, symMap);
25542573
auto resultTy = converter.genType(rhs);
25552574
auto rhsCC = [&]() {
25562575
PushSemantics(ConstituentSemantics::RefTransparent);
@@ -2738,8 +2757,11 @@ class ArrayExprLowering {
27382757
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &exp) {
27392758
auto resTy = explicitSpace ? destination->getResult(0).getType()
27402759
: converter.genType(exp);
2760+
bool explicitScalar = explicitSpace && exp.Rank() == 0;
27412761
return std::visit(
2742-
[&](const auto &e) { return lowerArrayExpression(genarr(e), resTy); },
2762+
[&](const auto &e) {
2763+
return lowerArrayExpression(genarr(e), resTy, explicitScalar);
2764+
},
27432765
exp.u);
27442766
}
27452767
ExtValue lowerArrayExpression(const ExtValue &exv) {
@@ -2766,11 +2788,15 @@ class ArrayExprLowering {
27662788
/// Otherwise, \p resultTy is ignored and the expression is evaluated
27672789
/// in the destination. \p f is a continuation built from an
27682790
/// evaluate::Expr or an ExtendedValue.
2769-
ExtValue lowerArrayExpression(CC f, mlir::Type resultTy) {
2791+
ExtValue lowerArrayExpression(CC f, mlir::Type resultTy,
2792+
bool explicitScalar = false) {
27702793
auto loc = getLoc();
27712794
auto [iterSpace, insPt] = genIterSpace(resultTy);
2795+
auto rhsIterSpace = iterSpace;
2796+
if (explicitScalar)
2797+
rhsIterSpace.removeImplicit();
27722798
auto innerArg = iterSpace.innerArgument();
2773-
auto exv = f(iterSpace);
2799+
auto exv = f(rhsIterSpace);
27742800
mlir::Value upd;
27752801
if (ccDest.hasValue()) {
27762802
auto element = fir::getBase(exv);
@@ -3212,17 +3238,21 @@ class ArrayExprLowering {
32123238
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &e) {
32133239
struct Filter : public Fortran::evaluate::AnyTraverse<
32143240
Filter, std::optional<llvm::SmallVector<mlir::Value>>> {
3215-
using Base = Fortran::evaluate::AnyTraverse<
3216-
Filter, std::optional<llvm::SmallVector<mlir::Value>>>;
3241+
using RT = std::optional<llvm::SmallVector<mlir::Value>>;
3242+
using Base = Fortran::evaluate::AnyTraverse<Filter, RT>;
32173243
using Base::operator();
32183244

3219-
Filter(const llvm::SmallVector<mlir::Value> init)
3220-
: Base(*this), bounds(init) {}
3245+
Filter(ArrayExprLowering *const ael) : Base(*this), ael(ael) {}
32213246

3222-
std::optional<llvm::SmallVector<mlir::Value>>
3223-
operator()(const Fortran::evaluate::ArrayRef &ref) {
3247+
RT operator()(const Fortran::evaluate::ArrayRef &ref) {
32243248
if ((ref.base().IsSymbol() || ref.base().Rank() == 0) &&
32253249
ref.Rank() > 0 && !ref.subscript().empty()) {
3250+
auto baseTy = ael->raiseBaseType(ref.base());
3251+
auto ty = ref.base().IsSymbol()
3252+
? baseTy
3253+
: baseTy.cast<fir::RecordType>().getType(
3254+
toStringRef(ref.GetLastSymbol().name()));
3255+
auto bounds = ael->getShape(ty);
32263256
assert(ref.subscript().size() == bounds.size());
32273257
llvm::SmallVector<mlir::Value> result;
32283258
auto bdIter = bounds.begin();
@@ -3242,15 +3272,24 @@ class ArrayExprLowering {
32423272
}
32433273
return {};
32443274
}
3275+
RT operator()(const Fortran::evaluate::Component &cpnt) {
3276+
if (cpnt.base().Rank() == 0 && cpnt.Rank() > 0)
3277+
return ael->getShape(ael->raiseBaseType(cpnt));
3278+
return {};
3279+
}
3280+
RT operator()(const Fortran::semantics::Symbol &sym) {
3281+
if (sym.Rank() > 0)
3282+
return ael->getShape(ael->raiseBaseType(sym));
3283+
return {};
3284+
}
32453285

3246-
llvm::SmallVector<mlir::Value> bounds;
3286+
ArrayExprLowering *const ael;
32473287
};
32483288

3249-
auto originalShape = getShape(converter.genType(e));
3250-
Filter filter(originalShape);
3289+
Filter filter(this);
32513290
if (auto res = filter(e))
32523291
return *res;
3253-
return originalShape;
3292+
return {};
32543293
}
32553294

32563295
void genMasks() {
@@ -4308,6 +4347,10 @@ class ArrayExprLowering {
43084347
return false;
43094348
}
43104349

4350+
/// Set of helper member functions for generating the type of a particular
4351+
/// component along a path. We cannot use the `converter` here because it is
4352+
/// not possible to uplift an arbitrary component list to a generic
4353+
/// `Fortran::evaluate::Expr`.
43114354
mlir::Type raiseBaseType(const Fortran::evaluate::Component &x) {
43124355
auto baseTy = raiseBaseType(x.base());
43134356
auto recTy = baseTy.cast<fir::RecordType>();
@@ -4320,10 +4363,13 @@ class ArrayExprLowering {
43204363
LLVM_DEBUG(llvm::dbgs() << "base type s " << rv << '\n');
43214364
return rv;
43224365
}
4366+
mlir::Type raiseBaseType(const Fortran::evaluate::NamedEntity &n) {
4367+
return n.IsSymbol() ? raiseBaseType(n.GetLastSymbol())
4368+
: raiseBaseType(n.GetComponent());
4369+
}
43234370
mlir::Type raiseBaseType(const Fortran::evaluate::ArrayRef &x) {
43244371
auto &base = x.base();
4325-
mlir::Type baseTy = base.IsSymbol() ? raiseBaseType(base.GetLastSymbol())
4326-
: raiseBaseType(base.GetComponent());
4372+
mlir::Type baseTy = raiseBaseType(base);
43274373
auto seqTy = baseTy.cast<fir::SequenceType>();
43284374
auto rv = seqTy.getEleTy();
43294375
LLVM_DEBUG(llvm::dbgs() << "base type a " << rv << '\n');
@@ -5700,12 +5746,12 @@ void Fortran::lower::createAnyMaskedArrayAssignment(
57005746

57015747
void Fortran::lower::createAllocatableArrayAssignment(
57025748
Fortran::lower::AbstractConverter &converter,
5703-
const fir::MutableBoxValue &lhs,
5749+
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &lhs,
57045750
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &rhs,
57055751
Fortran::lower::ExplicitIterSpace &explicitSpace,
57065752
Fortran::lower::ImplicitIterSpace &implicitSpace,
57075753
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx) {
5708-
LLVM_DEBUG(llvm::dbgs() << "defining array: " << lhs << '\n';
5754+
LLVM_DEBUG(lhs.AsFortran(llvm::dbgs() << "defining array: ") << '\n';
57095755
rhs.AsFortran(llvm::dbgs() << "assign expression: ")
57105756
<< " given the explicit iteration space:\n"
57115757
<< explicitSpace << "\n and implied mask conditions:\n"
@@ -5733,7 +5779,7 @@ fir::ExtendedValue Fortran::lower::createSomeArrayBox(
57335779
stmtCtx, expr);
57345780
}
57355781

5736-
fir::MutableBoxValue Fortran::lower::createSomeMutableBox(
5782+
fir::MutableBoxValue Fortran::lower::createMutableBox(
57375783
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
57385784
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &expr,
57395785
Fortran::lower::SymMap &symMap) {

0 commit comments

Comments
 (0)