@@ -59,6 +59,21 @@ struct MapInfoOpConversion
59
59
: public OpenMPFIROpConversion<mlir::omp::MapInfoOp> {
60
60
using OpenMPFIROpConversion::OpenMPFIROpConversion;
61
61
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
+
62
77
llvm::LogicalResult
63
78
matchAndRewrite (mlir::omp::MapInfoOp curOp, OpAdaptor adaptor,
64
79
mlir::ConversionPatternRewriter &rewriter) const override {
@@ -68,13 +83,58 @@ struct MapInfoOpConversion
68
83
return mlir::failure ();
69
84
70
85
llvm::SmallVector<mlir::NamedAttribute> newAttrs;
71
- mlir::omp::MapInfoOp newOp ;
86
+ mlir::omp::MapBoundsOp mapBoundsOp ;
72
87
for (mlir::NamedAttribute attr : curOp->getAttrs ()) {
73
88
if (auto typeAttr = mlir::dyn_cast<mlir::TypeAttr>(attr.getValue ())) {
74
89
mlir::Type newAttr;
75
90
if (fir::isTypeWithDescriptor (typeAttr.getValue ())) {
76
91
newAttr = lowerTy ().convertBoxTypeAsStruct (
77
92
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
+ }
78
138
} else {
79
139
newAttr = converter->convertType (typeAttr.getValue ());
80
140
}
@@ -84,8 +144,13 @@ struct MapInfoOpConversion
84
144
}
85
145
}
86
146
87
- rewriter.replaceOpWithNewOp <mlir::omp::MapInfoOp>(
147
+ auto newOp = rewriter.replaceOpWithNewOp <mlir::omp::MapInfoOp>(
88
148
curOp, resTypes, adaptor.getOperands (), newAttrs);
149
+ if (mapBoundsOp) {
150
+ rewriter.startOpModification (newOp);
151
+ newOp.getBoundsMutable ().append (mlir::ValueRange{mapBoundsOp});
152
+ rewriter.finalizeOpModification (newOp);
153
+ }
89
154
90
155
return mlir::success ();
91
156
}
0 commit comments