@@ -959,119 +959,6 @@ static mlir::Value getReductionInitValue(fir::FirOpBuilder &builder,
959959 llvm::report_fatal_error (" Unsupported OpenACC reduction type" );
960960}
961961
962- template <typename RecipeOp>
963- static void genPrivateLikeInitRegion (fir::FirOpBuilder &builder,
964- RecipeOp recipe, mlir::Type argTy,
965- mlir::Location loc,
966- mlir::Value initValue) {
967- mlir::Value retVal = recipe.getInitRegion ().front ().getArgument (0 );
968- mlir::Type unwrappedTy = fir::unwrapRefType (argTy);
969-
970- llvm::StringRef initName;
971- if constexpr (std::is_same_v<RecipeOp, mlir::acc::ReductionRecipeOp>)
972- initName = accReductionInitName;
973- else
974- initName = accPrivateInitName;
975-
976- auto getDeclareOpForType = [&](mlir::Type ty) -> hlfir::DeclareOp {
977- auto alloca = builder.create <fir::AllocaOp>(loc, ty);
978- return builder.create <hlfir::DeclareOp>(
979- loc, alloca, initName, /* shape=*/ nullptr , llvm::ArrayRef<mlir::Value>{},
980- /* dummy_scope=*/ nullptr , fir::FortranVariableFlagsAttr{});
981- };
982-
983- if (fir::isa_trivial (unwrappedTy)) {
984- auto declareOp = getDeclareOpForType (unwrappedTy);
985- if (initValue) {
986- auto convert = builder.createConvert (loc, unwrappedTy, initValue);
987- builder.create <fir::StoreOp>(loc, convert, declareOp.getBase ());
988- }
989- retVal = declareOp.getBase ();
990- } else if (auto seqTy =
991- mlir::dyn_cast_or_null<fir::SequenceType>(unwrappedTy)) {
992- if (fir::isa_trivial (seqTy.getEleTy ())) {
993- mlir::Value shape;
994- llvm::SmallVector<mlir::Value> extents;
995- if (seqTy.hasDynamicExtents ()) {
996- // Extents are passed as block arguments. First argument is the
997- // original value.
998- for (unsigned i = 1 ; i < recipe.getInitRegion ().getArguments ().size ();
999- ++i)
1000- extents.push_back (recipe.getInitRegion ().getArgument (i));
1001- shape = builder.create <fir::ShapeOp>(loc, extents);
1002- } else {
1003- shape = genShapeOp (builder, seqTy, loc);
1004- }
1005- auto alloca = builder.create <fir::AllocaOp>(
1006- loc, seqTy, /* typeparams=*/ mlir::ValueRange{}, extents);
1007- auto declareOp = builder.create <hlfir::DeclareOp>(
1008- loc, alloca, initName, shape, llvm::ArrayRef<mlir::Value>{},
1009- /* dummy_scope=*/ nullptr , fir::FortranVariableFlagsAttr{});
1010-
1011- if (initValue) {
1012- mlir::Type idxTy = builder.getIndexType ();
1013- mlir::Type refTy = fir::ReferenceType::get (seqTy.getEleTy ());
1014- llvm::SmallVector<fir::DoLoopOp> loops;
1015- llvm::SmallVector<mlir::Value> ivs;
1016-
1017- if (seqTy.hasDynamicExtents ()) {
1018- builder.create <hlfir::AssignOp>(loc, initValue, declareOp.getBase ());
1019- } else {
1020- for (auto ext : seqTy.getShape ()) {
1021- auto lb = builder.createIntegerConstant (loc, idxTy, 0 );
1022- auto ub = builder.createIntegerConstant (loc, idxTy, ext - 1 );
1023- auto step = builder.createIntegerConstant (loc, idxTy, 1 );
1024- auto loop = builder.create <fir::DoLoopOp>(loc, lb, ub, step,
1025- /* unordered=*/ false );
1026- builder.setInsertionPointToStart (loop.getBody ());
1027- loops.push_back (loop);
1028- ivs.push_back (loop.getInductionVar ());
1029- }
1030- auto coord = builder.create <fir::CoordinateOp>(
1031- loc, refTy, declareOp.getBase (), ivs);
1032- builder.create <fir::StoreOp>(loc, initValue, coord);
1033- builder.setInsertionPointAfter (loops[0 ]);
1034- }
1035- }
1036- retVal = declareOp.getBase ();
1037- }
1038- } else if (auto boxTy =
1039- mlir::dyn_cast_or_null<fir::BaseBoxType>(unwrappedTy)) {
1040- mlir::Type innerTy = fir::unwrapRefType (boxTy.getEleTy ());
1041- if (fir::isa_trivial (innerTy)) {
1042- retVal = getDeclareOpForType (unwrappedTy).getBase ();
1043- } else if (mlir::isa<fir::SequenceType>(innerTy)) {
1044- fir::FirOpBuilder firBuilder{builder, recipe.getOperation ()};
1045- hlfir::Entity source = hlfir::Entity{retVal};
1046- auto [temp, cleanup] = hlfir::createTempFromMold (loc, firBuilder, source);
1047- if (fir::isa_ref_type (argTy)) {
1048- // When the temp is created - it is not a reference - thus we can
1049- // end up with a type inconsistency. Therefore ensure storage is created
1050- // for it.
1051- retVal = getDeclareOpForType (unwrappedTy).getBase ();
1052- mlir::Value storeDst = retVal;
1053- if (fir::unwrapRefType (retVal.getType ()) != temp.getType ()) {
1054- // `createTempFromMold` makes the unfortunate choice to lose the
1055- // `fir.heap` and `fir.ptr` types when wrapping with a box. Namely,
1056- // when wrapping a `fir.heap<fir.array>`, it will create instead a
1057- // `fir.box<fir.array>`. Cast here to deal with this inconsistency.
1058- storeDst = firBuilder.createConvert (
1059- loc, firBuilder.getRefType (temp.getType ()), retVal);
1060- }
1061- builder.create <fir::StoreOp>(loc, temp, storeDst);
1062- } else {
1063- retVal = temp;
1064- }
1065- } else {
1066- TODO (loc, " Unsupported boxed type for OpenACC private-like recipe" );
1067- }
1068- if (initValue) {
1069- builder.create <hlfir::AssignOp>(loc, initValue, retVal);
1070- }
1071- }
1072- builder.create <mlir::acc::YieldOp>(loc, retVal);
1073- }
1074-
1075962template <typename RecipeOp>
1076963static RecipeOp genRecipeOp (
1077964 fir::FirOpBuilder &builder, mlir::ModuleOp mod, llvm::StringRef recipeName,
@@ -1100,15 +987,35 @@ static RecipeOp genRecipeOp(
1100987 }
1101988 }
1102989 }
1103- builder.createBlock (&recipe. getInitRegion (), recipe. getInitRegion (). end (),
1104- argsTy, argsLoc);
990+ auto initBlock = builder.createBlock (
991+ &recipe. getInitRegion (), recipe. getInitRegion (). end (), argsTy, argsLoc);
1105992 builder.setInsertionPointToEnd (&recipe.getInitRegion ().back ());
1106993 mlir::Value initValue;
1107994 if constexpr (std::is_same_v<RecipeOp, mlir::acc::ReductionRecipeOp>) {
1108995 assert (op != mlir::acc::ReductionOperator::AccNone);
1109996 initValue = getReductionInitValue (builder, loc, fir::unwrapRefType (ty), op);
1110997 }
1111- genPrivateLikeInitRegion<RecipeOp>(builder, recipe, ty, loc, initValue);
998+
999+ // Since we reuse the same recipe for all variables of the same type - we
1000+ // cannot use the actual variable name. Thus use a temporary name.
1001+ llvm::StringRef initName;
1002+ if constexpr (std::is_same_v<RecipeOp, mlir::acc::ReductionRecipeOp>)
1003+ initName = accReductionInitName;
1004+ else
1005+ initName = accPrivateInitName;
1006+
1007+ auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(ty);
1008+ assert (mappableTy &&
1009+ " Expected that all variable types are considered mappable" );
1010+ auto retVal = mappableTy.generatePrivateInit (
1011+ builder, loc,
1012+ mlir::cast<mlir::TypedValue<mlir::acc::MappableType>>(
1013+ initBlock->getArgument (0 )),
1014+ initName,
1015+ initBlock->getArguments ().take_back (initBlock->getArguments ().size () - 1 ),
1016+ initValue);
1017+ builder.create <mlir::acc::YieldOp>(loc, retVal ? retVal
1018+ : initBlock->getArgument (0 ));
11121019 return recipe;
11131020}
11141021
0 commit comments