@@ -382,13 +382,23 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
382
382
retVal = declareOp.getBase ();
383
383
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(
384
384
refTy.getEleTy ())) {
385
- if (seqTy.hasDynamicExtents ())
386
- TODO (loc, " private recipe of array with dynamic extents" );
387
385
if (fir::isa_trivial (seqTy.getEleTy ())) {
388
- auto alloca = builder.create <fir::AllocaOp>(loc, seqTy);
389
- auto shapeOp = genShapeOp (builder, seqTy, loc);
386
+ mlir::Value shape;
387
+ llvm::SmallVector<mlir::Value> extents;
388
+ if (seqTy.hasDynamicExtents ()) {
389
+ // Extents are passed as block arguments. First argument is the
390
+ // original value.
391
+ for (unsigned i = 1 ; i < recipe.getInitRegion ().getArguments ().size ();
392
+ ++i)
393
+ extents.push_back (recipe.getInitRegion ().getArgument (i));
394
+ shape = builder.create <fir::ShapeOp>(loc, extents);
395
+ } else {
396
+ shape = genShapeOp (builder, seqTy, loc);
397
+ }
398
+ auto alloca = builder.create <fir::AllocaOp>(
399
+ loc, seqTy, /* typeparams=*/ mlir::ValueRange{}, extents);
390
400
auto declareOp = builder.create <hlfir::DeclareOp>(
391
- loc, alloca , accPrivateInitName, shapeOp ,
401
+ loc, alloca , accPrivateInitName, shape ,
392
402
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
393
403
retVal = declareOp.getBase ();
394
404
}
@@ -418,8 +428,22 @@ Fortran::lower::createOrGetPrivateRecipe(mlir::OpBuilder &builder,
418
428
mlir::OpBuilder modBuilder (mod.getBodyRegion ());
419
429
auto recipe =
420
430
modBuilder.create <mlir::acc::PrivateRecipeOp>(loc, recipeName, ty);
431
+ llvm::SmallVector<mlir::Type> argsTy{ty};
432
+ llvm::SmallVector<mlir::Location> argsLoc{loc};
433
+ if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
434
+ if (auto seqTy =
435
+ mlir::dyn_cast_or_null<fir::SequenceType>(refTy.getEleTy ())) {
436
+ if (seqTy.hasDynamicExtents ()) {
437
+ mlir::Type idxTy = builder.getIndexType ();
438
+ for (unsigned i = 0 ; i < seqTy.getDimension (); ++i) {
439
+ argsTy.push_back (idxTy);
440
+ argsLoc.push_back (loc);
441
+ }
442
+ }
443
+ }
444
+ }
421
445
builder.createBlock (&recipe.getInitRegion (), recipe.getInitRegion ().end (),
422
- {ty}, {loc} );
446
+ argsTy, argsLoc );
423
447
builder.setInsertionPointToEnd (&recipe.getInitRegion ().back ());
424
448
genPrivateLikeInitRegion<mlir::acc::PrivateRecipeOp>(builder, recipe, ty,
425
449
loc);
@@ -554,6 +578,29 @@ mlir::Type getTypeFromBounds(llvm::SmallVector<mlir::Value> &bounds,
554
578
return ty;
555
579
}
556
580
581
+ // / Check if the DataBoundsOp is a constant bound (lb and ub are constants or
582
+ // / extent is a constant).
583
+ bool isConstantBound (mlir::acc::DataBoundsOp &op) {
584
+ if (op.getLowerbound () && fir::getIntIfConstant (op.getLowerbound ()) &&
585
+ op.getUpperbound () && fir::getIntIfConstant (op.getUpperbound ()))
586
+ return true ;
587
+ if (op.getExtent () && fir::getIntIfConstant (op.getExtent ()))
588
+ return true ;
589
+ return false ;
590
+ }
591
+
592
+ // / Return true iff all the bounds are expressed with constant values.
593
+ bool areAllBoundConstant (llvm::SmallVector<mlir::Value> &bounds) {
594
+ for (auto bound : bounds) {
595
+ auto dataBound =
596
+ mlir::dyn_cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp ());
597
+ assert (dataBound && " Must be DataBoundOp operation" );
598
+ if (!isConstantBound (dataBound))
599
+ return false ;
600
+ }
601
+ return true ;
602
+ }
603
+
557
604
template <typename RecipeOp>
558
605
static void
559
606
genPrivatizations (const Fortran::parser::AccObjectList &objectList,
@@ -683,29 +730,6 @@ static R getReductionInitValue(mlir::acc::ReductionOperator op, mlir::Type ty) {
683
730
llvm_unreachable (" OpenACC reduction unsupported type" );
684
731
}
685
732
686
- // / Check if the DataBoundsOp is a constant bound (lb and ub are constants or
687
- // / extent is a constant).
688
- bool isConstantBound (mlir::acc::DataBoundsOp &op) {
689
- if (op.getLowerbound () && fir::getIntIfConstant (op.getLowerbound ()) &&
690
- op.getUpperbound () && fir::getIntIfConstant (op.getUpperbound ()))
691
- return true ;
692
- if (op.getExtent () && fir::getIntIfConstant (op.getExtent ()))
693
- return true ;
694
- return false ;
695
- }
696
-
697
- // / Return true iff all the bounds are expressed with constant values.
698
- bool areAllBoundConstant (llvm::SmallVector<mlir::Value> &bounds) {
699
- for (auto bound : bounds) {
700
- auto dataBound =
701
- mlir::dyn_cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp ());
702
- assert (dataBound && " Must be DataBoundOp operation" );
703
- if (!isConstantBound (dataBound))
704
- return false ;
705
- }
706
- return true ;
707
- }
708
-
709
733
// / Return a constant with the initial value for the reduction operator and
710
734
// / type combination.
711
735
static mlir::Value getReductionInitValue (fir::FirOpBuilder &builder,
0 commit comments