Skip to content

Commit 07f1502

Browse files
authored
[CIR] Implement SizedTypeInterface to make isSized hookable (#146045)
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. This mirrors incubator changes from llvm/clangir#1714
1 parent 61c0a94 commit 07f1502

File tree

6 files changed

+92
-41
lines changed

6 files changed

+92
-41
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ struct RecordTypeStorage;
2626

2727
bool isValidFundamentalIntWidth(unsigned width);
2828

29+
/// Returns true if the type is a CIR sized type.
30+
///
31+
/// Types are sized if they implement SizedTypeInterface and
32+
/// return true from its method isSized.
33+
///
34+
/// Unsized types are those that do not have a size, such as
35+
/// void, or abstract types.
36+
bool isSized(mlir::Type ty);
37+
2938
} // namespace cir
3039

3140
//===----------------------------------------------------------------------===//

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

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ class CIR_Type<string name, string typeMnemonic, list<Trait> traits = [],
3333
// IntType
3434
//===----------------------------------------------------------------------===//
3535

36-
def CIR_IntType : CIR_Type<"Int", "int",
37-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
36+
def CIR_IntType : CIR_Type<"Int", "int", [
37+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
38+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
39+
]> {
3840
let summary = "Integer type with arbitrary precision up to a fixed limit";
3941
let description = [{
4042
CIR type that represents integer types with arbitrary precision, including
@@ -82,7 +84,8 @@ def CIR_IntType : CIR_Type<"Int", "int",
8284

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

8891
def CIR_Single : CIR_FloatType<"Single", "float"> {
@@ -165,9 +168,10 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {
165168
// ComplexType
166169
//===----------------------------------------------------------------------===//
167170

168-
def CIR_ComplexType : CIR_Type<"Complex", "complex",
169-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
170-
171+
def CIR_ComplexType : CIR_Type<"Complex", "complex", [
172+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
173+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
174+
]> {
171175
let summary = "CIR complex type";
172176
let description = [{
173177
CIR type that represents a C complex number. `cir.complex` models the C type
@@ -215,12 +219,13 @@ def CIR_ComplexType : CIR_Type<"Complex", "complex",
215219
// PointerType
216220
//===----------------------------------------------------------------------===//
217221

218-
def CIR_PointerType : CIR_Type<"Pointer", "ptr",
219-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
220-
222+
def CIR_PointerType : CIR_Type<"Pointer", "ptr", [
223+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
224+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
225+
]> {
221226
let summary = "CIR pointer type";
222227
let description = [{
223-
The `cir.ptr` type represents C and C++ pointer types and C++ reference
228+
The `!cir.ptr` type represents C and C++ pointer types and C++ reference
224229
types, other than pointers-to-members. The `pointee` type is the type
225230
pointed to.
226231

@@ -279,26 +284,27 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr",
279284
// BoolType
280285
//===----------------------------------------------------------------------===//
281286

282-
def CIR_BoolType :
283-
CIR_Type<"Bool", "bool",
284-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
285-
287+
def CIR_BoolType : CIR_Type<"Bool", "bool", [
288+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
289+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
290+
]> {
286291
let summary = "CIR bool type";
287292
let description = [{
288-
`cir.bool` represents C++ bool type.
293+
`!cir.bool` represents C++ bool type.
289294
}];
290295
}
291296

292297
//===----------------------------------------------------------------------===//
293298
// ArrayType
294299
//===----------------------------------------------------------------------===//
295300

296-
def CIR_ArrayType : CIR_Type<"Array", "array",
297-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
298-
301+
def CIR_ArrayType : CIR_Type<"Array", "array", [
302+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
303+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface, ["isSized"]>,
304+
]> {
299305
let summary = "CIR array type";
300306
let description = [{
301-
`CIR.array` represents C/C++ constant arrays.
307+
`!cir.array` represents C/C++ constant arrays.
302308
}];
303309

304310
let parameters = (ins "mlir::Type":$elementType, "uint64_t":$size);
@@ -314,15 +320,22 @@ def CIR_ArrayType : CIR_Type<"Array", "array",
314320
let assemblyFormat = [{
315321
`<` $elementType `x` $size `>`
316322
}];
323+
324+
let extraClassDefinition = [{
325+
bool $cppClass::isSized() const {
326+
return ::cir::isSized(getElementType());
327+
}
328+
}];
317329
}
318330

319331
//===----------------------------------------------------------------------===//
320332
// VectorType (fixed size)
321333
//===----------------------------------------------------------------------===//
322334

323-
def CIR_VectorType : CIR_Type<"Vector", "vector",
324-
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
325-
335+
def CIR_VectorType : CIR_Type<"Vector", "vector", [
336+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
337+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface, ["isSized"]>,
338+
]> {
326339
let summary = "CIR vector type";
327340
let description = [{
328341
The `!cir.vector` type represents a fixed-size, one-dimensional vector.
@@ -363,6 +376,12 @@ def CIR_VectorType : CIR_Type<"Vector", "vector",
363376
}]>,
364377
];
365378

379+
let extraClassDefinition = [{
380+
bool $cppClass::isSized() const {
381+
return ::cir::isSized(getElementType());
382+
}
383+
}];
384+
366385
let genVerifyDecl = 1;
367386
}
368387

@@ -459,11 +478,11 @@ def CIR_VoidType : CIR_Type<"Void", "void"> {
459478
// The base type for all RecordDecls.
460479
//===----------------------------------------------------------------------===//
461480

462-
def CIR_RecordType : CIR_Type<"Record", "record",
463-
[
464-
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
465-
MutableType,
466-
]> {
481+
def CIR_RecordType : CIR_Type<"Record", "record", [
482+
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
483+
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>,
484+
MutableType,
485+
]> {
467486
let summary = "CIR record type";
468487
let description = [{
469488
Each unique clang::RecordDecl is mapped to a `cir.record` and any object in

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,29 @@ 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+
let cppNamespace = "::cir";
62+
let methods = [
63+
InterfaceMethod<[{
64+
Returns true if this is a sized type. This mirrors sizedness from the
65+
clang AST, where a type is sized if it has a known size.
66+
By default type defining this interface returns true,
67+
but this can be overridden if sizedness depends on properties of the type.
68+
For example, whether a struct is not sized if it is incomplete.
69+
}],
70+
/*retTy=*/"bool",
71+
/*methodName=*/"isSized",
72+
/*args=*/(ins),
73+
/*methodBody=*/"",
74+
/*defaultImplementation=*/[{
75+
return true;
76+
}]
77+
>,
78+
];
79+
}
80+
5681
#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
@@ -139,18 +139,6 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
139139
return getType<cir::RecordType>(nameAttr, kind);
140140
}
141141

142-
bool isSized(mlir::Type ty) {
143-
if (mlir::isa<cir::PointerType, cir::ArrayType, cir::BoolType, cir::IntType,
144-
cir::FPTypeInterface, cir::ComplexType, cir::RecordType>(ty))
145-
return true;
146-
147-
if (const auto vt = mlir::dyn_cast<cir::VectorType>(ty))
148-
return isSized(vt.getElementType());
149-
150-
assert(!cir::MissingFeatures::unsizedTypes());
151-
return false;
152-
}
153-
154142
// Return true if the value is a null constant such as null pointer, (+0.0)
155143
// for floating-point or zero initializer
156144
bool isNullValue(mlir::Attribute attr) const {

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
424424
mlir::Type elemTy = convertTypeForMem(arrTy->getElementType());
425425
// int X[] -> [0 x int], unless the element type is not sized. If it is
426426
// unsized (e.g. an incomplete record) just use [0 x i8].
427-
if (!builder.isSized(elemTy)) {
427+
if (!cir::isSized(elemTy)) {
428428
elemTy = cgm.SInt8Ty;
429429
}
430430

@@ -438,7 +438,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
438438

439439
// TODO(CIR): In LLVM, "lower arrays of undefined struct type to arrays of
440440
// i8 just to have a concrete type"
441-
if (!builder.isSized(elemTy)) {
441+
if (!cir::isSized(elemTy)) {
442442
cgm.errorNYI(SourceLocation(), "arrays of undefined struct type", type);
443443
resultType = cgm.UInt32Ty;
444444
break;

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@
1818
#include "clang/CIR/MissingFeatures.h"
1919
#include "llvm/ADT/TypeSwitch.h"
2020

21+
//===----------------------------------------------------------------------===//
22+
// CIR Helpers
23+
//===----------------------------------------------------------------------===//
24+
bool cir::isSized(mlir::Type ty) {
25+
if (auto sizedTy = mlir::dyn_cast<cir::SizedTypeInterface>(ty))
26+
return sizedTy.isSized();
27+
assert(!cir::MissingFeatures::unsizedTypes());
28+
return false;
29+
}
30+
2131
//===----------------------------------------------------------------------===//
2232
// CIR Custom Parser/Printer Signatures
2333
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)