@@ -87,6 +87,14 @@ static inline mlir::Type getI8Type(mlir::MLIRContext *context) {
87
87
return mlir::IntegerType::get (context, 8 );
88
88
}
89
89
90
+ static mlir::LLVM::ConstantOp
91
+ genConstantIndex (mlir::Location loc, mlir::Type ity,
92
+ mlir::ConversionPatternRewriter &rewriter,
93
+ std::int64_t offset) {
94
+ auto cattr = rewriter.getI64IntegerAttr (offset);
95
+ return mlir::LLVM::ConstantOp::create (rewriter, loc, ity, cattr);
96
+ }
97
+
90
98
static mlir::Block *createBlock (mlir::ConversionPatternRewriter &rewriter,
91
99
mlir::Block *insertBefore) {
92
100
assert (insertBefore && " expected valid insertion block" );
@@ -200,6 +208,39 @@ getDependentTypeMemSizeFn(fir::RecordType recTy, fir::AllocaOp op,
200
208
TODO (op.getLoc (), " did not find allocation function" );
201
209
}
202
210
211
+ // Compute the alloc scale size (constant factors encoded in the array type).
212
+ // We do this for arrays without a constant interior or arrays of character with
213
+ // dynamic length arrays, since those are the only ones that get decayed to a
214
+ // pointer to the element type.
215
+ template <typename OP>
216
+ static mlir::Value
217
+ genAllocationScaleSize (OP op, mlir::Type ity,
218
+ mlir::ConversionPatternRewriter &rewriter) {
219
+ mlir::Location loc = op.getLoc ();
220
+ mlir::Type dataTy = op.getInType ();
221
+ auto seqTy = mlir::dyn_cast<fir::SequenceType>(dataTy);
222
+ fir::SequenceType::Extent constSize = 1 ;
223
+ if (seqTy) {
224
+ int constRows = seqTy.getConstantRows ();
225
+ const fir::SequenceType::ShapeRef &shape = seqTy.getShape ();
226
+ if (constRows != static_cast <int >(shape.size ())) {
227
+ for (auto extent : shape) {
228
+ if (constRows-- > 0 )
229
+ continue ;
230
+ if (extent != fir::SequenceType::getUnknownExtent ())
231
+ constSize *= extent;
232
+ }
233
+ }
234
+ }
235
+
236
+ if (constSize != 1 ) {
237
+ mlir::Value constVal{
238
+ genConstantIndex (loc, ity, rewriter, constSize).getResult ()};
239
+ return constVal;
240
+ }
241
+ return nullptr ;
242
+ }
243
+
203
244
namespace {
204
245
struct DeclareOpConversion : public fir ::FIROpConversion<fir::cg::XDeclareOp> {
205
246
public:
@@ -234,7 +275,7 @@ struct AllocaOpConversion : public fir::FIROpConversion<fir::AllocaOp> {
234
275
auto loc = alloc.getLoc ();
235
276
mlir::Type ity = lowerTy ().indexType ();
236
277
unsigned i = 0 ;
237
- mlir::Value size = fir:: genConstantIndex (loc, ity, rewriter, 1 ).getResult ();
278
+ mlir::Value size = genConstantIndex (loc, ity, rewriter, 1 ).getResult ();
238
279
mlir::Type firObjType = fir::unwrapRefType (alloc.getType ());
239
280
mlir::Type llvmObjectType = convertObjectType (firObjType);
240
281
if (alloc.hasLenParams ()) {
@@ -266,8 +307,7 @@ struct AllocaOpConversion : public fir::FIROpConversion<fir::AllocaOp> {
266
307
<< scalarType << " with type parameters" ;
267
308
}
268
309
}
269
- if (auto scaleSize = fir::genAllocationScaleSize (
270
- alloc.getLoc (), alloc.getInType (), ity, rewriter))
310
+ if (auto scaleSize = genAllocationScaleSize (alloc, ity, rewriter))
271
311
size =
272
312
rewriter.createOrFold <mlir::LLVM::MulOp>(loc, ity, size, scaleSize);
273
313
if (alloc.hasShapeOperands ()) {
@@ -444,7 +484,7 @@ struct BoxIsArrayOpConversion : public fir::FIROpConversion<fir::BoxIsArrayOp> {
444
484
auto loc = boxisarray.getLoc ();
445
485
TypePair boxTyPair = getBoxTypePair (boxisarray.getVal ().getType ());
446
486
mlir::Value rank = getRankFromBox (loc, boxTyPair, a, rewriter);
447
- mlir::Value c0 = fir:: genConstantIndex (loc, rank.getType (), rewriter, 0 );
487
+ mlir::Value c0 = genConstantIndex (loc, rank.getType (), rewriter, 0 );
448
488
rewriter.replaceOpWithNewOp <mlir::LLVM::ICmpOp>(
449
489
boxisarray, mlir::LLVM::ICmpPredicate::ne, rank, c0);
450
490
return mlir::success ();
@@ -780,7 +820,7 @@ struct ConvertOpConversion : public fir::FIROpConversion<fir::ConvertOp> {
780
820
// Do folding for constant inputs.
781
821
if (auto constVal = fir::getIntIfConstant (op0)) {
782
822
mlir::Value normVal =
783
- fir:: genConstantIndex (loc, toTy, rewriter, *constVal ? 1 : 0 );
823
+ genConstantIndex (loc, toTy, rewriter, *constVal ? 1 : 0 );
784
824
rewriter.replaceOp (convert, normVal);
785
825
return mlir::success ();
786
826
}
@@ -793,7 +833,7 @@ struct ConvertOpConversion : public fir::FIROpConversion<fir::ConvertOp> {
793
833
}
794
834
795
835
// Compare the input with zero.
796
- mlir::Value zero = fir:: genConstantIndex (loc, fromTy, rewriter, 0 );
836
+ mlir::Value zero = genConstantIndex (loc, fromTy, rewriter, 0 );
797
837
auto isTrue = mlir::LLVM::ICmpOp::create (
798
838
rewriter, loc, mlir::LLVM::ICmpPredicate::ne, op0, zero);
799
839
@@ -1042,6 +1082,21 @@ static mlir::SymbolRefAttr getMalloc(fir::AllocMemOp op,
1042
1082
return getMallocInModule (mod, op, rewriter, indexType);
1043
1083
}
1044
1084
1085
+ // / Helper function for generating the LLVM IR that computes the distance
1086
+ // / in bytes between adjacent elements pointed to by a pointer
1087
+ // / of type \p ptrTy. The result is returned as a value of \p idxTy integer
1088
+ // / type.
1089
+ static mlir::Value
1090
+ computeElementDistance (mlir::Location loc, mlir::Type llvmObjectType,
1091
+ mlir::Type idxTy,
1092
+ mlir::ConversionPatternRewriter &rewriter,
1093
+ const mlir::DataLayout &dataLayout) {
1094
+ llvm::TypeSize size = dataLayout.getTypeSize (llvmObjectType);
1095
+ unsigned short alignment = dataLayout.getTypeABIAlignment (llvmObjectType);
1096
+ std::int64_t distance = llvm::alignTo (size, alignment);
1097
+ return genConstantIndex (loc, idxTy, rewriter, distance);
1098
+ }
1099
+
1045
1100
// / Return value of the stride in bytes between adjacent elements
1046
1101
// / of LLVM type \p llTy. The result is returned as a value of
1047
1102
// / \p idxTy integer type.
@@ -1050,7 +1105,7 @@ genTypeStrideInBytes(mlir::Location loc, mlir::Type idxTy,
1050
1105
mlir::ConversionPatternRewriter &rewriter, mlir::Type llTy,
1051
1106
const mlir::DataLayout &dataLayout) {
1052
1107
// Create a pointer type and use computeElementDistance().
1053
- return fir:: computeElementDistance (loc, llTy, idxTy, rewriter, dataLayout);
1108
+ return computeElementDistance (loc, llTy, idxTy, rewriter, dataLayout);
1054
1109
}
1055
1110
1056
1111
namespace {
@@ -1069,18 +1124,17 @@ struct AllocMemOpConversion : public fir::FIROpConversion<fir::AllocMemOp> {
1069
1124
if (fir::isRecordWithTypeParameters (fir::unwrapSequenceType (dataTy)))
1070
1125
TODO (loc, " fir.allocmem codegen of derived type with length parameters" );
1071
1126
mlir::Value size = genTypeSizeInBytes (loc, ity, rewriter, llvmObjectTy);
1072
- if (auto scaleSize =
1073
- fir::genAllocationScaleSize (loc, heap.getInType (), ity, rewriter))
1074
- size = rewriter.create <mlir::LLVM::MulOp>(loc, ity, size, scaleSize);
1127
+ if (auto scaleSize = genAllocationScaleSize (heap, ity, rewriter))
1128
+ size = mlir::LLVM::MulOp::create (rewriter, loc, ity, size, scaleSize);
1075
1129
for (mlir::Value opnd : adaptor.getOperands ())
1076
1130
size = mlir::LLVM::MulOp::create (rewriter, loc, ity, size,
1077
1131
integerCast (loc, rewriter, ity, opnd));
1078
1132
1079
1133
// As the return value of malloc(0) is implementation defined, allocate one
1080
1134
// byte to ensure the allocation status being true. This behavior aligns to
1081
1135
// what the runtime has.
1082
- mlir::Value zero = fir:: genConstantIndex (loc, ity, rewriter, 0 );
1083
- mlir::Value one = fir:: genConstantIndex (loc, ity, rewriter, 1 );
1136
+ mlir::Value zero = genConstantIndex (loc, ity, rewriter, 0 );
1137
+ mlir::Value one = genConstantIndex (loc, ity, rewriter, 1 );
1084
1138
mlir::Value cmp = mlir::LLVM::ICmpOp::create (
1085
1139
rewriter, loc, mlir::LLVM::ICmpPredicate::sgt, size, zero);
1086
1140
size = mlir::LLVM::SelectOp::create (rewriter, loc, cmp, size, one);
@@ -1103,8 +1157,7 @@ struct AllocMemOpConversion : public fir::FIROpConversion<fir::AllocMemOp> {
1103
1157
mlir::Value genTypeSizeInBytes (mlir::Location loc, mlir::Type idxTy,
1104
1158
mlir::ConversionPatternRewriter &rewriter,
1105
1159
mlir::Type llTy) const {
1106
- return fir::computeElementDistance (loc, llTy, idxTy, rewriter,
1107
- getDataLayout ());
1160
+ return computeElementDistance (loc, llTy, idxTy, rewriter, getDataLayout ());
1108
1161
}
1109
1162
};
1110
1163
} // namespace
@@ -1291,7 +1344,7 @@ genCUFAllocDescriptor(mlir::Location loc,
1291
1344
mlir::Type structTy = typeConverter.convertBoxTypeAsStruct (boxTy);
1292
1345
std::size_t boxSize = dl->getTypeSizeInBits (structTy) / 8 ;
1293
1346
mlir::Value sizeInBytes =
1294
- fir:: genConstantIndex (loc, llvmIntPtrType, rewriter, boxSize);
1347
+ genConstantIndex (loc, llvmIntPtrType, rewriter, boxSize);
1295
1348
llvm::SmallVector args = {sizeInBytes, sourceFile, sourceLine};
1296
1349
return mlir::LLVM::CallOp::create (rewriter, loc, fctTy,
1297
1350
RTNAME_STRING (CUFAllocDescriptor), args)
@@ -1546,7 +1599,7 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
1546
1599
// representation of derived types with pointer/allocatable components.
1547
1600
// This has been seen in hashing algorithms using TRANSFER.
1548
1601
mlir::Value zero =
1549
- fir:: genConstantIndex (loc, rewriter.getI64Type (), rewriter, 0 );
1602
+ genConstantIndex (loc, rewriter.getI64Type (), rewriter, 0 );
1550
1603
descriptor = insertField (rewriter, loc, descriptor,
1551
1604
{getLenParamFieldId (boxTy), 0 }, zero);
1552
1605
}
@@ -1891,8 +1944,8 @@ struct XEmboxOpConversion : public EmboxCommonConversion<fir::cg::XEmboxOp> {
1891
1944
bool hasSlice = !xbox.getSlice ().empty ();
1892
1945
unsigned sliceOffset = xbox.getSliceOperandIndex ();
1893
1946
mlir::Location loc = xbox.getLoc ();
1894
- mlir::Value zero = fir:: genConstantIndex (loc, i64Ty, rewriter, 0 );
1895
- mlir::Value one = fir:: genConstantIndex (loc, i64Ty, rewriter, 1 );
1947
+ mlir::Value zero = genConstantIndex (loc, i64Ty, rewriter, 0 );
1948
+ mlir::Value one = genConstantIndex (loc, i64Ty, rewriter, 1 );
1896
1949
mlir::Value prevPtrOff = one;
1897
1950
mlir::Type eleTy = boxTy.getEleTy ();
1898
1951
const unsigned rank = xbox.getRank ();
@@ -1941,7 +1994,7 @@ struct XEmboxOpConversion : public EmboxCommonConversion<fir::cg::XEmboxOp> {
1941
1994
prevDimByteStride =
1942
1995
getCharacterByteSize (loc, rewriter, charTy, adaptor.getLenParams ());
1943
1996
} else {
1944
- prevDimByteStride = fir:: genConstantIndex (
1997
+ prevDimByteStride = genConstantIndex (
1945
1998
loc, i64Ty, rewriter,
1946
1999
charTy.getLen () * lowerTy ().characterBitsize (charTy) / 8 );
1947
2000
}
@@ -2099,7 +2152,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
2099
2152
if (auto charTy = mlir::dyn_cast<fir::CharacterType>(inputEleTy)) {
2100
2153
if (charTy.hasConstantLen ()) {
2101
2154
mlir::Value len =
2102
- fir:: genConstantIndex (loc, idxTy, rewriter, charTy.getLen ());
2155
+ genConstantIndex (loc, idxTy, rewriter, charTy.getLen ());
2103
2156
lenParams.emplace_back (len);
2104
2157
} else {
2105
2158
mlir::Value len = getElementSizeFromBox (loc, idxTy, inputBoxTyPair,
@@ -2108,7 +2161,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
2108
2161
assert (!isInGlobalOp (rewriter) &&
2109
2162
" character target in global op must have constant length" );
2110
2163
mlir::Value width =
2111
- fir:: genConstantIndex (loc, idxTy, rewriter, charTy.getFKind ());
2164
+ genConstantIndex (loc, idxTy, rewriter, charTy.getFKind ());
2112
2165
len = mlir::LLVM::SDivOp::create (rewriter, loc, idxTy, len, width);
2113
2166
}
2114
2167
lenParams.emplace_back (len);
@@ -2162,9 +2215,8 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
2162
2215
mlir::ConversionPatternRewriter &rewriter) const {
2163
2216
mlir::Location loc = rebox.getLoc ();
2164
2217
mlir::Value zero =
2165
- fir::genConstantIndex (loc, lowerTy ().indexType (), rewriter, 0 );
2166
- mlir::Value one =
2167
- fir::genConstantIndex (loc, lowerTy ().indexType (), rewriter, 1 );
2218
+ genConstantIndex (loc, lowerTy ().indexType (), rewriter, 0 );
2219
+ mlir::Value one = genConstantIndex (loc, lowerTy ().indexType (), rewriter, 1 );
2168
2220
for (auto iter : llvm::enumerate (llvm::zip (extents, strides))) {
2169
2221
mlir::Value extent = std::get<0 >(iter.value ());
2170
2222
unsigned dim = iter.index ();
@@ -2197,7 +2249,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
2197
2249
mlir::Location loc = rebox.getLoc ();
2198
2250
mlir::Type byteTy = ::getI8Type (rebox.getContext ());
2199
2251
mlir::Type idxTy = lowerTy ().indexType ();
2200
- mlir::Value zero = fir:: genConstantIndex (loc, idxTy, rewriter, 0 );
2252
+ mlir::Value zero = genConstantIndex (loc, idxTy, rewriter, 0 );
2201
2253
// Apply subcomponent and substring shift on base address.
2202
2254
if (!rebox.getSubcomponent ().empty () || !rebox.getSubstr ().empty ()) {
2203
2255
// Cast to inputEleTy* so that a GEP can be used.
@@ -2225,7 +2277,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
2225
2277
// and strides.
2226
2278
llvm::SmallVector<mlir::Value> slicedExtents;
2227
2279
llvm::SmallVector<mlir::Value> slicedStrides;
2228
- mlir::Value one = fir:: genConstantIndex (loc, idxTy, rewriter, 1 );
2280
+ mlir::Value one = genConstantIndex (loc, idxTy, rewriter, 1 );
2229
2281
const bool sliceHasOrigins = !rebox.getShift ().empty ();
2230
2282
unsigned sliceOps = rebox.getSliceOperandIndex ();
2231
2283
unsigned shiftOps = rebox.getShiftOperandIndex ();
@@ -2298,7 +2350,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
2298
2350
// which may be OK if all new extents are ones, the stride does not
2299
2351
// matter, use one.
2300
2352
mlir::Value stride = inputStrides.empty ()
2301
- ? fir:: genConstantIndex (loc, idxTy, rewriter, 1 )
2353
+ ? genConstantIndex (loc, idxTy, rewriter, 1 )
2302
2354
: inputStrides[0 ];
2303
2355
for (unsigned i = 0 ; i < rebox.getShape ().size (); ++i) {
2304
2356
mlir::Value rawExtent = operands[rebox.getShapeOperandIndex () + i];
@@ -2533,9 +2585,9 @@ struct XArrayCoorOpConversion
2533
2585
unsigned shiftOffset = coor.getShiftOperandIndex ();
2534
2586
unsigned sliceOffset = coor.getSliceOperandIndex ();
2535
2587
auto sliceOps = coor.getSlice ().begin ();
2536
- mlir::Value one = fir:: genConstantIndex (loc, idxTy, rewriter, 1 );
2588
+ mlir::Value one = genConstantIndex (loc, idxTy, rewriter, 1 );
2537
2589
mlir::Value prevExt = one;
2538
- mlir::Value offset = fir:: genConstantIndex (loc, idxTy, rewriter, 0 );
2590
+ mlir::Value offset = genConstantIndex (loc, idxTy, rewriter, 0 );
2539
2591
const bool isShifted = !coor.getShift ().empty ();
2540
2592
const bool isSliced = !coor.getSlice ().empty ();
2541
2593
const bool baseIsBoxed =
@@ -2866,7 +2918,7 @@ struct CoordinateOpConversion
2866
2918
// of lower bound aspects. This both accounts for dynamically sized
2867
2919
// types and non contiguous arrays.
2868
2920
auto idxTy = lowerTy ().indexType ();
2869
- mlir::Value off = fir:: genConstantIndex (loc, idxTy, rewriter, 0 );
2921
+ mlir::Value off = genConstantIndex (loc, idxTy, rewriter, 0 );
2870
2922
unsigned arrayDim = arrTy.getDimension ();
2871
2923
for (unsigned dim = 0 ; dim < arrayDim && it != end; ++dim, ++it) {
2872
2924
mlir::Value stride =
@@ -3794,7 +3846,7 @@ struct IsPresentOpConversion : public fir::FIROpConversion<fir::IsPresentOp> {
3794
3846
ptr = mlir::LLVM::ExtractValueOp::create (rewriter, loc, ptr, 0 );
3795
3847
}
3796
3848
mlir::LLVM::ConstantOp c0 =
3797
- fir:: genConstantIndex (isPresent.getLoc (), idxTy, rewriter, 0 );
3849
+ genConstantIndex (isPresent.getLoc (), idxTy, rewriter, 0 );
3798
3850
auto addr = mlir::LLVM::PtrToIntOp::create (rewriter, loc, idxTy, ptr);
3799
3851
rewriter.replaceOpWithNewOp <mlir::LLVM::ICmpOp>(
3800
3852
isPresent, mlir::LLVM::ICmpPredicate::ne, addr, c0);
0 commit comments