@@ -399,7 +399,7 @@ hlfir::genBounds(mlir::Location loc, fir::FirOpBuilder &builder,
399
399
return result;
400
400
}
401
401
402
- static hlfir::Entity followEntitySource (hlfir::Entity entity) {
402
+ static hlfir::Entity followShapeInducingSource (hlfir::Entity entity) {
403
403
while (true ) {
404
404
if (auto reassoc = entity.getDefiningOp <hlfir::NoReassocOp>()) {
405
405
entity = hlfir::Entity{reassoc.getVal ()};
@@ -414,6 +414,24 @@ static hlfir::Entity followEntitySource(hlfir::Entity entity) {
414
414
return entity;
415
415
}
416
416
417
+ static mlir::Value computeVariableExtent (mlir::Location loc,
418
+ fir::FirOpBuilder &builder,
419
+ hlfir::Entity variable,
420
+ fir::SequenceType seqTy,
421
+ unsigned dim) {
422
+ mlir::Type idxTy = builder.getIndexType ();
423
+ if (seqTy.getShape ().size () > dim) {
424
+ fir::SequenceType::Extent typeExtent = seqTy.getShape ()[dim];
425
+ if (typeExtent != fir::SequenceType::getUnknownExtent ())
426
+ return builder.createIntegerConstant (loc, idxTy, typeExtent);
427
+ }
428
+ assert (variable.getType ().isa <fir::BaseBoxType>() &&
429
+ " array variable with dynamic extent must be boxed" );
430
+ mlir::Value dimVal = builder.createIntegerConstant (loc, idxTy, dim);
431
+ auto dimInfo = builder.create <fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy,
432
+ variable, dimVal);
433
+ return dimInfo.getExtent ();
434
+ }
417
435
llvm::SmallVector<mlir::Value> getVariableExtents (mlir::Location loc,
418
436
fir::FirOpBuilder &builder,
419
437
hlfir::Entity variable) {
@@ -432,42 +450,38 @@ llvm::SmallVector<mlir::Value> getVariableExtents(mlir::Location loc,
432
450
fir::SequenceType seqTy =
433
451
hlfir::getFortranElementOrSequenceType (variable.getType ())
434
452
.cast <fir::SequenceType>();
435
- mlir::Type idxTy = builder.getIndexType ();
436
- for (auto typeExtent : seqTy.getShape ())
437
- if (typeExtent != fir::SequenceType::getUnknownExtent ()) {
438
- extents.push_back (builder.createIntegerConstant (loc, idxTy, typeExtent));
439
- } else {
440
- assert (variable.getType ().isa <fir::BaseBoxType>() &&
441
- " array variable with dynamic extent must be boxed" );
442
- mlir::Value dim =
443
- builder.createIntegerConstant (loc, idxTy, extents.size ());
444
- auto dimInfo = builder.create <fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy,
445
- variable, dim);
446
- extents.push_back (dimInfo.getExtent ());
447
- }
453
+ unsigned rank = seqTy.getShape ().size ();
454
+ for (unsigned dim = 0 ; dim < rank; ++dim)
455
+ extents.push_back (
456
+ computeVariableExtent (loc, builder, variable, seqTy, dim));
448
457
return extents;
449
458
}
450
459
451
- mlir::Value hlfir::genShape (mlir::Location loc, fir::FirOpBuilder &builder,
452
- hlfir::Entity entity) {
453
- assert (entity.isArray () && " entity must be an array" );
454
- entity = followEntitySource (entity);
455
-
460
+ static mlir::Value tryRetrievingShapeOrShift (hlfir::Entity entity) {
456
461
if (entity.getType ().isa <hlfir::ExprType>()) {
457
462
if (auto elemental = entity.getDefiningOp <hlfir::ElementalOp>())
458
463
return elemental.getShape ();
459
- TODO (loc, " get shape from HLFIR expr without producer holding the shape " ) ;
464
+ return mlir::Value{} ;
460
465
}
461
- // Entity is an array variable.
462
- if (auto varIface = entity.getIfVariableInterface ()) {
463
- if (auto shape = varIface.getShape ()) {
464
- if (shape.getType ().isa <fir::ShapeType>())
465
- return shape;
466
- if (shape.getType ().isa <fir::ShapeShiftType>())
467
- if (auto s = shape.getDefiningOp <fir::ShapeShiftOp>())
468
- return builder.create <fir::ShapeOp>(loc, s.getExtents ());
469
- }
466
+ if (auto varIface = entity.getIfVariableInterface ())
467
+ return varIface.getShape ();
468
+ return {};
469
+ }
470
+
471
+ mlir::Value hlfir::genShape (mlir::Location loc, fir::FirOpBuilder &builder,
472
+ hlfir::Entity entity) {
473
+ assert (entity.isArray () && " entity must be an array" );
474
+ entity = followShapeInducingSource (entity);
475
+ assert (entity && " what?" );
476
+ if (auto shape = tryRetrievingShapeOrShift (entity)) {
477
+ if (shape.getType ().isa <fir::ShapeType>())
478
+ return shape;
479
+ if (shape.getType ().isa <fir::ShapeShiftType>())
480
+ if (auto s = shape.getDefiningOp <fir::ShapeShiftOp>())
481
+ return builder.create <fir::ShapeOp>(loc, s.getExtents ());
470
482
}
483
+ if (entity.getType ().isa <hlfir::ExprType>())
484
+ TODO (loc, " get shape from HLFIR expr without producer holding the shape" );
471
485
// There is no shape lying around for this entity. Retrieve the extents and
472
486
// build a new fir.shape.
473
487
return builder.create <fir::ShapeOp>(loc,
@@ -484,6 +498,50 @@ hlfir::getIndexExtents(mlir::Location loc, fir::FirOpBuilder &builder,
484
498
return extents;
485
499
}
486
500
501
+ mlir::Value hlfir::genExtent (mlir::Location loc, fir::FirOpBuilder &builder,
502
+ hlfir::Entity entity, unsigned dim) {
503
+ entity = followShapeInducingSource (entity);
504
+ if (auto shape = tryRetrievingShapeOrShift (entity)) {
505
+ auto extents = getExplicitExtentsFromShape (shape);
506
+ if (!extents.empty ()) {
507
+ assert (extents.size () > dim && " bad inquiry" );
508
+ return extents[dim];
509
+ }
510
+ }
511
+ if (entity.isVariable ()) {
512
+ if (entity.isMutableBox ())
513
+ entity = hlfir::derefPointersAndAllocatables (loc, builder, entity);
514
+ // Use the type shape information, and/or the fir.box/fir.class shape
515
+ // information if any extents are not static.
516
+ fir::SequenceType seqTy =
517
+ hlfir::getFortranElementOrSequenceType (entity.getType ())
518
+ .cast <fir::SequenceType>();
519
+ return computeVariableExtent (loc, builder, entity, seqTy, dim);
520
+ }
521
+ TODO (loc, " get extent from HLFIR expr without producer holding the shape" );
522
+ }
523
+
524
+ mlir::Value hlfir::genLBound (mlir::Location loc, fir::FirOpBuilder &builder,
525
+ hlfir::Entity entity, unsigned dim) {
526
+ if (!entity.hasNonDefaultLowerBounds ())
527
+ return builder.createIntegerConstant (loc, builder.getIndexType (), 1 );
528
+ if (auto shape = tryRetrievingShapeOrShift (entity)) {
529
+ auto lbounds = getExplicitLboundsFromShape (shape);
530
+ if (!lbounds.empty ()) {
531
+ assert (lbounds.size () > dim && " bad inquiry" );
532
+ return lbounds[dim];
533
+ }
534
+ }
535
+ if (entity.isMutableBox ())
536
+ entity = hlfir::derefPointersAndAllocatables (loc, builder, entity);
537
+ assert (entity.getType ().isa <fir::BaseBoxType>() && " must be a box" );
538
+ mlir::Type idxTy = builder.getIndexType ();
539
+ mlir::Value dimVal = builder.createIntegerConstant (loc, idxTy, dim);
540
+ auto dimInfo =
541
+ builder.create <fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, entity, dimVal);
542
+ return dimInfo.getLowerBound ();
543
+ }
544
+
487
545
void hlfir::genLengthParameters (mlir::Location loc, fir::FirOpBuilder &builder,
488
546
Entity entity,
489
547
llvm::SmallVectorImpl<mlir::Value> &result) {
0 commit comments