Skip to content

Commit 30718ac

Browse files
authored
[CIR] Implement SizedTypeInterface to make isSized hookable. (#1714)
This resolves issues pointed out in https://github.com/llvm/llvm-project/pull/143960/files#r2164047625 of needing to update sized list of types on each new type.
1 parent b22961d commit 30718ac

File tree

6 files changed

+89
-37
lines changed

6 files changed

+89
-37
lines changed

clang/include/clang/CIR/Dialect/IR/CIRTypes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ struct RecordTypeStorage;
2727

2828
bool isValidFundamentalIntWidth(unsigned width);
2929

30+
// Returns true if the type is a CIR sized type.
31+
bool isSized(mlir::Type ty);
32+
3033
} // namespace cir
3134

3235
mlir::ParseResult parseAddrSpaceAttribute(mlir::AsmParser &p,

clang/include/clang/CIR/Dialect/IR/CIRTypes.td

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ class CIR_Type<string name, string typeMnemonic, list<Trait> traits = [],
3535
// IntType
3636
//===----------------------------------------------------------------------===//
3737

38-
def CIR_IntType : CIR_Type<"Int", "int",
39-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
38+
def CIR_IntType : CIR_Type<"Int", "int", [
39+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
40+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>,
41+
]> {
4042
let summary = "Integer type with arbitrary precision up to a fixed limit";
4143
let description = [{
4244
CIR type that represents integer types with arbitrary precision.
@@ -81,8 +83,9 @@ def CIR_IntType : CIR_Type<"Int", "int",
8183
//===----------------------------------------------------------------------===//
8284

8385
class CIR_FloatType<string name, string mnemonic> : CIR_Type<name, mnemonic, [
84-
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
85-
DeclareTypeInterfaceMethods<CIR_FPTypeInterface>
86+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
87+
DeclareTypeInterfaceMethods<CIR_FPTypeInterface>,
88+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
8689
]>;
8790

8891
def CIR_Single : CIR_FloatType<"Single", "float"> {
@@ -151,9 +154,10 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {
151154
// ComplexType
152155
//===----------------------------------------------------------------------===//
153156

154-
def CIR_ComplexType : CIR_Type<"Complex", "complex",
155-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
156-
157+
def CIR_ComplexType : CIR_Type<"Complex", "complex", [
158+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
159+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
160+
]> {
157161
let summary = "CIR complex type";
158162
let description = [{
159163
CIR type that represents a C complex number. `cir.complex` models the C type
@@ -194,9 +198,10 @@ def CIR_ComplexType : CIR_Type<"Complex", "complex",
194198
// PointerType
195199
//===----------------------------------------------------------------------===//
196200

197-
def CIR_PointerType : CIR_Type<"Pointer", "ptr",
198-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
199-
201+
def CIR_PointerType : CIR_Type<"Pointer", "ptr", [
202+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
203+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
204+
]> {
200205
let summary = "CIR pointer type";
201206
let description = [{
202207
`CIR.ptr` is a type returned by any op generating a pointer in C++.
@@ -295,9 +300,10 @@ def CIR_DataMemberType : CIR_Type<"DataMember", "data_member",
295300
// BoolType
296301
//===----------------------------------------------------------------------===//
297302

298-
def CIR_BoolType : CIR_Type<"Bool", "bool",
299-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
300-
303+
def CIR_BoolType : CIR_Type<"Bool", "bool", [
304+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
305+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
306+
]> {
301307
let summary = "CIR bool type";
302308
let description = [{
303309
`cir.bool` represent's C++ bool type.
@@ -308,9 +314,10 @@ def CIR_BoolType : CIR_Type<"Bool", "bool",
308314
// ArrayType
309315
//===----------------------------------------------------------------------===//
310316

311-
def CIR_ArrayType : CIR_Type<"Array", "array",
312-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
313-
317+
def CIR_ArrayType : CIR_Type<"Array", "array", [
318+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
319+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface, ["isSized"]>,
320+
]> {
314321
let summary = "CIR array type";
315322
let description = [{
316323
`CIR.array` represents C/C++ constant arrays.
@@ -329,14 +336,22 @@ def CIR_ArrayType : CIR_Type<"Array", "array",
329336
let assemblyFormat = [{
330337
`<` $elementType `x` $size `>`
331338
}];
339+
340+
let extraClassDefinition = [{
341+
bool $cppClass::isSized() const {
342+
return ::cir::isSized(getElementType());
343+
}
344+
}];
332345
}
333346

334347
//===----------------------------------------------------------------------===//
335348
// VectorType (fixed size)
336349
//===----------------------------------------------------------------------===//
337350

338-
def CIR_VectorType : CIR_Type<"Vector", "vector",
339-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
351+
def CIR_VectorType : CIR_Type<"Vector", "vector", [
352+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
353+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface, ["isSized"]>,
354+
]> {
340355

341356
let summary = "CIR vector type";
342357
let description = [{
@@ -378,6 +393,12 @@ def CIR_VectorType : CIR_Type<"Vector", "vector",
378393
`<` $elementType `x` $size `>`
379394
}];
380395

396+
let extraClassDefinition = [{
397+
bool $cppClass::isSized() const {
398+
return ::cir::isSized(getElementType());
399+
}
400+
}];
401+
381402
let genVerifyDecl = 1;
382403
}
383404

@@ -524,11 +545,11 @@ def CIR_VoidType : CIR_Type<"Void", "void"> {
524545
// The base type for all RecordDecls.
525546
//===----------------------------------------------------------------------===//
526547

527-
def CIR_RecordType : CIR_Type<"Record", "record",
528-
[
529-
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
530-
MutableType,
531-
]> {
548+
def CIR_RecordType : CIR_Type<"Record", "record", [
549+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
550+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>,
551+
MutableType,
552+
]> {
532553
let summary = "CIR record type";
533554
let description = [{
534555
Each unique clang::RecordDecl is mapped to a `cir.record` and any object in

clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,32 @@ def CIR_FPTypeInterface : TypeInterface<"FPTypeInterface"> {
5353
];
5454
}
5555

56+
def CIR_SizedTypeInterface : TypeInterface<"SizedTypeInterface"> {
57+
let description = [{
58+
Annotates types that have known size. Types that don't have a size are
59+
abstract types and void.
60+
}];
61+
62+
let cppNamespace = "::cir";
63+
64+
let methods = [
65+
InterfaceMethod<[{
66+
Returns true if this is a sized type. This mirrors sizedness from the
67+
clang AST, where a type is sized if it has a known size.
68+
69+
By default type defining this interface returns true,
70+
but this can be overridden if sizedness depends on properties of the type.
71+
For example, whether a struct is not sized if it is incomplete.
72+
}],
73+
/*retTy=*/"bool",
74+
/*methodName=*/"isSized",
75+
/*args=*/(ins),
76+
/*methodBody=*/"",
77+
/*defaultImplementation=*/[{
78+
return true;
79+
}]
80+
>,
81+
];
82+
}
83+
5684
#endif // CLANG_CIR_INTERFACES_CIRTYPEINTERFACES_TD

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -527,18 +527,6 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
527527
return getCompleteRecordTy(members, name, packed, padded, ast);
528528
}
529529

530-
bool isSized(mlir::Type ty) {
531-
if (mlir::isa<cir::PointerType, cir::RecordType, cir::ArrayType,
532-
cir::BoolType, cir::IntType, cir::FPTypeInterface,
533-
cir::ComplexType>(ty))
534-
return true;
535-
if (mlir::isa<cir::VectorType>(ty)) {
536-
return isSized(mlir::cast<cir::VectorType>(ty).getElementType());
537-
}
538-
assert(0 && "Unimplemented size for type");
539-
return false;
540-
}
541-
542530
//
543531
// Constant creation helpers
544532
// -------------------------

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ mlir::Type CIRGenTypes::convertType(QualType T) {
646646
// int X[] -> [0 x int], unless the element type is not sized. If it is
647647
// unsized (e.g. an incomplete record) just use [0 x i8].
648648
ResultType = convertTypeForMem(A->getElementType());
649-
if (!Builder.isSized(ResultType)) {
649+
if (!cir::isSized(ResultType)) {
650650
SkippedLayout = true;
651651
ResultType = Builder.getUInt8Ty();
652652
}
@@ -659,7 +659,7 @@ mlir::Type CIRGenTypes::convertType(QualType T) {
659659

660660
// FIXME: In LLVM, "lower arrays of undefined struct type to arrays of
661661
// i8 just to have a concrete type". Not sure this makes sense in CIR yet.
662-
assert(Builder.isSized(EltTy) && "not implemented");
662+
assert(cir::isSized(EltTy) && "not implemented");
663663
ResultType = cir::ArrayType::get(EltTy, A->getSize().getZExtValue());
664664
break;
665665
}

clang/lib/CIR/Dialect/IR/CIRTypes.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@
3838

3939
using cir::MissingFeatures;
4040

41+
//===----------------------------------------------------------------------===//
42+
// CIR Helpers
43+
//===----------------------------------------------------------------------===//
44+
45+
bool cir::isSized(mlir::Type ty) {
46+
if (auto sizedTy = mlir::dyn_cast<cir::SizedTypeInterface>(ty))
47+
return sizedTy.isSized();
48+
// TODO: Remove this once all sized types are annotated.
49+
assert(0 && "Unimplemented size for type");
50+
return false;
51+
}
52+
4153
//===----------------------------------------------------------------------===//
4254
// CIR Custom Parser/Printer Signatures
4355
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)