clang 20.0.0git
CIRTypes.cpp
Go to the documentation of this file.
1//===- CIRTypes.cpp - MLIR CIR Types --------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the types in the CIR dialect.
10//
11//===----------------------------------------------------------------------===//
12
14
15#include "mlir/IR/DialectImplementation.h"
17#include "llvm/ADT/TypeSwitch.h"
18
19//===----------------------------------------------------------------------===//
20// CIR Custom Parser/Printer Signatures
21//===----------------------------------------------------------------------===//
22
23static mlir::ParseResult
24parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
25 bool &isVarArg);
26static void printFuncTypeArgs(mlir::AsmPrinter &p,
27 mlir::ArrayRef<mlir::Type> params, bool isVarArg);
28
29//===----------------------------------------------------------------------===//
30// Get autogenerated stuff
31//===----------------------------------------------------------------------===//
32
33#define GET_TYPEDEF_CLASSES
34#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc"
35
36using namespace mlir;
37using namespace cir;
38
39//===----------------------------------------------------------------------===//
40// General CIR parsing / printing
41//===----------------------------------------------------------------------===//
42
43Type CIRDialect::parseType(DialectAsmParser &parser) const {
44 llvm::SMLoc typeLoc = parser.getCurrentLocation();
45 llvm::StringRef mnemonic;
46 Type genType;
47
48 // Try to parse as a tablegen'd type.
49 OptionalParseResult parseResult =
50 generatedTypeParser(parser, &mnemonic, genType);
51 if (parseResult.has_value())
52 return genType;
53
54 // TODO(CIR) Attempt to parse as a raw C++ type.
55 parser.emitError(typeLoc) << "unknown CIR type: " << mnemonic;
56 return Type();
57}
58
59void CIRDialect::printType(Type type, DialectAsmPrinter &os) const {
60 // Try to print as a tablegen'd type.
61 if (generatedTypePrinter(type, os).succeeded())
62 return;
63
64 // TODO(CIR) Attempt to print as a raw C++ type.
65 llvm::report_fatal_error("printer is missing a handler for this type");
66}
67
68//===----------------------------------------------------------------------===//
69// IntType Definitions
70//===----------------------------------------------------------------------===//
71
72Type IntType::parse(mlir::AsmParser &parser) {
73 mlir::MLIRContext *context = parser.getBuilder().getContext();
74 llvm::SMLoc loc = parser.getCurrentLocation();
75 bool isSigned;
76 unsigned width;
77
78 if (parser.parseLess())
79 return {};
80
81 // Fetch integer sign.
82 llvm::StringRef sign;
83 if (parser.parseKeyword(&sign))
84 return {};
85 if (sign == "s")
86 isSigned = true;
87 else if (sign == "u")
88 isSigned = false;
89 else {
90 parser.emitError(loc, "expected 's' or 'u'");
91 return {};
92 }
93
94 if (parser.parseComma())
95 return {};
96
97 // Fetch integer size.
98 if (parser.parseInteger(width))
99 return {};
100 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
101 parser.emitError(loc, "expected integer width to be from ")
102 << IntType::minBitwidth() << " up to " << IntType::maxBitwidth();
103 return {};
104 }
105
106 if (parser.parseGreater())
107 return {};
108
109 return IntType::get(context, width, isSigned);
110}
111
112void IntType::print(mlir::AsmPrinter &printer) const {
113 char sign = isSigned() ? 's' : 'u';
114 printer << '<' << sign << ", " << getWidth() << '>';
115}
116
117llvm::TypeSize
118IntType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
119 mlir::DataLayoutEntryListRef params) const {
120 return llvm::TypeSize::getFixed(getWidth());
121}
122
123uint64_t IntType::getABIAlignment(const mlir::DataLayout &dataLayout,
124 mlir::DataLayoutEntryListRef params) const {
125 return (uint64_t)(getWidth() / 8);
126}
127
129IntType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
130 ::mlir::DataLayoutEntryListRef params) const {
131 return (uint64_t)(getWidth() / 8);
132}
133
134mlir::LogicalResult
135IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
136 unsigned width, bool isSigned) {
137 if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) {
138 emitError() << "IntType only supports widths from "
139 << IntType::minBitwidth() << " up to "
140 << IntType::maxBitwidth();
141 return mlir::failure();
142 }
143 return mlir::success();
144}
145
146//===----------------------------------------------------------------------===//
147// Floating-point type definitions
148//===----------------------------------------------------------------------===//
149
150const llvm::fltSemantics &SingleType::getFloatSemantics() const {
151 return llvm::APFloat::IEEEsingle();
152}
153
154llvm::TypeSize
155SingleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
156 mlir::DataLayoutEntryListRef params) const {
157 return llvm::TypeSize::getFixed(getWidth());
158}
159
161SingleType::getABIAlignment(const mlir::DataLayout &dataLayout,
162 mlir::DataLayoutEntryListRef params) const {
163 return (uint64_t)(getWidth() / 8);
164}
165
167SingleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
168 ::mlir::DataLayoutEntryListRef params) const {
169 return (uint64_t)(getWidth() / 8);
170}
171
172const llvm::fltSemantics &DoubleType::getFloatSemantics() const {
173 return llvm::APFloat::IEEEdouble();
174}
175
176llvm::TypeSize
177DoubleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
178 mlir::DataLayoutEntryListRef params) const {
179 return llvm::TypeSize::getFixed(getWidth());
180}
181
183DoubleType::getABIAlignment(const mlir::DataLayout &dataLayout,
184 mlir::DataLayoutEntryListRef params) const {
185 return (uint64_t)(getWidth() / 8);
186}
187
189DoubleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
190 ::mlir::DataLayoutEntryListRef params) const {
191 return (uint64_t)(getWidth() / 8);
192}
193
194const llvm::fltSemantics &FP16Type::getFloatSemantics() const {
195 return llvm::APFloat::IEEEhalf();
196}
197
198llvm::TypeSize
199FP16Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
200 mlir::DataLayoutEntryListRef params) const {
201 return llvm::TypeSize::getFixed(getWidth());
202}
203
204uint64_t FP16Type::getABIAlignment(const mlir::DataLayout &dataLayout,
205 mlir::DataLayoutEntryListRef params) const {
206 return (uint64_t)(getWidth() / 8);
207}
208
210FP16Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
211 ::mlir::DataLayoutEntryListRef params) const {
212 return (uint64_t)(getWidth() / 8);
213}
214
215const llvm::fltSemantics &BF16Type::getFloatSemantics() const {
216 return llvm::APFloat::BFloat();
217}
218
219llvm::TypeSize
220BF16Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
221 mlir::DataLayoutEntryListRef params) const {
222 return llvm::TypeSize::getFixed(getWidth());
223}
224
225uint64_t BF16Type::getABIAlignment(const mlir::DataLayout &dataLayout,
226 mlir::DataLayoutEntryListRef params) const {
227 return (uint64_t)(getWidth() / 8);
228}
229
231BF16Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
232 ::mlir::DataLayoutEntryListRef params) const {
233 return (uint64_t)(getWidth() / 8);
234}
235
236const llvm::fltSemantics &FP80Type::getFloatSemantics() const {
237 return llvm::APFloat::x87DoubleExtended();
238}
239
240llvm::TypeSize
241FP80Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
242 mlir::DataLayoutEntryListRef params) const {
243 // Though only 80 bits are used for the value, the type is 128 bits in size.
244 return llvm::TypeSize::getFixed(128);
245}
246
247uint64_t FP80Type::getABIAlignment(const mlir::DataLayout &dataLayout,
248 mlir::DataLayoutEntryListRef params) const {
249 return 16;
250}
251
253FP80Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
254 ::mlir::DataLayoutEntryListRef params) const {
255 return 16;
256}
257
258const llvm::fltSemantics &FP128Type::getFloatSemantics() const {
259 return llvm::APFloat::IEEEquad();
260}
261
262llvm::TypeSize
263FP128Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
264 mlir::DataLayoutEntryListRef params) const {
265 return llvm::TypeSize::getFixed(getWidth());
266}
267
268uint64_t FP128Type::getABIAlignment(const mlir::DataLayout &dataLayout,
269 mlir::DataLayoutEntryListRef params) const {
270 return 16;
271}
272
274FP128Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
275 ::mlir::DataLayoutEntryListRef params) const {
276 return 16;
277}
278
279const llvm::fltSemantics &LongDoubleType::getFloatSemantics() const {
280 return mlir::cast<cir::CIRFPTypeInterface>(getUnderlying())
281 .getFloatSemantics();
282}
283
284llvm::TypeSize
285LongDoubleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
286 mlir::DataLayoutEntryListRef params) const {
287 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
288 .getTypeSizeInBits(dataLayout, params);
289}
290
292LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout,
293 mlir::DataLayoutEntryListRef params) const {
294 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
295 .getABIAlignment(dataLayout, params);
296}
297
298uint64_t LongDoubleType::getPreferredAlignment(
299 const ::mlir::DataLayout &dataLayout,
300 mlir::DataLayoutEntryListRef params) const {
301 return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying())
302 .getPreferredAlignment(dataLayout, params);
303}
304
305LogicalResult
306LongDoubleType::verify(function_ref<InFlightDiagnostic()> emitError,
307 mlir::Type underlying) {
308 if (!mlir::isa<DoubleType, FP80Type, FP128Type>(underlying)) {
309 emitError() << "invalid underlying type for long double";
310 return failure();
311 }
312
313 return success();
314}
315
316//===----------------------------------------------------------------------===//
317// Floating-point type helpers
318//===----------------------------------------------------------------------===//
319
320bool cir::isAnyFloatingPointType(mlir::Type t) {
321 return isa<cir::SingleType, cir::DoubleType, cir::LongDoubleType,
322 cir::FP80Type, cir::BF16Type, cir::FP16Type, cir::FP128Type>(t);
323}
324
325//===----------------------------------------------------------------------===//
326// FuncType Definitions
327//===----------------------------------------------------------------------===//
328
329FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
330 assert(results.size() == 1 && "expected exactly one result type");
331 return get(llvm::to_vector(inputs), results[0], isVarArg());
332}
333
334mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p,
336 bool &isVarArg) {
337 isVarArg = false;
338 // `(` `)`
339 if (succeeded(p.parseOptionalRParen()))
340 return mlir::success();
341
342 // `(` `...` `)`
343 if (succeeded(p.parseOptionalEllipsis())) {
344 isVarArg = true;
345 return p.parseRParen();
346 }
347
348 // type (`,` type)* (`,` `...`)?
349 mlir::Type type;
350 if (p.parseType(type))
351 return mlir::failure();
352 params.push_back(type);
353 while (succeeded(p.parseOptionalComma())) {
354 if (succeeded(p.parseOptionalEllipsis())) {
355 isVarArg = true;
356 return p.parseRParen();
357 }
358 if (p.parseType(type))
359 return mlir::failure();
360 params.push_back(type);
361 }
362
363 return p.parseRParen();
364}
365
366void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
367 bool isVarArg) {
368 llvm::interleaveComma(params, p,
369 [&p](mlir::Type type) { p.printType(type); });
370 if (isVarArg) {
371 if (!params.empty())
372 p << ", ";
373 p << "...";
374 }
375 p << ')';
376}
377
378llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes() const {
379 return static_cast<detail::FuncTypeStorage *>(getImpl())->returnType;
380}
381
382bool FuncType::isVoid() const { return mlir::isa<VoidType>(getReturnType()); }
383
384//===----------------------------------------------------------------------===//
385// PointerType Definitions
386//===----------------------------------------------------------------------===//
387
388llvm::TypeSize
389PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
390 ::mlir::DataLayoutEntryListRef params) const {
391 // FIXME: improve this in face of address spaces
392 return llvm::TypeSize::getFixed(64);
393}
394
396PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
397 ::mlir::DataLayoutEntryListRef params) const {
398 // FIXME: improve this in face of address spaces
399 return 8;
400}
401
402uint64_t PointerType::getPreferredAlignment(
403 const ::mlir::DataLayout &dataLayout,
404 ::mlir::DataLayoutEntryListRef params) const {
405 // FIXME: improve this in face of address spaces
406 return 8;
407}
408
409mlir::LogicalResult
410PointerType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
411 mlir::Type pointee) {
412 // TODO(CIR): Verification of the address space goes here.
413 return mlir::success();
414}
415
416//===----------------------------------------------------------------------===//
417// CIR Dialect
418//===----------------------------------------------------------------------===//
419
420void CIRDialect::registerTypes() {
421 // Register tablegen'd types.
422 addTypes<
423#define GET_TYPEDEF_LIST
424#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc"
425 >();
426
427 // Register raw C++ types.
428 // TODO(CIR) addTypes<StructType>();
429}
MatchType Type
static void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef< mlir::Type > params, bool isVarArg)
Definition: CIRTypes.cpp:366
static mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector< mlir::Type > &params, bool &isVarArg)
Definition: CIRTypes.cpp:334
static LiveVariablesImpl & getImpl(void *x)
bool isAnyFloatingPointType(mlir::Type t)
Definition: CIRTypes.cpp:320
unsigned long uint64_t
float __ovld __cnfn sign(float)
Returns 1.0 if x > 0, -0.0 if x = -0.0, +0.0 if x = +0.0, or -1.0 if x < 0.