@@ -59,6 +59,21 @@ struct MapInfoOpConversion
5959 : public OpenMPFIROpConversion<mlir::omp::MapInfoOp> {
6060 using OpenMPFIROpConversion::OpenMPFIROpConversion;
6161
62+ mlir::omp::MapBoundsOp
63+ createBoundsForCharString (mlir::ConversionPatternRewriter &rewriter,
64+ unsigned int len, mlir::Location loc) const {
65+ mlir::Type i64Ty = rewriter.getIntegerType (64 );
66+ auto lBound = mlir::LLVM::ConstantOp::create (rewriter, loc, i64Ty, 0 );
67+ auto uBoundAndExt =
68+ mlir::LLVM::ConstantOp::create (rewriter, loc, i64Ty, len - 1 );
69+ auto stride = mlir::LLVM::ConstantOp::create (rewriter, loc, i64Ty, 1 );
70+ auto baseLb = mlir::LLVM::ConstantOp::create (rewriter, loc, i64Ty, 1 );
71+ auto mapBoundType = rewriter.getType <mlir::omp::MapBoundsType>();
72+ return mlir::omp::MapBoundsOp::create (rewriter, loc, mapBoundType, lBound,
73+ uBoundAndExt, uBoundAndExt, stride,
74+ /* strideInBytes*/ false , baseLb);
75+ }
76+
6277 llvm::LogicalResult
6378 matchAndRewrite (mlir::omp::MapInfoOp curOp, OpAdaptor adaptor,
6479 mlir::ConversionPatternRewriter &rewriter) const override {
@@ -68,13 +83,58 @@ struct MapInfoOpConversion
6883 return mlir::failure ();
6984
7085 llvm::SmallVector<mlir::NamedAttribute> newAttrs;
71- mlir::omp::MapInfoOp newOp ;
86+ mlir::omp::MapBoundsOp mapBoundsOp ;
7287 for (mlir::NamedAttribute attr : curOp->getAttrs ()) {
7388 if (auto typeAttr = mlir::dyn_cast<mlir::TypeAttr>(attr.getValue ())) {
7489 mlir::Type newAttr;
7590 if (fir::isTypeWithDescriptor (typeAttr.getValue ())) {
7691 newAttr = lowerTy ().convertBoxTypeAsStruct (
7792 mlir::cast<fir::BaseBoxType>(typeAttr.getValue ()));
93+ } else if (fir::isa_char_string (fir::unwrapSequenceType (
94+ fir::unwrapPassByRefType (typeAttr.getValue ()))) &&
95+ !characterWithDynamicLen (
96+ fir::unwrapPassByRefType (typeAttr.getValue ()))) {
97+ // Characters with a LEN param are represented as char
98+ // arrays/strings, the initial lowering doesn't generate
99+ // bounds for these, however, we require them to map the
100+ // data appropriately in the later lowering stages. This
101+ // is to prevent the need for unecessary caveats
102+ // specific to Flang. We also strip the array from the
103+ // type so that all variations of strings are treated
104+ // identically and there's no caveats or specialisations
105+ // required in the later stages. As an example, Boxed
106+ // char strings will emit a single char array no matter
107+ // the number of dimensions caused by additional array
108+ // dimensions which needs specialised for, as it differs
109+ // from the non-box variation which will emit each array
110+ // wrapping the character array, e.g. given a type of
111+ // the same dimensions, if one is boxed, the types would
112+ // end up:
113+ //
114+ // array<i8 x 16>
115+ // vs
116+ // array<10 x array< 10 x array<i8 x 16>>>
117+ //
118+ // This means we have to treat one specially in the
119+ // lowering. So we try to "canonicalize" it here.
120+ // TODO: Handle dynamic LEN characters.
121+ if (auto ct = mlir::dyn_cast_or_null<fir::CharacterType>(
122+ fir::unwrapSequenceType (typeAttr.getValue ()))) {
123+ newAttr = converter->convertType (
124+ fir::unwrapSequenceType (typeAttr.getValue ()));
125+ if (auto type = mlir::dyn_cast<mlir::LLVM::LLVMArrayType>(newAttr))
126+ newAttr = type.getElementType ();
127+ // We do not generate for device, as MapBoundsOps are
128+ // unsupported, as they're currently unused.
129+ auto offloadMod =
130+ llvm::dyn_cast_or_null<mlir::omp::OffloadModuleInterface>(
131+ *curOp->getParentOfType <mlir::ModuleOp>());
132+ if (!offloadMod.getIsTargetDevice ())
133+ mapBoundsOp = createBoundsForCharString (rewriter, ct.getLen (),
134+ curOp.getLoc ());
135+ } else {
136+ newAttr = converter->convertType (typeAttr.getValue ());
137+ }
78138 } else {
79139 newAttr = converter->convertType (typeAttr.getValue ());
80140 }
@@ -84,8 +144,13 @@ struct MapInfoOpConversion
84144 }
85145 }
86146
87- rewriter.replaceOpWithNewOp <mlir::omp::MapInfoOp>(
147+ auto newOp = rewriter.replaceOpWithNewOp <mlir::omp::MapInfoOp>(
88148 curOp, resTypes, adaptor.getOperands (), newAttrs);
149+ if (mapBoundsOp) {
150+ rewriter.startOpModification (newOp);
151+ newOp.getBoundsMutable ().append (mlir::ValueRange{mapBoundsOp});
152+ rewriter.finalizeOpModification (newOp);
153+ }
89154
90155 return mlir::success ();
91156 }
0 commit comments