@@ -1272,42 +1272,119 @@ struct EmboxCommonConversion : public FIROpConversion<OP> {
1272
1272
mlir::Location loc, mlir::ConversionPatternRewriter &rewriter,
1273
1273
mlir::Type boxEleTy, mlir::ValueRange lenParams = {}) const {
1274
1274
auto i64Ty = mlir::IntegerType::get (rewriter.getContext (), 64 );
1275
- if (auto eleTy = fir::dyn_cast_ptrEleTy (boxEleTy))
1276
- boxEleTy = eleTy;
1277
- if (auto seqTy = boxEleTy.dyn_cast <fir::SequenceType>())
1278
- return getSizeAndTypeCode (loc, rewriter, seqTy.getEleTy (), lenParams);
1279
- if (boxEleTy.isa <mlir::NoneType>()) // unlimited polymorphic or assumed type
1280
- return {rewriter.create <mlir::LLVM::ConstantOp>(loc, i64Ty, 0 ),
1281
- this ->genConstantOffset (loc, rewriter, CFI_type_other)};
1282
- mlir::Value typeCodeVal = this ->genConstantOffset (
1283
- loc, rewriter,
1284
- fir::getTypeCode (boxEleTy, this ->lowerTy ().getKindMap ()));
1285
- if (fir::isa_integer (boxEleTy) || boxEleTy.dyn_cast <fir::LogicalType>() ||
1286
- fir::isa_real (boxEleTy) || fir::isa_complex (boxEleTy))
1287
- return {genTypeStrideInBytes (loc, i64Ty, rewriter,
1288
- this ->convertType (boxEleTy)),
1289
- typeCodeVal};
1290
- if (auto charTy = boxEleTy.dyn_cast <fir::CharacterType>()) {
1291
- mlir::Value size =
1292
- genTypeStrideInBytes (loc, i64Ty, rewriter, this ->convertType (charTy));
1293
- if (charTy.getLen () == fir::CharacterType::unknownLen ()) {
1294
- // Multiply the single character size by the length.
1275
+ auto getKindMap = [&]() -> fir::KindMapping & {
1276
+ return this ->lowerTy ().getKindMap ();
1277
+ };
1278
+ auto doInteger =
1279
+ [&](mlir::Type type,
1280
+ unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
1281
+ int typeCode = fir::integerBitsToTypeCode (width);
1282
+ return {
1283
+ genTypeStrideInBytes (loc, i64Ty, rewriter, this ->convertType (type)),
1284
+ this ->genConstantOffset (loc, rewriter, typeCode)};
1285
+ };
1286
+ auto doLogical =
1287
+ [&](mlir::Type type,
1288
+ unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
1289
+ int typeCode = fir::logicalBitsToTypeCode (width);
1290
+ return {
1291
+ genTypeStrideInBytes (loc, i64Ty, rewriter, this ->convertType (type)),
1292
+ this ->genConstantOffset (loc, rewriter, typeCode)};
1293
+ };
1294
+ auto doFloat = [&](mlir::Type type,
1295
+ unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
1296
+ int typeCode = fir::realBitsToTypeCode (width);
1297
+ return {
1298
+ genTypeStrideInBytes (loc, i64Ty, rewriter, this ->convertType (type)),
1299
+ this ->genConstantOffset (loc, rewriter, typeCode)};
1300
+ };
1301
+ auto doComplex =
1302
+ [&](mlir::Type type,
1303
+ unsigned width) -> std::tuple<mlir::Value, mlir::Value> {
1304
+ auto typeCode = fir::complexBitsToTypeCode (width);
1305
+ return {
1306
+ genTypeStrideInBytes (loc, i64Ty, rewriter, this ->convertType (type)),
1307
+ this ->genConstantOffset (loc, rewriter, typeCode)};
1308
+ };
1309
+ auto doCharacter = [&](fir::CharacterType type, mlir::ValueRange lenParams)
1310
+ -> std::tuple<mlir::Value, mlir::Value> {
1311
+ unsigned bitWidth = getKindMap ().getCharacterBitsize (type.getFKind ());
1312
+ auto typeCode = fir::characterBitsToTypeCode (bitWidth);
1313
+ auto typeCodeVal = this ->genConstantOffset (loc, rewriter, typeCode);
1314
+
1315
+ bool lengthIsConst = (type.getLen () != fir::CharacterType::unknownLen ());
1316
+ mlir::Value eleSize =
1317
+ genTypeStrideInBytes (loc, i64Ty, rewriter, this ->convertType (type));
1318
+
1319
+ if (!lengthIsConst) {
1320
+ // If length is constant, then the fir::CharacterType will be
1321
+ // represented as an array of known size of elements having
1322
+ // the corresponding LLVM type. In this case eleSize already
1323
+ // holds correct memory size. If length is not constant, then
1324
+ // the fir::CharacterType will decay to a scalar type,
1325
+ // so we have to multiply it by the non-constant length
1326
+ // to get its size in memory.
1295
1327
assert (!lenParams.empty ());
1296
1328
auto len64 = FIROpConversion<OP>::integerCast (loc, rewriter, i64Ty,
1297
1329
lenParams.back ());
1298
- size = rewriter.create <mlir::LLVM::MulOp>(loc, i64Ty, size, len64);
1330
+ eleSize =
1331
+ rewriter.create <mlir::LLVM::MulOp>(loc, i64Ty, eleSize, len64);
1299
1332
}
1300
- return {size , typeCodeVal};
1333
+ return {eleSize , typeCodeVal};
1301
1334
};
1335
+ // Pointer-like types.
1336
+ if (auto eleTy = fir::dyn_cast_ptrEleTy (boxEleTy))
1337
+ boxEleTy = eleTy;
1338
+ // Integer types.
1339
+ if (fir::isa_integer (boxEleTy)) {
1340
+ if (auto ty = boxEleTy.dyn_cast <mlir::IntegerType>())
1341
+ return doInteger (ty, ty.getWidth ());
1342
+ auto ty = boxEleTy.cast <fir::IntegerType>();
1343
+ return doInteger (ty, getKindMap ().getIntegerBitsize (ty.getFKind ()));
1344
+ }
1345
+ // Floating point types.
1346
+ if (fir::isa_real (boxEleTy)) {
1347
+ if (auto ty = boxEleTy.dyn_cast <mlir::FloatType>())
1348
+ return doFloat (ty, ty.getWidth ());
1349
+ auto ty = boxEleTy.cast <fir::RealType>();
1350
+ return doFloat (ty, getKindMap ().getRealBitsize (ty.getFKind ()));
1351
+ }
1352
+ // Complex types.
1353
+ if (fir::isa_complex (boxEleTy)) {
1354
+ if (auto ty = boxEleTy.dyn_cast <mlir::ComplexType>())
1355
+ return doComplex (
1356
+ ty, ty.getElementType ().cast <mlir::FloatType>().getWidth ());
1357
+ auto ty = boxEleTy.cast <fir::ComplexType>();
1358
+ return doComplex (ty, getKindMap ().getRealBitsize (ty.getFKind ()));
1359
+ }
1360
+ // Character types.
1361
+ if (auto ty = boxEleTy.dyn_cast <fir::CharacterType>())
1362
+ return doCharacter (ty, lenParams);
1363
+ // Logical type.
1364
+ if (auto ty = boxEleTy.dyn_cast <fir::LogicalType>())
1365
+ return doLogical (ty, getKindMap ().getLogicalBitsize (ty.getFKind ()));
1366
+ // Array types.
1367
+ if (auto seqTy = boxEleTy.dyn_cast <fir::SequenceType>())
1368
+ return getSizeAndTypeCode (loc, rewriter, seqTy.getEleTy (), lenParams);
1369
+ // Derived-type types.
1370
+ if (boxEleTy.isa <fir::RecordType>()) {
1371
+ auto eleSize = genTypeStrideInBytes (loc, i64Ty, rewriter,
1372
+ this ->convertType (boxEleTy));
1373
+ return {eleSize,
1374
+ this ->genConstantOffset (loc, rewriter, fir::derivedToTypeCode ())};
1375
+ }
1376
+ // Reference type.
1302
1377
if (fir::isa_ref_type (boxEleTy)) {
1303
1378
auto ptrTy = mlir::LLVM::LLVMPointerType::get (
1304
1379
mlir::LLVM::LLVMVoidType::get (rewriter.getContext ()));
1305
- return {genTypeStrideInBytes (loc, i64Ty, rewriter, ptrTy), typeCodeVal};
1380
+ mlir::Value size = genTypeStrideInBytes (loc, i64Ty, rewriter, ptrTy);
1381
+ return {size, this ->genConstantOffset (loc, rewriter, CFI_type_cptr)};
1306
1382
}
1307
- if (boxEleTy.isa <fir::RecordType>())
1308
- return {genTypeStrideInBytes (loc, i64Ty, rewriter,
1309
- this ->convertType (boxEleTy)),
1310
- typeCodeVal};
1383
+ // Unlimited polymorphic or assumed type. Use 0 and CFI_type_other since the
1384
+ // information is not none at this point.
1385
+ if (boxEleTy.isa <mlir::NoneType>())
1386
+ return {rewriter.create <mlir::LLVM::ConstantOp>(loc, i64Ty, 0 ),
1387
+ this ->genConstantOffset (loc, rewriter, CFI_type_other)};
1311
1388
fir::emitFatalError (loc, " unhandled type in fir.box code generation" );
1312
1389
}
1313
1390
0 commit comments