|
16 | 16 | #include "mlir/IR/BuiltinAttributes.h"
|
17 | 17 | #include "mlir/IR/Types.h"
|
18 | 18 | #include "mlir/Interfaces/DataLayoutInterfaces.h"
|
19 |
| -#include "clang/CIR/Interfaces/CIRFPTypeInterface.h" |
20 |
| - |
21 |
| -#include "clang/CIR/Interfaces/ASTAttrInterfaces.h" |
22 |
| - |
23 | 19 | #include "clang/CIR/Dialect/IR/CIROpsEnums.h"
|
24 |
| - |
25 |
| -//===----------------------------------------------------------------------===// |
26 |
| -// CIR StructType |
27 |
| -// |
28 |
| -// The base type for all RecordDecls. |
29 |
| -//===----------------------------------------------------------------------===// |
| 20 | +#include "clang/CIR/Interfaces/ASTAttrInterfaces.h" |
| 21 | +#include "clang/CIR/Interfaces/CIRFPTypeInterface.h" |
30 | 22 |
|
31 | 23 | namespace cir {
|
32 |
| - |
33 | 24 | namespace detail {
|
34 | 25 | struct StructTypeStorage;
|
35 | 26 | } // namespace detail
|
36 | 27 |
|
37 |
| -/// Each unique clang::RecordDecl is mapped to a `cir.struct` and any object in |
38 |
| -/// C/C++ that has a struct type will have a `cir.struct` in CIR. |
39 |
| -/// |
40 |
| -/// There are three possible formats for this type: |
41 |
| -/// |
42 |
| -/// - Identified and complete structs: unique name and a known body. |
43 |
| -/// - Identified and incomplete structs: unique name and unknown body. |
44 |
| -/// - Anonymous structs: no name and a known body. |
45 |
| -/// |
46 |
| -/// Identified structs are uniqued by their name, and anonymous structs are |
47 |
| -/// uniqued by their body. This means that two anonymous structs with the same |
48 |
| -/// body will be the same type, and two identified structs with the same name |
49 |
| -/// will be the same type. Attempting to build a struct with an existing name, |
50 |
| -/// but a different body will result in an error. |
51 |
| -/// |
52 |
| -/// A few examples: |
53 |
| -/// |
54 |
| -/// ```mlir |
55 |
| -/// !complete = !cir.struct<struct "complete" {!cir.int<u, 8>}> |
56 |
| -/// !incomplete = !cir.struct<struct "incomplete" incomplete> |
57 |
| -/// !anonymous = !cir.struct<struct {!cir.int<u, 8>}> |
58 |
| -/// ``` |
59 |
| -/// |
60 |
| -/// Incomplete structs are mutable, meaning they can be later completed with a |
61 |
| -/// body automatically updating in place every type in the code that uses the |
62 |
| -/// incomplete struct. Mutability allows for recursive types to be represented, |
63 |
| -/// meaning the struct can have members that refer to itself. This is useful for |
64 |
| -/// representing recursive records and is implemented through a special syntax. |
65 |
| -/// In the example below, the `Node` struct has a member that is a pointer to a |
66 |
| -/// `Node` struct: |
67 |
| -/// |
68 |
| -/// ```mlir |
69 |
| -/// !struct = !cir.struct<struct "Node" {!cir.ptr<!cir.struct<struct |
70 |
| -/// "Node">>}> |
71 |
| -/// ``` |
72 |
| -class StructType |
73 |
| - : public mlir::Type::TypeBase< |
74 |
| - StructType, mlir::Type, detail::StructTypeStorage, |
75 |
| - mlir::DataLayoutTypeInterface::Trait, mlir::TypeTrait::IsMutable> { |
76 |
| - // FIXME(cir): migrate this type to Tablegen once mutable types are supported. |
77 |
| -public: |
78 |
| - using Base::Base; |
79 |
| - using Base::getChecked; |
80 |
| - using Base::verifyInvariants; |
81 |
| - |
82 |
| - static constexpr llvm::StringLiteral name = "cir.struct"; |
83 |
| - |
84 |
| - enum RecordKind : uint32_t { Class, Union, Struct }; |
85 |
| - |
86 |
| - /// Create an identified and complete struct type. |
87 |
| - static StructType get(mlir::MLIRContext *context, |
88 |
| - llvm::ArrayRef<mlir::Type> members, |
89 |
| - mlir::StringAttr name, bool packed, bool padded, |
90 |
| - RecordKind kind, ASTRecordDeclInterface ast = {}); |
91 |
| - static StructType |
92 |
| - getChecked(llvm::function_ref<mlir::InFlightDiagnostic()> emitError, |
93 |
| - mlir::MLIRContext *context, llvm::ArrayRef<mlir::Type> members, |
94 |
| - mlir::StringAttr name, bool packed, bool padded, RecordKind kind, |
95 |
| - ASTRecordDeclInterface ast = {}); |
96 |
| - |
97 |
| - /// Create an identified and incomplete struct type. |
98 |
| - static StructType get(mlir::MLIRContext *context, mlir::StringAttr name, |
99 |
| - RecordKind kind); |
100 |
| - static StructType |
101 |
| - getChecked(llvm::function_ref<mlir::InFlightDiagnostic()> emitError, |
102 |
| - mlir::MLIRContext *context, mlir::StringAttr name, |
103 |
| - RecordKind kind); |
104 |
| - |
105 |
| - /// Create an anonymous struct type (always complete). |
106 |
| - static StructType get(mlir::MLIRContext *context, |
107 |
| - llvm::ArrayRef<mlir::Type> members, bool packed, |
108 |
| - bool padded, RecordKind kind, |
109 |
| - ASTRecordDeclInterface ast = {}); |
110 |
| - static StructType |
111 |
| - getChecked(llvm::function_ref<mlir::InFlightDiagnostic()> emitError, |
112 |
| - mlir::MLIRContext *context, llvm::ArrayRef<mlir::Type> members, |
113 |
| - bool packed, bool padded, RecordKind kind, |
114 |
| - ASTRecordDeclInterface ast = {}); |
115 |
| - |
116 |
| - /// Validate the struct about to be constructed. |
117 |
| - static llvm::LogicalResult |
118 |
| - verifyInvariants(llvm::function_ref<mlir::InFlightDiagnostic()> emitError, |
119 |
| - llvm::ArrayRef<mlir::Type> members, mlir::StringAttr name, |
120 |
| - bool incomplete, bool packed, bool padded, |
121 |
| - StructType::RecordKind kind, ASTRecordDeclInterface ast); |
122 |
| - |
123 |
| - // Parse/print methods. |
124 |
| - static constexpr llvm::StringLiteral getMnemonic() { return {"struct"}; } |
125 |
| - static mlir::Type parse(mlir::AsmParser &odsParser); |
126 |
| - void print(mlir::AsmPrinter &odsPrinter) const; |
127 |
| - |
128 |
| - // Accessors |
129 |
| - ASTRecordDeclInterface getAst() const; |
130 |
| - llvm::ArrayRef<mlir::Type> getMembers() const; |
131 |
| - mlir::StringAttr getName() const; |
132 |
| - StructType::RecordKind getKind() const; |
133 |
| - bool getIncomplete() const; |
134 |
| - bool getPacked() const; |
135 |
| - bool getPadded() const; |
136 |
| - void dropAst(); |
137 |
| - |
138 |
| - // Predicates |
139 |
| - bool isClass() const { return getKind() == RecordKind::Class; }; |
140 |
| - bool isStruct() const { return getKind() == RecordKind::Struct; }; |
141 |
| - bool isUnion() const { return getKind() == RecordKind::Union; }; |
142 |
| - bool isComplete() const { return !isIncomplete(); }; |
143 |
| - bool isIncomplete() const; |
144 |
| - |
145 |
| - // Utilities |
146 |
| - mlir::Type getLargestMember(const mlir::DataLayout &dataLayout) const; |
147 |
| - size_t getNumElements() const { return getMembers().size(); }; |
148 |
| - std::string getKindAsStr() { |
149 |
| - switch (getKind()) { |
150 |
| - case RecordKind::Class: |
151 |
| - return "class"; |
152 |
| - case RecordKind::Union: |
153 |
| - return "union"; |
154 |
| - case RecordKind::Struct: |
155 |
| - return "struct"; |
156 |
| - } |
157 |
| - llvm_unreachable("Invalid value for StructType::getKind()"); |
158 |
| - } |
159 |
| - std::string getPrefixedName() { |
160 |
| - return getKindAsStr() + "." + getName().getValue().str(); |
161 |
| - } |
162 |
| - |
163 |
| - /// Complete the struct type by mutating its members and attributes. |
164 |
| - void complete(llvm::ArrayRef<mlir::Type> members, bool packed, bool isPadded, |
165 |
| - ASTRecordDeclInterface ast = {}); |
166 |
| - |
167 |
| - /// DataLayoutTypeInterface methods. |
168 |
| - llvm::TypeSize getTypeSizeInBits(const mlir::DataLayout &dataLayout, |
169 |
| - mlir::DataLayoutEntryListRef params) const; |
170 |
| - uint64_t getABIAlignment(const mlir::DataLayout &dataLayout, |
171 |
| - mlir::DataLayoutEntryListRef params) const; |
172 |
| - uint64_t getElementOffset(const mlir::DataLayout &dataLayout, |
173 |
| - unsigned idx) const; |
174 |
| - |
175 |
| - bool isLayoutIdentical(const StructType &other); |
176 |
| - |
177 |
| - // Utilities for lazily computing and cacheing data layout info. |
178 |
| -private: |
179 |
| - // FIXME: currently opaque because there's a cycle if CIRTypes.types include |
180 |
| - // from CIRAttrs.h. The implementation operates in terms of StructLayoutAttr |
181 |
| - // instead. |
182 |
| - mutable mlir::Attribute layoutInfo; |
183 |
| - void computeSizeAndAlignment(const mlir::DataLayout &dataLayout) const; |
184 |
| -}; |
185 |
| - |
186 | 28 | bool isAnyFloatingPointType(mlir::Type t);
|
187 | 29 | bool isScalarType(mlir::Type t);
|
188 | 30 | bool isFPOrFPVectorTy(mlir::Type);
|
|
0 commit comments