clang 22.0.0git
CIRGenBuilder.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H
10#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H
11
12#include "Address.h"
13#include "CIRGenRecordLayout.h"
14#include "CIRGenTypeCache.h"
18
21#include "llvm/ADT/APFloat.h"
22#include "llvm/ADT/STLExtras.h"
23
24namespace clang::CIRGen {
25
27 const CIRGenTypeCache &typeCache;
28 llvm::StringMap<unsigned> recordNames;
29 llvm::StringMap<unsigned> globalsVersioning;
30
31public:
32 CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
33 : CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
34
35 /// Get a cir::ConstArrayAttr for a string literal.
36 /// Note: This is different from what is returned by
37 /// mlir::Builder::getStringAttr() which is an mlir::StringAttr.
38 mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
39 std::optional<size_t> size) {
40 size_t finalSize = size.value_or(str.size());
41
42 size_t lastNonZeroPos = str.find_last_not_of('\0');
43 // If the string is full of null bytes, emit a #cir.zero rather than
44 // a #cir.const_array.
45 if (lastNonZeroPos == llvm::StringRef::npos) {
46 auto arrayTy = cir::ArrayType::get(eltTy, finalSize);
47 return cir::ZeroAttr::get(arrayTy);
48 }
49 // We emit trailing zeros only if there are multiple trailing zeros.
50 size_t trailingZerosNum = 0;
51 if (finalSize > lastNonZeroPos + 2)
52 trailingZerosNum = finalSize - lastNonZeroPos - 1;
53 auto truncatedArrayTy =
54 cir::ArrayType::get(eltTy, finalSize - trailingZerosNum);
55 auto fullArrayTy = cir::ArrayType::get(eltTy, finalSize);
56 return cir::ConstArrayAttr::get(
57 fullArrayTy,
58 mlir::StringAttr::get(str.drop_back(trailingZerosNum),
59 truncatedArrayTy),
60 trailingZerosNum);
61 }
62
63 cir::ConstRecordAttr getAnonConstRecord(mlir::ArrayAttr arrayAttr,
64 bool packed = false,
65 bool padded = false,
66 mlir::Type ty = {}) {
68 for (auto &f : arrayAttr) {
69 auto ta = mlir::cast<mlir::TypedAttr>(f);
70 members.push_back(ta.getType());
71 }
72
73 if (!ty)
74 ty = getAnonRecordTy(members, packed, padded);
75
76 auto sTy = mlir::cast<cir::RecordType>(ty);
77 return cir::ConstRecordAttr::get(sTy, arrayAttr);
78 }
79
80 std::string getUniqueAnonRecordName() { return getUniqueRecordName("anon"); }
81
82 std::string getUniqueRecordName(const std::string &baseName) {
83 auto it = recordNames.find(baseName);
84 if (it == recordNames.end()) {
85 recordNames[baseName] = 0;
86 return baseName;
87 }
88
89 return baseName + "." + std::to_string(recordNames[baseName]++);
90 }
91
92 cir::LongDoubleType getLongDoubleTy(const llvm::fltSemantics &format) const {
93 if (&format == &llvm::APFloat::IEEEdouble())
94 return cir::LongDoubleType::get(getContext(), typeCache.DoubleTy);
95 if (&format == &llvm::APFloat::x87DoubleExtended())
96 return cir::LongDoubleType::get(getContext(), typeCache.FP80Ty);
97 if (&format == &llvm::APFloat::IEEEquad())
98 return cir::LongDoubleType::get(getContext(), typeCache.FP128Ty);
99 if (&format == &llvm::APFloat::PPCDoubleDouble())
100 llvm_unreachable("NYI: PPC double-double format for long double");
101 llvm_unreachable("Unsupported format for long double");
102 }
103
104 mlir::Type getPtrToVPtrType() {
105 return getPointerTo(cir::VPtrType::get(getContext()));
106 }
107
108 /// Get a CIR record kind from a AST declaration tag.
109 cir::RecordType::RecordKind getRecordKind(const clang::TagTypeKind kind) {
110 switch (kind) {
112 return cir::RecordType::Class;
114 return cir::RecordType::Struct;
116 return cir::RecordType::Union;
118 llvm_unreachable("interface records are NYI");
120 llvm_unreachable("enums are not records");
121 }
122 llvm_unreachable("Unsupported record kind");
123 }
124
125 /// Get a CIR named record type.
126 ///
127 /// If a record already exists and is complete, but the client tries to fetch
128 /// it with a different set of attributes, this method will crash.
130 llvm::StringRef name, bool packed,
131 bool padded) {
132 const auto nameAttr = getStringAttr(name);
133 auto kind = cir::RecordType::RecordKind::Struct;
135
136 // Create or get the record.
137 auto type =
138 getType<cir::RecordType>(members, nameAttr, packed, padded, kind);
139
140 // If we found an existing type, verify that either it is incomplete or
141 // it matches the requested attributes.
142 assert(!type.isIncomplete() ||
143 (type.getMembers() == members && type.getPacked() == packed &&
144 type.getPadded() == padded));
145
146 // Complete an incomplete record or ensure the existing complete record
147 // matches the requested attributes.
148 type.complete(members, packed, padded);
149
150 return type;
151 }
152
153 /// Get an incomplete CIR struct type. If we have a complete record
154 /// declaration, we may create an incomplete type and then add the
155 /// members, so \p rd here may be complete.
156 cir::RecordType getIncompleteRecordTy(llvm::StringRef name,
157 const clang::RecordDecl *rd) {
158 const mlir::StringAttr nameAttr = getStringAttr(name);
159 cir::RecordType::RecordKind kind = cir::RecordType::RecordKind::Struct;
160 if (rd)
161 kind = getRecordKind(rd->getTagKind());
162 return getType<cir::RecordType>(nameAttr, kind);
163 }
164
165 // Return true if the value is a null constant such as null pointer, (+0.0)
166 // for floating-point or zero initializer
167 bool isNullValue(mlir::Attribute attr) const {
168 if (mlir::isa<cir::ZeroAttr>(attr))
169 return true;
170
171 if (const auto ptrVal = mlir::dyn_cast<cir::ConstPtrAttr>(attr))
172 return ptrVal.isNullValue();
173
174 if (const auto intVal = mlir::dyn_cast<cir::IntAttr>(attr))
175 return intVal.isNullValue();
176
177 if (const auto boolVal = mlir::dyn_cast<cir::BoolAttr>(attr))
178 return !boolVal.getValue();
179
180 if (auto fpAttr = mlir::dyn_cast<cir::FPAttr>(attr)) {
181 auto fpVal = fpAttr.getValue();
182 bool ignored;
183 llvm::APFloat fv(+0.0);
184 fv.convert(fpVal.getSemantics(), llvm::APFloat::rmNearestTiesToEven,
185 &ignored);
186 return fv.bitwiseIsEqual(fpVal);
187 }
188
189 if (const auto arrayVal = mlir::dyn_cast<cir::ConstArrayAttr>(attr)) {
190 if (mlir::isa<mlir::StringAttr>(arrayVal.getElts()))
191 return false;
192
193 return llvm::all_of(
194 mlir::cast<mlir::ArrayAttr>(arrayVal.getElts()),
195 [&](const mlir::Attribute &elt) { return isNullValue(elt); });
196 }
197 return false;
198 }
199
200 //
201 // Type helpers
202 // ------------
203 //
204 cir::IntType getUIntNTy(int n) {
205 switch (n) {
206 case 8:
207 return getUInt8Ty();
208 case 16:
209 return getUInt16Ty();
210 case 32:
211 return getUInt32Ty();
212 case 64:
213 return getUInt64Ty();
214 default:
215 return cir::IntType::get(getContext(), n, false);
216 }
217 }
218
219 cir::IntType getSIntNTy(int n) {
220 switch (n) {
221 case 8:
222 return getSInt8Ty();
223 case 16:
224 return getSInt16Ty();
225 case 32:
226 return getSInt32Ty();
227 case 64:
228 return getSInt64Ty();
229 default:
230 return cir::IntType::get(getContext(), n, true);
231 }
232 }
233
234 cir::VoidType getVoidTy() { return typeCache.VoidTy; }
235
236 cir::IntType getSInt8Ty() { return typeCache.SInt8Ty; }
237 cir::IntType getSInt16Ty() { return typeCache.SInt16Ty; }
238 cir::IntType getSInt32Ty() { return typeCache.SInt32Ty; }
239 cir::IntType getSInt64Ty() { return typeCache.SInt64Ty; }
240
241 cir::IntType getUInt8Ty() { return typeCache.UInt8Ty; }
242 cir::IntType getUInt16Ty() { return typeCache.UInt16Ty; }
243 cir::IntType getUInt32Ty() { return typeCache.UInt32Ty; }
244 cir::IntType getUInt64Ty() { return typeCache.UInt64Ty; }
245
246 cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal);
247
248 cir::ConstantOp getConstInt(mlir::Location loc, llvm::APInt intVal);
249
250 cir::ConstantOp getConstInt(mlir::Location loc, mlir::Type t, uint64_t c);
251
252 cir::ConstantOp getConstFP(mlir::Location loc, mlir::Type t,
253 llvm::APFloat fpVal);
254
255 bool isInt8Ty(mlir::Type i) {
256 return i == typeCache.UInt8Ty || i == typeCache.SInt8Ty;
257 }
258 bool isInt16Ty(mlir::Type i) {
259 return i == typeCache.UInt16Ty || i == typeCache.SInt16Ty;
260 }
261 bool isInt32Ty(mlir::Type i) {
262 return i == typeCache.UInt32Ty || i == typeCache.SInt32Ty;
263 }
264 bool isInt64Ty(mlir::Type i) {
265 return i == typeCache.UInt64Ty || i == typeCache.SInt64Ty;
266 }
267 bool isInt(mlir::Type i) { return mlir::isa<cir::IntType>(i); }
268
269 // Fetch the type representing a pointer to unsigned int8 values.
270 cir::PointerType getUInt8PtrTy() { return typeCache.UInt8PtrTy; }
271
272 /// Get a CIR anonymous record type.
274 bool packed = false, bool padded = false) {
276 auto kind = cir::RecordType::RecordKind::Struct;
277 return getType<cir::RecordType>(members, packed, padded, kind);
278 }
279
280 //
281 // Constant creation helpers
282 // -------------------------
283 //
284 cir::ConstantOp getSInt32(int32_t c, mlir::Location loc) {
285 return getConstantInt(loc, getSInt32Ty(), c);
286 }
287 cir::ConstantOp getUInt32(uint32_t c, mlir::Location loc) {
288 return getConstantInt(loc, getUInt32Ty(), c);
289 }
290
291 // Creates constant nullptr for pointer type ty.
292 cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) {
294 return cir::ConstantOp::create(*this, loc, getConstPtrAttr(ty, 0));
295 }
296
297 mlir::Value createNeg(mlir::Value value) {
298
299 if (auto intTy = mlir::dyn_cast<cir::IntType>(value.getType())) {
300 // Source is a unsigned integer: first cast it to signed.
301 if (intTy.isUnsigned())
302 value = createIntCast(value, getSIntNTy(intTy.getWidth()));
303 return cir::UnaryOp::create(*this, value.getLoc(), value.getType(),
304 cir::UnaryOpKind::Minus, value);
305 }
306
307 llvm_unreachable("negation for the given type is NYI");
308 }
309
310 // TODO: split this to createFPExt/createFPTrunc when we have dedicated cast
311 // operations.
312 mlir::Value createFloatingCast(mlir::Value v, mlir::Type destType) {
314
315 return cir::CastOp::create(*this, v.getLoc(), destType,
316 cir::CastKind::floating, v);
317 }
318
319 mlir::Value createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
323
324 return cir::BinOp::create(*this, loc, cir::BinOpKind::Sub, lhs, rhs);
325 }
326
327 mlir::Value createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
331
332 return cir::BinOp::create(*this, loc, cir::BinOpKind::Add, lhs, rhs);
333 }
334 mlir::Value createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
338
339 return cir::BinOp::create(*this, loc, cir::BinOpKind::Mul, lhs, rhs);
340 }
341 mlir::Value createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs) {
345
346 return cir::BinOp::create(*this, loc, cir::BinOpKind::Div, lhs, rhs);
347 }
348
349 Address createBaseClassAddr(mlir::Location loc, Address addr,
350 mlir::Type destType, unsigned offset,
351 bool assumeNotNull) {
352 if (destType == addr.getElementType())
353 return addr;
354
355 auto ptrTy = getPointerTo(destType);
356 auto baseAddr =
357 cir::BaseClassAddrOp::create(*this, loc, ptrTy, addr.getPointer(),
358 mlir::APInt(64, offset), assumeNotNull);
359 return Address(baseAddr, destType, addr.getAlignment());
360 }
361
362 /// Cast the element type of the given address to a different type,
363 /// preserving information like the alignment.
364 Address createElementBitCast(mlir::Location loc, Address addr,
365 mlir::Type destType) {
366 if (destType == addr.getElementType())
367 return addr;
368
369 auto ptrTy = getPointerTo(destType);
370 return Address(createBitcast(loc, addr.getPointer(), ptrTy), destType,
371 addr.getAlignment());
372 }
373
374 cir::LoadOp createLoad(mlir::Location loc, Address addr,
375 bool isVolatile = false) {
376 mlir::IntegerAttr align = getAlignmentAttr(addr.getAlignment());
377 return cir::LoadOp::create(*this, loc, addr.getPointer(), /*isDeref=*/false,
378 isVolatile, /*alignment=*/align,
379 /*mem_order=*/cir::MemOrderAttr{});
380 }
381
382 cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst,
383 bool isVolatile = false,
384 mlir::IntegerAttr align = {},
385 cir::MemOrderAttr order = {}) {
386 if (!align)
387 align = getAlignmentAttr(dst.getAlignment());
388 return CIRBaseBuilderTy::createStore(loc, val, dst.getPointer(), isVolatile,
389 align, order);
390 }
391
392 /// Create a cir.complex.real_ptr operation that derives a pointer to the real
393 /// part of the complex value pointed to by the specified pointer value.
394 mlir::Value createComplexRealPtr(mlir::Location loc, mlir::Value value) {
395 auto srcPtrTy = mlir::cast<cir::PointerType>(value.getType());
396 auto srcComplexTy = mlir::cast<cir::ComplexType>(srcPtrTy.getPointee());
397 return cir::ComplexRealPtrOp::create(
398 *this, loc, getPointerTo(srcComplexTy.getElementType()), value);
399 }
400
401 Address createComplexRealPtr(mlir::Location loc, Address addr) {
402 return Address{createComplexRealPtr(loc, addr.getPointer()),
403 addr.getAlignment()};
404 }
405
406 /// Create a cir.complex.imag_ptr operation that derives a pointer to the
407 /// imaginary part of the complex value pointed to by the specified pointer
408 /// value.
409 mlir::Value createComplexImagPtr(mlir::Location loc, mlir::Value value) {
410 auto srcPtrTy = mlir::cast<cir::PointerType>(value.getType());
411 auto srcComplexTy = mlir::cast<cir::ComplexType>(srcPtrTy.getPointee());
412 return cir::ComplexImagPtrOp::create(
413 *this, loc, getPointerTo(srcComplexTy.getElementType()), value);
414 }
415
416 Address createComplexImagPtr(mlir::Location loc, Address addr) {
417 return Address{createComplexImagPtr(loc, addr.getPointer()),
418 addr.getAlignment()};
419 }
420
421 /// Create a cir.ptr_stride operation to get access to an array element.
422 /// \p idx is the index of the element to access, \p shouldDecay is true if
423 /// the result should decay to a pointer to the element type.
424 mlir::Value getArrayElement(mlir::Location arrayLocBegin,
425 mlir::Location arrayLocEnd, mlir::Value arrayPtr,
426 mlir::Type eltTy, mlir::Value idx,
427 bool shouldDecay);
428
429 /// Returns a decayed pointer to the first element of the array
430 /// pointed to by \p arrayPtr.
431 mlir::Value maybeBuildArrayDecay(mlir::Location loc, mlir::Value arrayPtr,
432 mlir::Type eltTy);
433
434 // Convert byte offset to sequence of high-level indices suitable for
435 // GlobalViewAttr. Ideally we shouldn't deal with low-level offsets at all
436 // but currently some parts of Clang AST, which we don't want to touch just
437 // yet, return them.
439 int64_t offset, mlir::Type ty, cir::CIRDataLayout layout,
441
442 /// Creates a versioned global variable. If the symbol is already taken, an ID
443 /// will be appended to the symbol. The returned global must always be queried
444 /// for its name so it can be referenced correctly.
445 [[nodiscard]] cir::GlobalOp
446 createVersionedGlobal(mlir::ModuleOp module, mlir::Location loc,
447 mlir::StringRef name, mlir::Type type, bool isConstant,
448 cir::GlobalLinkageKind linkage) {
449 // Create a unique name if the given name is already taken.
450 std::string uniqueName;
451 if (unsigned version = globalsVersioning[name.str()]++)
452 uniqueName = name.str() + "." + std::to_string(version);
453 else
454 uniqueName = name.str();
455
456 return createGlobal(module, loc, uniqueName, type, isConstant, linkage);
457 }
458
459 mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType,
460 Address dstAddr, mlir::Type storageType,
461 mlir::Value src, const CIRGenBitFieldInfo &info,
462 bool isLvalueVolatile, bool useVolatile) {
463 unsigned offset = useVolatile ? info.volatileOffset : info.offset;
464
465 // If using AAPCS and the field is volatile, load with the size of the
466 // declared field
467 storageType =
468 useVolatile ? cir::IntType::get(storageType.getContext(),
469 info.volatileStorageSize, info.isSigned)
470 : storageType;
471 return cir::SetBitfieldOp::create(
472 *this, loc, resultType, dstAddr.getPointer(), storageType, src,
473 info.name, info.size, offset, info.isSigned, isLvalueVolatile,
474 dstAddr.getAlignment().getAsAlign().value());
475 }
476
477 mlir::Value createGetBitfield(mlir::Location loc, mlir::Type resultType,
478 Address addr, mlir::Type storageType,
479 const CIRGenBitFieldInfo &info,
480 bool isLvalueVolatile, bool useVolatile) {
481 unsigned offset = useVolatile ? info.volatileOffset : info.offset;
482
483 // If using AAPCS and the field is volatile, load with the size of the
484 // declared field
485 storageType =
486 useVolatile ? cir::IntType::get(storageType.getContext(),
487 info.volatileStorageSize, info.isSigned)
488 : storageType;
489 return cir::GetBitfieldOp::create(*this, loc, resultType, addr.getPointer(),
490 storageType, info.name, info.size, offset,
491 info.isSigned, isLvalueVolatile,
492 addr.getAlignment().getAsAlign().value());
493 }
494};
495
496} // namespace clang::CIRGen
497
498#endif
__device__ __2f16 float c
cir::PointerType getPointerTo(mlir::Type ty)
mlir::Value createIntCast(mlir::Value src, mlir::Type newTy)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule, mlir::Location loc, mlir::StringRef name, mlir::Type type, bool isConstant, cir::GlobalLinkageKind linkage)
mlir::IntegerAttr getAlignmentAttr(clang::CharUnits alignment)
cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty, int64_t value)
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
mlir::Value getPointer() const
Definition: Address.h:81
mlir::Type getElementType() const
Definition: Address.h:101
clang::CharUnits getAlignment() const
Definition: Address.h:109
mlir::Value createComplexRealPtr(mlir::Location loc, mlir::Value value)
Create a cir.complex.real_ptr operation that derives a pointer to the real part of the complex value ...
cir::RecordType::RecordKind getRecordKind(const clang::TagTypeKind kind)
Get a CIR record kind from a AST declaration tag.
cir::IntType getSIntNTy(int n)
cir::ConstRecordAttr getAnonConstRecord(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type ty={})
Definition: CIRGenBuilder.h:63
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
cir::RecordType getIncompleteRecordTy(llvm::StringRef name, const clang::RecordDecl *rd)
Get an incomplete CIR struct type.
cir::ConstantOp getUInt32(uint32_t c, mlir::Location loc)
cir::GlobalOp createVersionedGlobal(mlir::ModuleOp module, mlir::Location loc, mlir::StringRef name, mlir::Type type, bool isConstant, cir::GlobalLinkageKind linkage)
Creates a versioned global variable.
cir::PointerType getUInt8PtrTy()
std::string getUniqueRecordName(const std::string &baseName)
Definition: CIRGenBuilder.h:82
cir::RecordType getAnonRecordTy(llvm::ArrayRef< mlir::Type > members, bool packed=false, bool padded=false)
Get a CIR anonymous record type.
Address createBaseClassAddr(mlir::Location loc, Address addr, mlir::Type destType, unsigned offset, bool assumeNotNull)
mlir::Value createComplexImagPtr(mlir::Location loc, mlir::Value value)
Create a cir.complex.imag_ptr operation that derives a pointer to the imaginary part of the complex v...
mlir::Value maybeBuildArrayDecay(mlir::Location loc, mlir::Value arrayPtr, mlir::Type eltTy)
Returns a decayed pointer to the first element of the array pointed to by arrayPtr.
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, std::optional< size_t > size)
Get a cir::ConstArrayAttr for a string literal.
Definition: CIRGenBuilder.h:38
cir::ConstantOp getConstFP(mlir::Location loc, mlir::Type t, llvm::APFloat fpVal)
mlir::Value createFloatingCast(mlir::Value v, mlir::Type destType)
mlir::Value createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::RecordType getCompleteRecordTy(llvm::ArrayRef< mlir::Type > members, llvm::StringRef name, bool packed, bool padded)
Get a CIR named record type.
std::string getUniqueAnonRecordName()
Definition: CIRGenBuilder.h:80
Address createElementBitCast(mlir::Location loc, Address addr, mlir::Type destType)
Cast the element type of the given address to a different type, preserving information like the align...
bool isInt16Ty(mlir::Type i)
bool isInt32Ty(mlir::Type i)
mlir::Value createGetBitfield(mlir::Location loc, mlir::Type resultType, Address addr, mlir::Type storageType, const CIRGenBitFieldInfo &info, bool isLvalueVolatile, bool useVolatile)
bool isNullValue(mlir::Attribute attr) const
bool isInt64Ty(mlir::Type i)
mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType, Address dstAddr, mlir::Type storageType, mlir::Value src, const CIRGenBitFieldInfo &info, bool isLvalueVolatile, bool useVolatile)
Address createComplexRealPtr(mlir::Location loc, Address addr)
mlir::Value createFAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
Definition: CIRGenBuilder.h:32
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
void computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
Address createComplexImagPtr(mlir::Location loc, Address addr)
mlir::Value createFMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::ConstantOp getSInt32(int32_t c, mlir::Location loc)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
cir::LongDoubleType getLongDoubleTy(const llvm::fltSemantics &format) const
Definition: CIRGenBuilder.h:92
mlir::Value createFSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::IntType getUIntNTy(int n)
mlir::Value getArrayElement(mlir::Location arrayLocBegin, mlir::Location arrayLocEnd, mlir::Value arrayPtr, mlir::Type eltTy, mlir::Value idx, bool shouldDecay)
Create a cir.ptr_stride operation to get access to an array element.
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::MemOrderAttr order={})
mlir::Value createNeg(mlir::Value value)
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
Definition: CharUnits.h:189
Represents a struct/union/class.
Definition: Decl.h:4309
TagKind getTagKind() const
Definition: Decl.h:3908
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
TagTypeKind
The kind of a tag type.
Definition: TypeBase.h:5906
@ Interface
The "__interface" keyword.
@ Struct
The "struct" keyword.
@ Class
The "class" keyword.
@ Union
The "union" keyword.
@ Enum
The "enum" keyword.
static bool metaDataNode()
static bool targetCodeGenInfoGetNullPointer()
static bool fpConstraints()
static bool astRecordDeclAttr()
static bool fastMathFlags()
Record with information about how a bitfield should be accessed.
unsigned offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
unsigned volatileStorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned size
The total size of the bit-field, in bits.
unsigned isSigned
Whether the bit-field is signed.
unsigned volatileOffset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
llvm::StringRef name
The name of a bitfield.
This structure provides a set of types that are commonly used during IR emission.