@@ -1399,16 +1399,15 @@ mlir::Type lowerArrayType(cir::ArrayType type, bool hasValueSemantics,
1399
1399
mlir::TypeConverter prepareTypeConverter (mlir::DataLayout &dataLayout) {
1400
1400
mlir::TypeConverter converter;
1401
1401
converter.addConversion ([&](cir::PointerType type) -> mlir::Type {
1402
- auto pointeeType = type.getPointee ();
1403
- if (mlir::isa<cir::ArrayType>(pointeeType))
1404
- // A pointer to an array gives the array a reference semantics, lower to a
1405
- // memref.
1406
- return lowerArrayType (mlir::cast<cir::ArrayType>(pointeeType),
1407
- /* hasValueSemantics */ false , converter);
1408
- auto ty = convertTypeForMemory (converter, pointeeType);
1409
- // FIXME: The pointee type might not be converted (e.g. struct)
1402
+ auto ty = convertTypeForMemory (
1403
+ converter, type.getPointee ()); // FIXME: The pointee type might not be
1404
+ // converted (e.g. struct)
1410
1405
if (!ty)
1411
1406
return nullptr ;
1407
+ if (isa<cir::ArrayType>(type.getPointee ()))
1408
+ // An array is already lowered as a memref with reference semantics by
1409
+ // default
1410
+ return ty;
1412
1411
// Each level of pointer becomes a level of memref
1413
1412
return mlir::MemRefType::get ({}, ty);
1414
1413
});
@@ -1448,15 +1447,23 @@ mlir::TypeConverter prepareTypeConverter(mlir::DataLayout &dataLayout) {
1448
1447
return mlir::BFloat16Type::get (type.getContext ());
1449
1448
});
1450
1449
converter.addConversion ([&](cir::ArrayType type) -> mlir::Type {
1451
- // Assume we are in a class/struct/union context with value semantics, so
1452
- // lower as a tensor .
1453
- return lowerArrayType (type, /* hasValueSemantics */ true , converter);
1450
+ // Assume we are not in a class/struct/union context with value semantics,
1451
+ // so lower it as a memref to provide reference semantics .
1452
+ return lowerArrayType (type, /* hasValueSemantics */ false , converter);
1454
1453
});
1455
1454
converter.addConversion ([&](cir::VectorType type) -> mlir::Type {
1456
1455
auto ty = converter.convertType (type.getEltType ());
1457
1456
return mlir::VectorType::get (type.getSize (), ty);
1458
1457
});
1459
1458
converter.addConversion ([&](cir::StructType type) -> mlir::Type {
1459
+ auto convertWithValueSemanticsArray = [&](mlir::Type t) {
1460
+ if (mlir::isa<cir::ArrayType>(t))
1461
+ // Inside a class/struct/union, an array has value semantics and is
1462
+ // lowered as a tensor.
1463
+ return lowerArrayType (mlir::cast<cir::ArrayType>(t),
1464
+ /* hasValueSemantics */ true , converter);
1465
+ return converter.convertType (t);
1466
+ };
1460
1467
// FIXME(cir): create separate unions, struct, and classes types.
1461
1468
// Convert struct members.
1462
1469
llvm::SmallVector<mlir::Type> mlirMembers;
@@ -1465,13 +1472,13 @@ mlir::TypeConverter prepareTypeConverter(mlir::DataLayout &dataLayout) {
1465
1472
// TODO(cir): This should be properly validated.
1466
1473
case cir::StructType::Struct:
1467
1474
for (auto ty : type.getMembers ())
1468
- mlirMembers.push_back (converter. convertType (ty));
1475
+ mlirMembers.push_back (convertWithValueSemanticsArray (ty));
1469
1476
break ;
1470
1477
// Unions are lowered as only the largest member.
1471
1478
case cir::StructType::Union: {
1472
1479
auto largestMember = type.getLargestMember (dataLayout);
1473
1480
if (largestMember)
1474
- mlirMembers.push_back (converter. convertType (largestMember));
1481
+ mlirMembers.push_back (convertWithValueSemanticsArray (largestMember));
1475
1482
break ;
1476
1483
}
1477
1484
}
0 commit comments