@@ -959,119 +959,6 @@ static mlir::Value getReductionInitValue(fir::FirOpBuilder &builder,
959
959
llvm::report_fatal_error (" Unsupported OpenACC reduction type" );
960
960
}
961
961
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
-
1075
962
template <typename RecipeOp>
1076
963
static RecipeOp genRecipeOp (
1077
964
fir::FirOpBuilder &builder, mlir::ModuleOp mod, llvm::StringRef recipeName,
@@ -1100,15 +987,35 @@ static RecipeOp genRecipeOp(
1100
987
}
1101
988
}
1102
989
}
1103
- builder.createBlock (&recipe. getInitRegion (), recipe. getInitRegion (). end (),
1104
- argsTy, argsLoc);
990
+ auto initBlock = builder.createBlock (
991
+ &recipe. getInitRegion (), recipe. getInitRegion (). end (), argsTy, argsLoc);
1105
992
builder.setInsertionPointToEnd (&recipe.getInitRegion ().back ());
1106
993
mlir::Value initValue;
1107
994
if constexpr (std::is_same_v<RecipeOp, mlir::acc::ReductionRecipeOp>) {
1108
995
assert (op != mlir::acc::ReductionOperator::AccNone);
1109
996
initValue = getReductionInitValue (builder, loc, fir::unwrapRefType (ty), op);
1110
997
}
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 ));
1112
1019
return recipe;
1113
1020
}
1114
1021
0 commit comments