@@ -2411,6 +2411,19 @@ class ArrayExprLowering {
2411
2411
return result;
2412
2412
}
2413
2413
2414
+ // / In an explicit space, the context may include an implicit subspace. The
2415
+ // / RHS of the assignment does not necessarily have rank and can be promoted
2416
+ // / from a scalar to an array. In that case, the implicit subscripts must be
2417
+ // / removed.
2418
+ void removeImplicit () {
2419
+ llvm::SmallVector<AccessValue> newIndices;
2420
+ const auto size = indices.size ();
2421
+ for (std::remove_const_t <decltype (size)> i = 0 , j = 0 ; j < size; ++j)
2422
+ if (indices[j].access () != AccessKind::Implicit)
2423
+ newIndices[i++] = indices[j];
2424
+ indices.swap (newIndices);
2425
+ }
2426
+
2414
2427
private:
2415
2428
mlir::Value inArg;
2416
2429
mlir::Value outRes;
@@ -2487,8 +2500,10 @@ class ArrayExprLowering {
2487
2500
auto lambda = [=](IterSpace iters) -> ExtValue {
2488
2501
auto innerArg = iters.innerArgument ();
2489
2502
auto resTy = adjustedArrayElementType (innerArg.getType ());
2503
+ auto cast = builder.createConvert (loc, fir::unwrapSequenceType (resTy),
2504
+ iters.getElement ());
2490
2505
auto arrUpdate = builder.create <fir::ArrayUpdateOp>(
2491
- loc, resTy, innerArg, iters. getElement () , iters.iterVec (),
2506
+ loc, resTy, innerArg, cast , iters.iterVec (),
2492
2507
destination.typeparams ());
2493
2508
return abstractArrayExtValue (arrUpdate);
2494
2509
};
@@ -2537,7 +2552,7 @@ class ArrayExprLowering {
2537
2552
static void lowerAllocatableArrayAssignment (
2538
2553
Fortran::lower::AbstractConverter &converter,
2539
2554
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx,
2540
- const fir::MutableBoxValue &lhs,
2555
+ const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &lhs,
2541
2556
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &rhs,
2542
2557
Fortran::lower::ExplicitIterSpace &explicitSpace,
2543
2558
Fortran::lower::ImplicitIterSpace &implicitSpace) {
@@ -2553,11 +2568,15 @@ class ArrayExprLowering {
2553
2568
// / defines the iteration space of the computation and the lhs is
2554
2569
// / resized/reallocated to fit if necessary.
2555
2570
void lowerAllocatableArrayAssignment (
2556
- const fir::MutableBoxValue &mutableBox ,
2571
+ const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &lhs ,
2557
2572
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &rhs) {
2558
2573
// With assignment to allocatable, we want to lower the rhs first and use
2559
2574
// its shape to determine if we need to reallocate, etc.
2560
2575
auto loc = getLoc ();
2576
+ // FIXME: If the lhs is in an explicit iteration space, the assignment may
2577
+ // be to an array of allocatable arrays rather than a single allocatable
2578
+ // array.
2579
+ auto mutableBox = createMutableBox (loc, converter, lhs, symMap);
2561
2580
auto resultTy = converter.genType (rhs);
2562
2581
auto rhsCC = [&]() {
2563
2582
PushSemantics (ConstituentSemantics::RefTransparent);
@@ -2775,6 +2794,10 @@ class ArrayExprLowering {
2775
2794
ExtValue lowerArrayExpression (CC f, mlir::Type resultTy) {
2776
2795
auto loc = getLoc ();
2777
2796
auto [iterSpace, insPt] = genIterSpace (resultTy);
2797
+ #if 0
2798
+ if (explicitScalar)
2799
+ rhsIterSpace.removeImplicit();
2800
+ #endif
2778
2801
auto innerArg = iterSpace.innerArgument ();
2779
2802
auto exv = f (iterSpace);
2780
2803
mlir::Value upd;
@@ -3218,17 +3241,21 @@ class ArrayExprLowering {
3218
3241
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &e) {
3219
3242
struct Filter : public Fortran ::evaluate::AnyTraverse<
3220
3243
Filter, std::optional<llvm::SmallVector<mlir::Value>>> {
3221
- using Base = Fortran::evaluate::AnyTraverse<
3222
- Filter, std::optional<llvm::SmallVector<mlir::Value>> >;
3244
+ using RT = std::optional<llvm::SmallVector<mlir::Value>>;
3245
+ using Base = Fortran::evaluate::AnyTraverse<Filter, RT >;
3223
3246
using Base::operator ();
3224
3247
3225
- Filter (const llvm::SmallVector<mlir::Value> init)
3226
- : Base(*this ), bounds(init) {}
3248
+ Filter (ArrayExprLowering *const ael) : Base(*this ), ael(ael) {}
3227
3249
3228
- std::optional<llvm::SmallVector<mlir::Value>>
3229
- operator ()(const Fortran::evaluate::ArrayRef &ref) {
3250
+ RT operator ()(const Fortran::evaluate::ArrayRef &ref) {
3230
3251
if ((ref.base ().IsSymbol () || ref.base ().Rank () == 0 ) &&
3231
3252
ref.Rank () > 0 && !ref.subscript ().empty ()) {
3253
+ auto baseTy = ael->raiseBaseType (ref.base ());
3254
+ auto ty = ref.base ().IsSymbol ()
3255
+ ? baseTy
3256
+ : baseTy.cast <fir::RecordType>().getType (
3257
+ toStringRef (ref.GetLastSymbol ().name ()));
3258
+ auto bounds = ael->getShape (ty);
3232
3259
assert (ref.subscript ().size () == bounds.size ());
3233
3260
llvm::SmallVector<mlir::Value> result;
3234
3261
auto bdIter = bounds.begin ();
@@ -3248,15 +3275,24 @@ class ArrayExprLowering {
3248
3275
}
3249
3276
return {};
3250
3277
}
3278
+ RT operator ()(const Fortran::evaluate::Component &cpnt) {
3279
+ if (cpnt.base ().Rank () == 0 && cpnt.Rank () > 0 )
3280
+ return ael->getShape (ael->raiseBaseType (cpnt));
3281
+ return {};
3282
+ }
3283
+ RT operator ()(const Fortran::semantics::Symbol &sym) {
3284
+ if (sym.Rank () > 0 )
3285
+ return ael->getShape (ael->raiseBaseType (sym));
3286
+ return {};
3287
+ }
3251
3288
3252
- llvm::SmallVector<mlir::Value> bounds ;
3289
+ ArrayExprLowering * const ael ;
3253
3290
};
3254
3291
3255
- auto originalShape = getShape (converter.genType (e));
3256
- Filter filter (originalShape);
3292
+ Filter filter (this );
3257
3293
if (auto res = filter (e))
3258
3294
return *res;
3259
- return originalShape ;
3295
+ return {} ;
3260
3296
}
3261
3297
3262
3298
void genMasks () {
@@ -4306,6 +4342,10 @@ class ArrayExprLowering {
4306
4342
return false ;
4307
4343
}
4308
4344
4345
+ // / Set of helper member functions for generating the type of a particular
4346
+ // / component along a path. We cannot use the `converter` here because it is
4347
+ // / not possible to uplift an arbitrary component list to a generic
4348
+ // / `Fortran::evaluate::Expr`.
4309
4349
mlir::Type raiseBaseType (const Fortran::evaluate::Component &x) {
4310
4350
auto baseTy = raiseBaseType (x.base ());
4311
4351
auto recTy = baseTy.cast <fir::RecordType>();
@@ -4318,10 +4358,13 @@ class ArrayExprLowering {
4318
4358
LLVM_DEBUG (llvm::dbgs () << " base type s " << rv << ' \n ' );
4319
4359
return rv;
4320
4360
}
4361
+ mlir::Type raiseBaseType (const Fortran::evaluate::NamedEntity &n) {
4362
+ return n.IsSymbol () ? raiseBaseType (n.GetLastSymbol ())
4363
+ : raiseBaseType (n.GetComponent ());
4364
+ }
4321
4365
mlir::Type raiseBaseType (const Fortran::evaluate::ArrayRef &x) {
4322
4366
auto &base = x.base ();
4323
- mlir::Type baseTy = base.IsSymbol () ? raiseBaseType (base.GetLastSymbol ())
4324
- : raiseBaseType (base.GetComponent ());
4367
+ mlir::Type baseTy = raiseBaseType (base);
4325
4368
auto seqTy = baseTy.cast <fir::SequenceType>();
4326
4369
auto rv = seqTy.getEleTy ();
4327
4370
LLVM_DEBUG (llvm::dbgs () << " base type a " << rv << ' \n ' );
@@ -4387,7 +4430,8 @@ class ArrayExprLowering {
4387
4430
4388
4431
RaiseRT
4389
4432
raiseToArray (const Fortran::evaluate::DataRef &x,
4390
- llvm::ArrayRef<const Fortran::semantics::Symbol *> ctrlSet) {
4433
+ llvm::ArrayRef<const Fortran::semantics::Symbol *> ctrlSet,
4434
+ bool isScalar) {
4391
4435
return std::visit (
4392
4436
Fortran::common::visitors{
4393
4437
[&](const Fortran::semantics::SymbolRef &s) -> RaiseRT {
@@ -4401,13 +4445,16 @@ class ArrayExprLowering {
4401
4445
TODO (getLoc (), " coarray reference" );
4402
4446
return {llvm::None, mlir::Type{}, false , false };
4403
4447
},
4404
- [&](const auto &y) -> RaiseRT { return raiseToArray (y, ctrlSet); }},
4448
+ [&](const auto &y) -> RaiseRT {
4449
+ return raiseToArray (y, ctrlSet, isScalar);
4450
+ }},
4405
4451
x.u );
4406
4452
}
4407
4453
RaiseRT
4408
4454
raiseToArray (const Fortran::evaluate::Component &x,
4409
- llvm::ArrayRef<const Fortran::semantics::Symbol *> ctrlSet) {
4410
- auto [fopt, ty, inrank, ranked] = raiseToArray (x.base (), ctrlSet);
4455
+ llvm::ArrayRef<const Fortran::semantics::Symbol *> ctrlSet,
4456
+ bool isScalar) {
4457
+ auto [fopt, ty, inrank, ranked] = raiseToArray (x.base (), ctrlSet, isScalar);
4411
4458
if (fopt.hasValue ()) {
4412
4459
if (!ranked && x.Rank () > 0 ) {
4413
4460
auto [fopt2, ty2] = raiseRankedComponent (fopt, x, ty);
@@ -4424,7 +4471,8 @@ class ArrayExprLowering {
4424
4471
}
4425
4472
RaiseRT
4426
4473
raiseToArray (const Fortran::evaluate::ArrayRef &x,
4427
- llvm::ArrayRef<const Fortran::semantics::Symbol *> ctrlSet) {
4474
+ llvm::ArrayRef<const Fortran::semantics::Symbol *> ctrlSet,
4475
+ bool isScalar) {
4428
4476
const auto &base = x.base ();
4429
4477
auto accessUsesControlVariable = [&]() {
4430
4478
for (const auto &subs : x.subscript ())
@@ -4454,16 +4502,16 @@ class ArrayExprLowering {
4454
4502
}
4455
4503
// Otherwise, it's a component.
4456
4504
auto [fopt, ty, inrank, ranked] =
4457
- raiseToArray (base.GetComponent (), ctrlSet);
4505
+ raiseToArray (base.GetComponent (), ctrlSet, isScalar );
4458
4506
if (fopt.hasValue ())
4459
- return RaiseRT{fopt, ty, inrank, ranked };
4507
+ return RaiseRT{fopt, ty, inrank, x. Rank () > 0 };
4460
4508
if (x.Rank () > 0 || accessUsesControlVariable ()) {
4461
4509
auto [fopt2, ty2] = raiseBase (base.GetComponent ());
4462
4510
return RaiseRT{fopt2, ty2, inrank, x.Rank () > 0 };
4463
4511
}
4464
4512
return RaiseRT{fopt, ty, inrank, ranked};
4465
4513
}(),
4466
- x);
4514
+ x, isScalar );
4467
4515
}
4468
4516
static mlir::Type unwrapBoxEleTy (mlir::Type ty) {
4469
4517
if (auto boxTy = ty.dyn_cast <fir::BoxType>()) {
@@ -4508,7 +4556,7 @@ class ArrayExprLowering {
4508
4556
return {};
4509
4557
}
4510
4558
RaiseRT raiseSubscript (const RaiseRT &tup,
4511
- const Fortran::evaluate::ArrayRef &x) {
4559
+ const Fortran::evaluate::ArrayRef &x, bool isScalar ) {
4512
4560
auto fopt = std::get<llvm::Optional<CC>>(tup);
4513
4561
if (fopt.hasValue ()) {
4514
4562
auto arrTy = std::get<mlir::Type>(tup);
@@ -4587,8 +4635,14 @@ class ArrayExprLowering {
4587
4635
}
4588
4636
}
4589
4637
auto one = builder.createIntegerConstant (loc, idxTy, 1 );
4638
+ llvm::errs () << " DBG: " << isScalar << ' ' << implicitArguments << ' '
4639
+ << x.GetFirstSymbol () << ' \n ' ;
4590
4640
auto pc = [=](IterSpace iters) {
4591
4641
IterationSpace newIters = iters;
4642
+ if (isScalar) {
4643
+ newIters.removeImplicit ();
4644
+ assert (!implicitArguments);
4645
+ }
4592
4646
const auto firstImplicitIndex = iters.beginImplicitIndex ();
4593
4647
auto implicitIndex = iters.endImplicitIndex ();
4594
4648
assert (firstImplicitIndex <= implicitIndex);
@@ -4676,7 +4730,7 @@ class ArrayExprLowering {
4676
4730
// / variables, i.e. `array(func(i))`, are not.
4677
4731
template <typename A>
4678
4732
CC raiseToArray (const A &x) {
4679
- auto tup = raiseToArray (x, collectControlSymbols ());
4733
+ auto tup = raiseToArray (x, collectControlSymbols (), x. Rank () == 0 );
4680
4734
auto fopt = std::get<llvm::Optional<CC>>(tup);
4681
4735
assert (fopt.hasValue () && " continuation must be returned" );
4682
4736
return fopt.getValue ();
@@ -5698,12 +5752,12 @@ void Fortran::lower::createAnyMaskedArrayAssignment(
5698
5752
5699
5753
void Fortran::lower::createAllocatableArrayAssignment (
5700
5754
Fortran::lower::AbstractConverter &converter,
5701
- const fir::MutableBoxValue &lhs,
5755
+ const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &lhs,
5702
5756
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &rhs,
5703
5757
Fortran::lower::ExplicitIterSpace &explicitSpace,
5704
5758
Fortran::lower::ImplicitIterSpace &implicitSpace,
5705
5759
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx) {
5706
- LLVM_DEBUG (llvm::dbgs () << " defining array: " << lhs << ' \n ' ;
5760
+ LLVM_DEBUG (lhs. AsFortran ( llvm::dbgs () << " defining array: " ) << ' \n ' ;
5707
5761
rhs.AsFortran (llvm::dbgs () << " assign expression: " )
5708
5762
<< " given the explicit iteration space:\n "
5709
5763
<< explicitSpace << " \n and implied mask conditions:\n "
@@ -5731,7 +5785,7 @@ fir::ExtendedValue Fortran::lower::createSomeArrayBox(
5731
5785
stmtCtx, expr);
5732
5786
}
5733
5787
5734
- fir::MutableBoxValue Fortran::lower::createSomeMutableBox (
5788
+ fir::MutableBoxValue Fortran::lower::createMutableBox (
5735
5789
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
5736
5790
const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &expr,
5737
5791
Fortran::lower::SymMap &symMap) {
0 commit comments