-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[CIR] Implement SizedTypeInterface to make isSized hookable #146045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-clangir @llvm/pr-subscribers-clang Author: Henrich Lauko (xlauko) ChangesResolves 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 Full diff: https://github.com/llvm/llvm-project/pull/146045.diff 6 Files Affected:
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
index 620c72ef9023e..7f9fb9ef388b3 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
@@ -26,6 +26,15 @@ struct RecordTypeStorage;
bool isValidFundamentalIntWidth(unsigned width);
+/// Returns true if the type is a CIR sized type.
+///
+/// Types are sized if they implement SizedTypeInterface and
+/// return true from its method isSized.
+///
+/// Unsized types are those that do not have a size, such as
+/// void, or abstract types.
+bool isSized(mlir::Type ty);
+
} // namespace cir
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index 75c42a08c185f..bfe42562abad7 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -33,8 +33,10 @@ class CIR_Type<string name, string typeMnemonic, list<Trait> traits = [],
// IntType
//===----------------------------------------------------------------------===//
-def CIR_IntType : CIR_Type<"Int", "int",
- [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
+def CIR_IntType : CIR_Type<"Int", "int", [
+ DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
+ DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
+]> {
let summary = "Integer type with arbitrary precision up to a fixed limit";
let description = [{
CIR type that represents integer types with arbitrary precision, including
@@ -82,7 +84,8 @@ def CIR_IntType : CIR_Type<"Int", "int",
class CIR_FloatType<string name, string mnemonic> : CIR_Type<name, mnemonic, [
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
- DeclareTypeInterfaceMethods<CIR_FPTypeInterface>
+ DeclareTypeInterfaceMethods<CIR_FPTypeInterface>,
+ DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
]>;
def CIR_Single : CIR_FloatType<"Single", "float"> {
@@ -165,9 +168,10 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {
// ComplexType
//===----------------------------------------------------------------------===//
-def CIR_ComplexType : CIR_Type<"Complex", "complex",
- [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
-
+def CIR_ComplexType : CIR_Type<"Complex", "complex", [
+ DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
+ DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
+]> {
let summary = "CIR complex type";
let description = [{
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",
// PointerType
//===----------------------------------------------------------------------===//
-def CIR_PointerType : CIR_Type<"Pointer", "ptr",
- [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
-
+def CIR_PointerType : CIR_Type<"Pointer", "ptr", [
+ DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
+ DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
+]> {
let summary = "CIR pointer type";
let description = [{
- The `cir.ptr` type represents C and C++ pointer types and C++ reference
+ The `!cir.ptr` type represents C and C++ pointer types and C++ reference
types, other than pointers-to-members. The `pointee` type is the type
pointed to.
@@ -279,13 +284,13 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr",
// BoolType
//===----------------------------------------------------------------------===//
-def CIR_BoolType :
- CIR_Type<"Bool", "bool",
- [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
-
+def CIR_BoolType : CIR_Type<"Bool", "bool", [
+ DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
+ DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
+]> {
let summary = "CIR bool type";
let description = [{
- `cir.bool` represents C++ bool type.
+ `!cir.bool` represents C++ bool type.
}];
}
@@ -293,12 +298,13 @@ def CIR_BoolType :
// ArrayType
//===----------------------------------------------------------------------===//
-def CIR_ArrayType : CIR_Type<"Array", "array",
- [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
-
+def CIR_ArrayType : CIR_Type<"Array", "array", [
+ DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
+ DeclareTypeInterfaceMethods<CIR_SizedTypeInterface, ["isSized"]>,
+]> {
let summary = "CIR array type";
let description = [{
- `CIR.array` represents C/C++ constant arrays.
+ `!cir.array` represents C/C++ constant arrays.
}];
let parameters = (ins "mlir::Type":$elementType, "uint64_t":$size);
@@ -314,15 +320,22 @@ def CIR_ArrayType : CIR_Type<"Array", "array",
let assemblyFormat = [{
`<` $elementType `x` $size `>`
}];
+
+ let extraClassDefinition = [{
+ bool $cppClass::isSized() const {
+ return ::cir::isSized(getElementType());
+ }
+ }];
}
//===----------------------------------------------------------------------===//
// VectorType (fixed size)
//===----------------------------------------------------------------------===//
-def CIR_VectorType : CIR_Type<"Vector", "vector",
- [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
-
+def CIR_VectorType : CIR_Type<"Vector", "vector", [
+ DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
+ DeclareTypeInterfaceMethods<CIR_SizedTypeInterface, ["isSized"]>,
+]> {
let summary = "CIR vector type";
let description = [{
The `!cir.vector` type represents a fixed-size, one-dimensional vector.
@@ -363,6 +376,12 @@ def CIR_VectorType : CIR_Type<"Vector", "vector",
}]>,
];
+ let extraClassDefinition = [{
+ bool $cppClass::isSized() const {
+ return ::cir::isSized(getElementType());
+ }
+ }];
+
let genVerifyDecl = 1;
}
@@ -459,11 +478,11 @@ def CIR_VoidType : CIR_Type<"Void", "void"> {
// The base type for all RecordDecls.
//===----------------------------------------------------------------------===//
-def CIR_RecordType : CIR_Type<"Record", "record",
- [
- DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
- MutableType,
- ]> {
+def CIR_RecordType : CIR_Type<"Record", "record", [
+ DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
+ DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>,
+ MutableType,
+]> {
let summary = "CIR record type";
let description = [{
Each unique clang::RecordDecl is mapped to a `cir.record` and any object in
diff --git a/clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td b/clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td
index 84147478f8030..1b1acf749e773 100644
--- a/clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td
+++ b/clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td
@@ -53,4 +53,29 @@ def CIR_FPTypeInterface : TypeInterface<"FPTypeInterface"> {
];
}
+def CIR_SizedTypeInterface : TypeInterface<"SizedTypeInterface"> {
+ let description = [{
+ Annotates types that have known size. Types that don't have a size are
+ abstract types and void.
+ }];
+ let cppNamespace = "::cir";
+ let methods = [
+ InterfaceMethod<[{
+ Returns true if this is a sized type. This mirrors sizedness from the
+ clang AST, where a type is sized if it has a known size.
+ By default type defining this interface returns true,
+ but this can be overridden if sizedness depends on properties of the type.
+ For example, whether a struct is not sized if it is incomplete.
+ }],
+ /*retTy=*/"bool",
+ /*methodName=*/"isSized",
+ /*args=*/(ins),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ return true;
+ }]
+ >,
+ ];
+}
+
#endif // CLANG_CIR_INTERFACES_CIRTYPEINTERFACES_TD
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index e316c39b98919..17b931a0693aa 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -139,18 +139,6 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
return getType<cir::RecordType>(nameAttr, kind);
}
- bool isSized(mlir::Type ty) {
- if (mlir::isa<cir::PointerType, cir::ArrayType, cir::BoolType, cir::IntType,
- cir::FPTypeInterface, cir::ComplexType, cir::RecordType>(ty))
- return true;
-
- if (const auto vt = mlir::dyn_cast<cir::VectorType>(ty))
- return isSized(vt.getElementType());
-
- assert(!cir::MissingFeatures::unsizedTypes());
- return false;
- }
-
// Return true if the value is a null constant such as null pointer, (+0.0)
// for floating-point or zero initializer
bool isNullValue(mlir::Attribute attr) const {
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 621eb66962bfb..3e07f6d3e54cc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -424,7 +424,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
mlir::Type elemTy = convertTypeForMem(arrTy->getElementType());
// int X[] -> [0 x int], unless the element type is not sized. If it is
// unsized (e.g. an incomplete record) just use [0 x i8].
- if (!builder.isSized(elemTy)) {
+ if (!cir::isSized(elemTy)) {
elemTy = cgm.SInt8Ty;
}
@@ -438,7 +438,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
// TODO(CIR): In LLVM, "lower arrays of undefined struct type to arrays of
// i8 just to have a concrete type"
- if (!builder.isSized(elemTy)) {
+ if (!cir::isSized(elemTy)) {
cgm.errorNYI(SourceLocation(), "arrays of undefined struct type", type);
resultType = cgm.UInt32Ty;
break;
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index 1db5a9728fdb9..c6760cf1618cb 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -18,6 +18,16 @@
#include "clang/CIR/MissingFeatures.h"
#include "llvm/ADT/TypeSwitch.h"
+//===----------------------------------------------------------------------===//
+// CIR Helpers
+//===----------------------------------------------------------------------===//
+bool cir::isSized(mlir::Type ty) {
+ if (auto sizedTy = mlir::dyn_cast<cir::SizedTypeInterface>(ty))
+ return sizedTy.isSized();
+ assert(!cir::MissingFeatures::unsizedTypes());
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// CIR Custom Parser/Printer Signatures
//===----------------------------------------------------------------------===//
|
7d2e8b3
to
a56f531
Compare
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
586f2cc
to
1f65dd5
Compare
) 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
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