clang 24.0.0git
CIRGenRecordLayoutBuilder.cpp
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// This contains code to compute the layout of a record.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenBuilder.h"
14#include "CIRGenModule.h"
15#include "CIRGenTypes.h"
16#include "TargetInfo.h"
17
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
27#include "llvm/Support/Casting.h"
28
29#include <memory>
30
31using namespace llvm;
32using namespace clang;
33using namespace clang::CIRGen;
34
35namespace {
36/// The CIRRecordLowering is responsible for lowering an ASTRecordLayout to an
37/// mlir::Type. Some of the lowering is straightforward, some is not.
38// TODO: Detail some of the complexities and weirdnesses?
39// (See CGRecordLayoutBuilder.cpp)
40struct CIRRecordLowering final {
41
42 // MemberInfo is a helper structure that contains information about a record
43 // member. In addition to the standard member types, there exists a sentinel
44 // member type that ensures correct rounding.
45 struct MemberInfo final {
46 CharUnits offset;
47 enum class InfoKind { VFPtr, Field, Base, VBase } kind;
48 mlir::Type data;
49 /// What this member holds, recorded on the CIR record type.
50 cir::RecordMemberKind memberKind;
51 union {
52 const FieldDecl *fieldDecl;
53 const CXXRecordDecl *cxxRecordDecl;
54 };
55 MemberInfo(CharUnits offset, InfoKind kind, mlir::Type data,
56 cir::RecordMemberKind memberKind,
57 const FieldDecl *fieldDecl = nullptr)
58 : offset{offset}, kind{kind}, data{data}, memberKind{memberKind},
60 MemberInfo(CharUnits offset, InfoKind kind, mlir::Type data,
61 cir::RecordMemberKind memberKind, const CXXRecordDecl *rd)
62 : offset{offset}, kind{kind}, data{data}, memberKind{memberKind},
63 cxxRecordDecl{rd} {}
64 // MemberInfos are sorted so we define a < operator.
65 bool operator<(const MemberInfo &other) const {
66 return offset < other.offset;
67 }
68 };
69
70 static bool ownsBytes(const MemberInfo &member) {
71 return member.data && cir::memberOwnsBytes(member.data);
72 }
73
74 cir::BitFieldDeclAttr getBitFieldDecl(const FieldDecl *field) {
75 return cir::BitFieldDeclAttr::get(
76 cirGenTypes.convertTypeForMem(field->getType()),
77 field->getBitWidthValue(), field->isUnnamedBitField());
78 }
79
80 MemberInfo makeAccessUnitInfo(CharUnits offset, mlir::Type storage,
81 llvm::ArrayRef<cir::BitFieldDeclAttr> fields) {
82 mlir::Type unitTy =
83 cir::BitFieldType::get(&cirGenTypes.getMLIRContext(), storage, fields);
84 // If the access unit doesn't hold any named fields, it's empty.
85 const bool holdsNamedField =
86 mlir::cast<cir::BitFieldType>(unitTy).holdsNamedField();
87 return makeStorageInfo(offset, unitTy,
88 holdsNamedField ? cir::RecordMemberKind::BitField
89 : cir::RecordMemberKind::Empty);
90 }
91
92 /// The member for a zero-width bit-field, which belongs to no access unit
93 /// and owns no bytes. It sits at its own offset, where the run it ended
94 /// stops.
95 MemberInfo makeZeroWidthBitFieldInfo(const FieldDecl *field) {
96 assert(field->isZeroLengthBitField() && "not a zero-width bit-field");
97 return makeAccessUnitInfo(bitsToCharUnits(getFieldBitOffset(field)),
98 /*storage=*/mlir::Type{}, getBitFieldDecl(field));
99 }
100
101 // The constructor.
102 CIRRecordLowering(CIRGenTypes &cirGenTypes, const RecordDecl *recordDecl,
103 bool packed);
104
105 /// Constructs a MemberInfo instance from an offset and mlir::Type.
106 MemberInfo makeStorageInfo(CharUnits offset, mlir::Type data,
107 cir::RecordMemberKind memberKind) {
108 return MemberInfo(offset, MemberInfo::InfoKind::Field, data, memberKind);
109 }
110
111 // Layout routines.
112 void setBitFieldInfo(const FieldDecl *fd, CharUnits startOffset,
113 mlir::Type storageType);
114
115 void lower(bool nonVirtualBaseType);
116 void lowerUnion(bool nonVirtualBaseType);
117
118 /// Determines if we need a packed llvm struct.
119 void determinePacked(bool nvBaseType);
120 /// Inserts padding everywhere it's needed.
121 void insertPadding();
122
123 void computeVolatileBitfields();
124 void accumulateBases();
125 void accumulateVPtrs();
126 void accumulateVBases();
127 void accumulateFields(bool nonVirtualBaseType);
129 accumulateBitFields(RecordDecl::field_iterator field,
131
132 mlir::Type getVFPtrType();
133
134 /// Helper function to check if the target machine is BigEndian.
135 bool isBigEndian() const { return astContext.getTargetInfo().isBigEndian(); }
136
137 CharUnits bitsToCharUnits(uint64_t bitOffset) {
138 return astContext.toCharUnitsFromBits(bitOffset);
139 }
140
141 void calculateZeroInit();
142
143 CharUnits getSize(mlir::Type Ty) {
144 return CharUnits::fromQuantity(dataLayout.getTypeAllocSize(Ty));
145 }
146 CharUnits getSizeInBits(mlir::Type ty) {
147 return CharUnits::fromQuantity(dataLayout.layout.getTypeSizeInBits(ty));
148 }
149
150 CharUnits getMemberAlignment(mlir::Type Ty) {
151 // An access unit takes the alignment of its storage type. A zero-width
152 // bit-field has no storage and so imposes no alignment.
153 if (auto bitFieldTy = mlir::dyn_cast<cir::BitFieldType>(Ty)) {
154 if (mlir::Type storage = bitFieldTy.getStorageType())
155 return getMemberAlignment(storage);
156 return CharUnits::One();
157 }
158 // Recurse on Arrays, they have the member alignment of their element type.
159 if (auto arrayTy = mlir::dyn_cast<cir::ArrayType>(Ty))
160 return getMemberAlignment(arrayTy.getElementType());
161 // Int types (_BitInt in particular) share the alignment of their storage
162 // type.
163 if (auto intTy = mlir::dyn_cast<cir::IntType>(Ty))
165 intTy.getStorageTypeAlignment(dataLayout.layout));
166
167 return CharUnits::fromQuantity(dataLayout.layout.getTypeABIAlignment(Ty));
168 }
169
170 bool isZeroInitializable(const FieldDecl *fd) {
171 return cirGenTypes.isZeroInitializable(fd->getType());
172 }
173 bool isZeroInitializable(const RecordDecl *rd) {
174 return cirGenTypes.isZeroInitializable(rd);
175 }
176
177 /// The mark for a member, given whether it holds data for argument passing
178 /// and whether it is a bit-field. A run of bit-fields shares one access
179 /// unit whose width can be narrower than the declared type of the bit-field
180 /// it holds.
181 static cir::RecordMemberKind makeMemberKind(bool holdsData,
182 bool isNamedBitField) {
183 if (!holdsData)
184 return cir::RecordMemberKind::Empty;
185 return isNamedBitField ? cir::RecordMemberKind::BitField
186 : cir::RecordMemberKind::Data;
187 }
188
189 /// The mark for a field that is not a bit-field. A run of bit-fields is one
190 /// member per access unit rather than one per field, so a bit-field is
191 /// marked where its unit is built.
192 cir::RecordMemberKind getFieldMemberKind(const FieldDecl *fd) {
193 assert(!fd->isBitField() && "a bit-field is marked with its access unit");
194 return makeMemberKind(/*holdsData=*/!isEmptyFieldForABI(astContext, fd),
195 /*isNamedBitField=*/false);
196 }
197
198 /// The mark for a base subobject. A base contributes no ABI data when it is
199 /// empty for the ABI, which is not the same as CXXRecordDecl::isEmpty(): a
200 /// base holding only unnamed bit-fields is laid out but carries no data.
201 cir::RecordMemberKind getBaseMemberKind(const CXXRecordDecl *baseDecl) {
202 return isEmptyRecordForABI(astContext,
203 astContext.getCanonicalTagType(baseDecl))
204 ? cir::RecordMemberKind::Empty
205 : cir::RecordMemberKind::Data;
206 }
207
208 /// Wraps cir::IntType with some implicit arguments.
209 mlir::Type getUIntNType(uint64_t numBits) {
210 unsigned alignedBits = llvm::PowerOf2Ceil(numBits);
211 alignedBits = std::max(8u, alignedBits);
212 return cir::IntType::get(&cirGenTypes.getMLIRContext(), alignedBits,
213 /*isSigned=*/false);
214 }
215
216 mlir::Type getCharType() {
217 return cir::IntType::get(&cirGenTypes.getMLIRContext(),
218 astContext.getCharWidth(),
219 /*isSigned=*/false);
220 }
221
222 mlir::Type getByteArrayType(CharUnits numberOfChars) {
223 assert(!numberOfChars.isZero() && "Empty byte arrays aren't allowed.");
224 mlir::Type type = getCharType();
225 return numberOfChars == CharUnits::One()
226 ? type
227 : cir::ArrayType::get(type, numberOfChars.getQuantity());
228 }
229
230 // Gets the CIR BaseSubobject type from a CXXRecordDecl.
231 mlir::Type getStorageType(const CXXRecordDecl *RD) {
232 return cirGenTypes.getCIRGenRecordLayout(RD).getBaseSubobjectCIRType();
233 }
234 // This is different from LLVM traditional codegen because CIRGen uses arrays
235 // of bytes instead of arbitrary-sized integers. This is important for packed
236 // structures support.
237 mlir::Type getBitfieldStorageType(unsigned numBits) {
238 unsigned alignedBits = llvm::alignTo(numBits, astContext.getCharWidth());
239 if (cir::isValidFundamentalIntWidth(alignedBits))
240 return builder.getUIntNTy(alignedBits);
241
242 mlir::Type type = getCharType();
243 return cir::ArrayType::get(type, alignedBits / astContext.getCharWidth());
244 }
245
246 mlir::Type getStorageType(const FieldDecl *fieldDecl) {
247 mlir::Type type = cirGenTypes.convertTypeForMem(fieldDecl->getType());
248 if (fieldDecl->isBitField()) {
249 cirGenTypes.getCGModule().errorNYI(recordDecl->getSourceRange(),
250 "getStorageType for bitfields");
251 }
252 if (hasBoolVectorStorageAlignMismatch(type))
253 cirGenTypes.getCGModule().errorNYI(
254 fieldDecl->getSourceRange(),
255 "getStorageType for bool vector whose storage integer is aligned "
256 "differently from the vector");
257 return type;
258 }
259
260 /// Whether \p type, or the innermost element type of an array \p type, is a
261 /// bool vector whose storage integer is aligned differently from the
262 /// vector. A bool vector is stored as an integer with one bit per element,
263 /// at least a byte wide. The vector is aligned to its own size, so an
264 /// integer with the same alignment also has the same allocation size.
265 /// Classic CodeGen lays a mismatched member out as that integer and fills
266 /// the difference with padding bytes, which this layout does not do yet.
267 bool hasBoolVectorStorageAlignMismatch(mlir::Type type) {
268 while (auto arrTy = mlir::dyn_cast<cir::ArrayType>(type))
269 type = arrTy.getElementType();
270 auto vecTy = mlir::dyn_cast<cir::VectorType>(type);
271 if (!vecTy || !mlir::isa<cir::BoolType>(vecTy.getElementType()))
272 return false;
273 auto storageTy =
274 mlir::IntegerType::get(type.getContext(), vecTy.getBoolStorageWidth());
275 return dataLayout.layout.getTypeABIAlignment(storageTy) !=
276 dataLayout.layout.getTypeABIAlignment(vecTy);
277 }
278
279 uint64_t getFieldBitOffset(const FieldDecl *fieldDecl) {
280 return astRecordLayout.getFieldOffset(fieldDecl->getFieldIndex());
281 }
282
283 /// Fills out the structures that are ultimately consumed.
284 void fillOutputFields();
285
286 void appendPaddingBytes(CharUnits size) {
287 if (size.isZero())
288 return;
289 mlir::Type padTy = getByteArrayType(size);
290 if (recordDecl->isUnion()) {
291 assert(!unionPadding && "at most one union tail-padding type");
292 unionPadding = padTy;
293 } else {
294 addField(padTy, cir::RecordMemberKind::Pad);
295 }
296 }
297
298 void addField(mlir::Type ty, cir::RecordMemberKind memberKind) {
299 fieldTypes.push_back(ty);
300 fieldKinds.push_back(memberKind);
301 }
302
303 void clearFields() {
304 fieldTypes.clear();
305 fieldKinds.clear();
306 }
307
308 llvm::ArrayRef<mlir::Type> getFieldTypes() const { return fieldTypes; }
309 llvm::ArrayRef<cir::RecordMemberKind> getFieldKinds() const {
310 return fieldKinds;
311 }
312
313 CIRGenTypes &cirGenTypes;
314 CIRGenBuilderTy &builder;
315 const ASTContext &astContext;
316 const RecordDecl *recordDecl;
317 const CXXRecordDecl *cxxRecordDecl;
318 const ASTRecordLayout &astRecordLayout;
319 // Helpful intermediate data-structures
320 std::vector<MemberInfo> members;
321 mlir::Type unionPadding;
322 llvm::DenseMap<const FieldDecl *, CIRGenBitFieldInfo> bitFields;
323 llvm::DenseMap<const FieldDecl *, unsigned> fieldIdxMap;
324 llvm::DenseMap<const CXXRecordDecl *, unsigned> nonVirtualBases;
325 llvm::DenseMap<const CXXRecordDecl *, unsigned> virtualBases;
326 cir::CIRDataLayout dataLayout;
327
328 LLVM_PREFERRED_TYPE(bool)
329 unsigned zeroInitializable : 1;
330 LLVM_PREFERRED_TYPE(bool)
331 unsigned zeroInitializableAsBase : 1;
332 LLVM_PREFERRED_TYPE(bool)
333 unsigned packed : 1;
334
335private:
336 // Output fields, consumed by CIRGenTypes::computeRecordLayout. Private so
337 // that every append goes through addField and fieldKinds stays parallel to
338 // fieldTypes.
339 llvm::SmallVector<mlir::Type, 16> fieldTypes;
340 llvm::SmallVector<cir::RecordMemberKind> fieldKinds;
341
342 CIRRecordLowering(const CIRRecordLowering &) = delete;
343 void operator=(const CIRRecordLowering &) = delete;
344}; // CIRRecordLowering
345} // namespace
346
347CIRRecordLowering::CIRRecordLowering(CIRGenTypes &cirGenTypes,
348 const RecordDecl *recordDecl, bool packed)
349 : cirGenTypes{cirGenTypes}, builder{cirGenTypes.getBuilder()},
350 astContext{cirGenTypes.getASTContext()}, recordDecl{recordDecl},
352 astRecordLayout{
353 cirGenTypes.getASTContext().getASTRecordLayout(recordDecl)},
354 dataLayout{cirGenTypes.getCGModule().getModule()},
355 zeroInitializable{true}, zeroInitializableAsBase{true}, packed{packed} {}
356
357void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
358 CharUnits startOffset,
359 mlir::Type storageType) {
360 CIRGenBitFieldInfo &info = bitFields[fd->getCanonicalDecl()];
362 info.offset =
363 (unsigned)(getFieldBitOffset(fd) - astContext.toBits(startOffset));
364 info.size = fd->getBitWidthValue();
365 info.storageSize = getSizeInBits(storageType).getQuantity();
366 info.storageOffset = startOffset;
367 info.storageType = storageType;
368 info.name = fd->getName();
369
370 if (info.size > info.storageSize)
371 info.size = info.storageSize;
372 // Reverse the bit offsets for big endian machines. Since bitfields are laid
373 // out as packed bits within an integer-sized unit, we can imagine the bits
374 // counting from the most-significant-bit instead of the
375 // least-significant-bit.
376 if (dataLayout.isBigEndian())
377 info.offset = info.storageSize - (info.offset + info.size);
378
379 info.volatileStorageSize = 0;
380 info.volatileOffset = 0;
381 info.volatileStorageOffset = CharUnits::Zero();
382}
383
384void CIRRecordLowering::lower(bool nonVirtualBaseType) {
385 if (recordDecl->isUnion()) {
386 lowerUnion(nonVirtualBaseType);
387 computeVolatileBitfields();
388 return;
389 }
390
391 CharUnits size = nonVirtualBaseType ? astRecordLayout.getNonVirtualSize()
392 : astRecordLayout.getSize();
393
394 accumulateFields(nonVirtualBaseType);
395
396 if (cxxRecordDecl) {
397 accumulateVPtrs();
398 accumulateBases();
399 if (members.empty()) {
400 appendPaddingBytes(size);
401 computeVolatileBitfields();
402 return;
403 }
404 if (!nonVirtualBaseType)
405 accumulateVBases();
406 }
407
408 llvm::stable_sort(members);
409 // TODO: Verify bitfield clipping
411
412 // The sentinel is popped before fillOutputFields, so its kind never reaches
413 // the type.
414 members.push_back(
415 makeStorageInfo(size, getUIntNType(8), cir::RecordMemberKind::Data));
416 determinePacked(nonVirtualBaseType);
417 insertPadding();
418 members.pop_back();
419
420 calculateZeroInit();
421 fillOutputFields();
422 computeVolatileBitfields();
423}
424
425void CIRRecordLowering::fillOutputFields() {
426 for (const MemberInfo &member : members) {
427 if (member.data)
428 addField(member.data, member.memberKind);
429 if (member.kind == MemberInfo::InfoKind::Field) {
430 if (member.fieldDecl)
431 fieldIdxMap[member.fieldDecl->getCanonicalDecl()] =
432 fieldTypes.size() - 1;
433 // A bit-field carries no member of its own. It is numbered as the access
434 // unit ahead of it, whose storage it is read and written through.
435 if (!member.data) {
436 assert(member.fieldDecl &&
437 "member.data is a nullptr so member.fieldDecl should not be");
438 setBitFieldInfo(member.fieldDecl, member.offset,
439 cir::memberStorageType(fieldTypes.back()));
440 }
441 } else if (member.kind == MemberInfo::InfoKind::Base) {
442 nonVirtualBases[member.cxxRecordDecl] = fieldTypes.size() - 1;
443 } else if (member.kind == MemberInfo::InfoKind::VBase) {
444 virtualBases[member.cxxRecordDecl] = fieldTypes.size() - 1;
445 }
446 }
447}
448
450CIRRecordLowering::accumulateBitFields(RecordDecl::field_iterator field,
453 // run stores the first element of the current run of bitfields. fieldEnd is
454 // used as a special value to note that we don't have a current run. A
455 // bitfield run is a contiguous collection of bitfields that can be stored
456 // in the same storage block. Zero-sized bitfields and bitfields that would
457 // cross an alignment boundary break a run and start a new one.
459 // tail is the offset of the first bit off the end of the current run. It's
460 // used to determine if the ASTRecordLayout is treating these two bitfields
461 // as contiguous. StartBitOffset is offset of the beginning of the Run.
462 uint64_t startBitOffset, tail = 0;
463 // Where the current run's access unit sits in members, and the bit-fields
464 // it holds so far. The unit grows as new bit-fields are added.
465 size_t unitIdx = 0;
466 mlir::Type unitStorage;
467 llvm::SmallVector<cir::BitFieldDeclAttr> unitFields;
468 for (; field != fieldEnd && field->isBitField(); ++field) {
469 // Zero-width bitfields end runs.
470 if (field->isZeroLengthBitField()) {
471 members.push_back(makeZeroWidthBitFieldInfo(*field));
472 run = fieldEnd;
473 continue;
474 }
475 uint64_t bitOffset = getFieldBitOffset(*field);
476 mlir::Type type = cirGenTypes.convertTypeForMem(field->getType());
477 cir::BitFieldDeclAttr decl = getBitFieldDecl(*field);
478 // If we don't have a run yet, or don't live within the previous run's
479 // allocated storage then we allocate some storage and start a new run.
480 if (run == fieldEnd || bitOffset >= tail) {
481 run = field;
482 startBitOffset = bitOffset;
483 tail = startBitOffset + dataLayout.getTypeAllocSizeInBits(type);
484 // The access unit is added to the record before the bit-fields it
485 // holds so that it gets laid out ahead of them.
486 unitIdx = members.size();
487 unitStorage = type;
488 unitFields.assign(1, decl);
489 members.push_back(makeAccessUnitInfo(bitsToCharUnits(startBitOffset),
490 unitStorage, unitFields));
491 } else {
492 unitFields.push_back(decl);
493 members[unitIdx] = makeAccessUnitInfo(bitsToCharUnits(startBitOffset),
494 unitStorage, unitFields);
495 }
496 assert(members[unitIdx].offset == bitsToCharUnits(startBitOffset) &&
497 "unitIdx must name the current run's access unit");
498 // Bitfields get the offset of their access unit but come afterward and
499 // remain there after a stable sort.
500 members.push_back(MemberInfo(bitsToCharUnits(startBitOffset),
501 MemberInfo::InfoKind::Field, nullptr,
502 cir::RecordMemberKind::Data, *field));
503 }
504 return field;
505 }
506
507 CharUnits regSize =
508 bitsToCharUnits(astContext.getTargetInfo().getRegisterWidth());
509 unsigned charBits = astContext.getCharWidth();
510
511 // Data about the start of the span we're accumulating to create an access
512 // unit from. 'Begin' is the first bitfield of the span. If 'begin' is
513 // 'fieldEnd', we've not got a current span. The span starts at the
514 // 'beginOffset' character boundary. 'bitSizeSinceBegin' is the size (in bits)
515 // of the span -- this might include padding when we've advanced to a
516 // subsequent bitfield run.
517 RecordDecl::field_iterator begin = fieldEnd;
518 CharUnits beginOffset;
519 uint64_t bitSizeSinceBegin;
520
521 // The (non-inclusive) end of the largest acceptable access unit we've found
522 // since 'begin'. If this is 'begin', we're gathering the initial set of
523 // bitfields of a new span. 'bestEndOffset' is the end of that acceptable
524 // access unit -- it might extend beyond the last character of the bitfield
525 // run, using available padding characters.
526 RecordDecl::field_iterator bestEnd = begin;
527 CharUnits bestEndOffset;
528 bool bestClipped; // Whether the representation must be in a byte array.
529
530 for (;;) {
531 // atAlignedBoundary is true if 'field' is the (potential) start of a new
532 // span (or the end of the bitfields). When true, limitOffset is the
533 // character offset of that span and barrier indicates whether the new
534 // span cannot be merged into the current one.
535 bool atAlignedBoundary = false;
536 bool barrier = false; // a barrier can be a zero Bit Width or non bit member
537 if (field != fieldEnd && field->isBitField()) {
538 uint64_t bitOffset = getFieldBitOffset(*field);
539 if (begin == fieldEnd) {
540 // Beginning a new span.
541 begin = field;
542 bestEnd = begin;
543
544 assert((bitOffset % charBits) == 0 && "Not at start of char");
545 beginOffset = bitsToCharUnits(bitOffset);
546 bitSizeSinceBegin = 0;
547 } else if ((bitOffset % charBits) != 0) {
548 // Bitfield occupies the same character as previous bitfield, it must be
549 // part of the same span. This can include zero-length bitfields, should
550 // the target not align them to character boundaries. Such non-alignment
551 // is at variance with the standards, which require zero-length
552 // bitfields be a barrier between access units. But of course we can't
553 // achieve that in the middle of a character.
554 assert(bitOffset ==
555 astContext.toBits(beginOffset) + bitSizeSinceBegin &&
556 "Concatenating non-contiguous bitfields");
557 } else {
558 // Bitfield potentially begins a new span. This includes zero-length
559 // bitfields on non-aligning targets that lie at character boundaries
560 // (those are barriers to merging).
561 if (field->isZeroLengthBitField())
562 barrier = true;
563 atAlignedBoundary = true;
564 }
565 } else {
566 // We've reached the end of the bitfield run. Either we're done, or this
567 // is a barrier for the current span.
568 if (begin == fieldEnd)
569 break;
570
571 barrier = true;
572 atAlignedBoundary = true;
573 }
574
575 // 'installBest' indicates whether we should create an access unit for the
576 // current best span: fields ['begin', 'bestEnd') occupying characters
577 // ['beginOffset', 'bestEndOffset').
578 bool installBest = false;
579 if (atAlignedBoundary) {
580 // 'field' is the start of a new span or the end of the bitfields. The
581 // just-seen span now extends to 'bitSizeSinceBegin'.
582
583 // Determine if we can accumulate that just-seen span into the current
584 // accumulation.
585 CharUnits accessSize = bitsToCharUnits(bitSizeSinceBegin + charBits - 1);
586 if (bestEnd == begin) {
587 // This is the initial run at the start of a new span. By definition,
588 // this is the best seen so far.
589 bestEnd = field;
590 bestEndOffset = beginOffset + accessSize;
591 // Assume clipped until proven not below.
592 bestClipped = true;
593 if (!bitSizeSinceBegin)
594 // A zero-sized initial span -- this will install nothing and reset
595 // for another.
596 installBest = true;
597 } else if (accessSize > regSize) {
598 // Accumulating the just-seen span would create a multi-register access
599 // unit, which would increase register pressure.
600 installBest = true;
601 }
602
603 if (!installBest) {
604 // Determine if accumulating the just-seen span will create an expensive
605 // access unit or not.
606 mlir::Type type = getUIntNType(astContext.toBits(accessSize));
608 // Unaligned accesses are expensive. Only accumulate if the new unit
609 // is naturally aligned. Otherwise install the best we have, which is
610 // either the initial access unit (can't do better), or a naturally
611 // aligned accumulation (since we would have already installed it if
612 // it wasn't naturally aligned).
613 CharUnits align = getMemberAlignment(type);
614 if (align > astRecordLayout.getAlignment()) {
615 // The alignment required is greater than the containing structure
616 // itself.
617 installBest = true;
618 } else if (!beginOffset.isMultipleOf(align)) {
619 // The access unit is not at a naturally aligned offset within the
620 // structure.
621 installBest = true;
622 }
623
624 if (installBest && bestEnd == field) {
625 // We're installing the first span, whose clipping was presumed
626 // above. Compute it correctly.
627 if (getSize(type) == accessSize)
628 bestClipped = false;
629 }
630 }
631
632 if (!installBest) {
633 // Find the next used storage offset to determine what the limit of
634 // the current span is. That's either the offset of the next field
635 // with storage (which might be field itself) or the end of the
636 // non-reusable tail padding.
637 CharUnits limitOffset;
638 for (auto probe = field; probe != fieldEnd; ++probe)
639 if (!CodeGenUtils::isEmptyFieldForLayout(astContext, *probe)) {
640 // A member with storage sets the limit.
641 assert((getFieldBitOffset(*probe) % charBits) == 0 &&
642 "Next storage is not byte-aligned");
643 limitOffset = bitsToCharUnits(getFieldBitOffset(*probe));
644 goto FoundLimit;
645 }
646 limitOffset = cxxRecordDecl ? astRecordLayout.getNonVirtualSize()
647 : astRecordLayout.getDataSize();
648
649 FoundLimit:
650 CharUnits typeSize = getSize(type);
651 if (beginOffset + typeSize <= limitOffset) {
652 // There is space before limitOffset to create a naturally-sized
653 // access unit.
654 bestEndOffset = beginOffset + typeSize;
655 bestEnd = field;
656 bestClipped = false;
657 }
658 if (barrier) {
659 // The next field is a barrier that we cannot merge across.
660 installBest = true;
661 } else if (cirGenTypes.getCGModule()
663 .FineGrainedBitfieldAccesses) {
664 installBest = true;
665 } else {
666 // Otherwise, we're not installing. Update the bit size
667 // of the current span to go all the way to limitOffset, which is
668 // the (aligned) offset of next bitfield to consider.
669 bitSizeSinceBegin = astContext.toBits(limitOffset - beginOffset);
670 }
671 }
672 }
673 }
674
675 if (installBest) {
676 assert((field == fieldEnd || !field->isBitField() ||
677 (getFieldBitOffset(*field) % charBits) == 0) &&
678 "Installing but not at an aligned bitfield or limit");
679 CharUnits accessSize = bestEndOffset - beginOffset;
680 if (!accessSize.isZero()) {
681 // Add the storage member for the access unit to the record. The
682 // bitfields get the offset of their storage but come afterward and
683 // remain there after a stable sort.
684 mlir::Type type;
685 if (bestClipped) {
686 assert(getSize(getUIntNType(astContext.toBits(accessSize))) >
687 accessSize &&
688 "Clipped access need not be clipped");
689 type = getByteArrayType(accessSize);
690 } else {
691 type = getUIntNType(astContext.toBits(accessSize));
692 assert(getSize(type) == accessSize &&
693 "Unclipped access must be clipped");
694 }
695 // A zero-length bit-field in the span was given a member of its own
696 // when it was accumulated, and belongs to no access unit, so it is not
697 // one of the fields this unit holds.
698 llvm::SmallVector<cir::BitFieldDeclAttr> unitFields;
699 for (auto occupant = begin; occupant != bestEnd; ++occupant)
700 if (!occupant->isZeroLengthBitField())
701 unitFields.push_back(getBitFieldDecl(*occupant));
702 assert(!unitFields.empty() && "an access unit holds a bit-field");
703 members.push_back(makeAccessUnitInfo(beginOffset, type, unitFields));
704
705 for (; begin != bestEnd; ++begin)
706 if (!begin->isZeroLengthBitField())
707 members.push_back(MemberInfo(beginOffset,
708 MemberInfo::InfoKind::Field, nullptr,
709 cir::RecordMemberKind::Data, *begin));
710 }
711 // Reset to start a new span.
712 field = bestEnd;
713 begin = fieldEnd;
714 } else {
715 assert(field != fieldEnd && field->isBitField() &&
716 "Accumulating past end of bitfields");
717 assert(!barrier && "Accumulating across barrier");
718 if (field->isZeroLengthBitField())
719 members.push_back(makeZeroWidthBitFieldInfo(*field));
720 // Accumulate this bitfield into the current (potential) span.
721 bitSizeSinceBegin += field->getBitWidthValue();
722 ++field;
723 }
724 }
725
726 return field;
727}
728
729void CIRRecordLowering::accumulateFields(bool nonVirtualBaseType) {
730 for (RecordDecl::field_iterator field = recordDecl->field_begin(),
731 fieldEnd = recordDecl->field_end();
732 field != fieldEnd;) {
733 if (field->isBitField()) {
734 field = accumulateBitFields(field, fieldEnd);
735 assert((field == fieldEnd || !field->isBitField()) &&
736 "Failed to accumulate all the bitfields");
737 } else if (CodeGenUtils::isEmptyFieldForLayout(astContext, *field) &&
738 field->isPotentiallyOverlapping()) {
739 // We lay out normal empty fields, as they are required for GEPs/getting
740 // function pointers. However 'no-unique-address' lends some additional
741 // complexity. These fields take up no real space, but would also have to
742 // be the correct 'GEP' offset to work here, but then mess with the
743 // layout. We likely need to come up with a new 'type' to support these,
744 // then figure out some way to lower these to the correct offset, likely
745 // by calculating the correct offset into the struct, and forming a
746 // replacement by-byte GEP in LowerToLLVM. However, this is only a
747 // problem with taking the address of one of these, so it is in practice
748 // not a horrifyingly problematic issue.
750 // Dropping the field leaves no member to mark, so its bytes read as
751 // padding. That is only sound when the field carries no ABI data, so
752 // make sure we add a member for it. if it does.
753 if (!isEmptyFieldForABI(astContext, *field))
754 members.push_back(
755 MemberInfo(bitsToCharUnits(getFieldBitOffset(*field)),
756 MemberInfo::InfoKind::Field,
757 getStorageType(field->getType()->getAsCXXRecordDecl()),
758 getFieldMemberKind(*field), *field));
759 ++field;
760 } else {
761 // Use base subobject layout for potentially-overlapping fields,
762 // as it is done in RecordLayoutBuilder.
763 //
764 // The mark comes from isEmptyFieldForABI, not the isEmptyFieldForLayout
765 // above. Neither predicate subsumes the other.
766 members.push_back(MemberInfo(
767 bitsToCharUnits(getFieldBitOffset(*field)),
768 MemberInfo::InfoKind::Field,
769 field->isPotentiallyOverlapping()
770 ? getStorageType(field->getType()->getAsCXXRecordDecl())
771 : getStorageType(*field),
772 getFieldMemberKind(*field), *field));
773 ++field;
774 }
775 }
776}
777
778void CIRRecordLowering::calculateZeroInit() {
779 for (const MemberInfo &member : members) {
780 if (member.kind == MemberInfo::InfoKind::Field) {
781 if (!member.fieldDecl || isZeroInitializable(member.fieldDecl))
782 continue;
783 zeroInitializable = zeroInitializableAsBase = false;
784 return;
785 } else if (member.kind == MemberInfo::InfoKind::Base ||
786 member.kind == MemberInfo::InfoKind::VBase) {
787 if (isZeroInitializable(member.cxxRecordDecl))
788 continue;
789 zeroInitializable = false;
790 if (member.kind == MemberInfo::InfoKind::Base)
791 zeroInitializableAsBase = false;
792 }
793 }
794}
795
796void CIRRecordLowering::determinePacked(bool nvBaseType) {
797 if (packed)
798 return;
799 CharUnits alignment = CharUnits::One();
800 CharUnits nvAlignment = CharUnits::One();
801 CharUnits nvSize = !nvBaseType && cxxRecordDecl
802 ? astRecordLayout.getNonVirtualSize()
803 : CharUnits::Zero();
804
805 for (const MemberInfo &member : members) {
806 // A member that owns no bytes sits inside another member's storage, whose
807 // own offset and alignment are what decide packing.
808 if (!ownsBytes(member))
809 continue;
810 // If any member falls at an offset that it not a multiple of its alignment,
811 // then the entire record must be packed.
812 if (!member.offset.isMultipleOf(getMemberAlignment(member.data)))
813 packed = true;
814 if (member.offset < nvSize)
815 nvAlignment = std::max(nvAlignment, getMemberAlignment(member.data));
816 alignment = std::max(alignment, getMemberAlignment(member.data));
817 }
818 // If the size of the record (the capstone's offset) is not a multiple of the
819 // record's alignment, it must be packed.
820 if (!members.back().offset.isMultipleOf(alignment))
821 packed = true;
822 // If the non-virtual sub-object is not a multiple of the non-virtual
823 // sub-object's alignment, it must be packed. We cannot have a packed
824 // non-virtual sub-object and an unpacked complete object or vise versa.
825 if (!nvSize.isMultipleOf(nvAlignment))
826 packed = true;
827 // Update the alignment of the sentinel.
828 if (!packed)
829 members.back().data = getUIntNType(astContext.toBits(alignment));
830}
831
832void CIRRecordLowering::insertPadding() {
833 std::vector<std::pair<CharUnits, CharUnits>> padding;
834 CharUnits size = CharUnits::Zero();
835 for (const MemberInfo &member : members) {
836 if (!member.data)
837 continue;
838 // A consumer recovers a member's offset by accumulating the sizes of the
839 // members before it, so the padding a zero-width bit-field sits inside has
840 // to be split at its offset for that sum to come out right. The offset
841 // can sit behind the running size, since the access unit covering the bits
842 // around it may be wider than the offset it was declared at.
843 if (!ownsBytes(member)) {
844 if (member.offset > size) {
845 padding.push_back(std::make_pair(size, member.offset - size));
846 size = member.offset;
847 }
848 continue;
849 }
850 CharUnits offset = member.offset;
851 assert(offset >= size);
852 // Insert padding if we need to.
853 if (offset != size.alignTo(packed ? CharUnits::One()
854 : getMemberAlignment(member.data)))
855 padding.push_back(std::make_pair(size, offset - size));
856 size = offset + getSize(member.data);
857 }
858 if (padding.empty())
859 return;
860 // Add the padding to the Members list and sort it.
861 for (const std::pair<CharUnits, CharUnits> &paddingPair : padding)
862 members.push_back(makeStorageInfo(paddingPair.first,
863 getByteArrayType(paddingPair.second),
864 cir::RecordMemberKind::Pad));
865 llvm::stable_sort(members);
866}
867
868static cir::ArgPassingKind
870 switch (kind) {
872 return cir::ArgPassingKind::CanPassInRegs;
874 return cir::ArgPassingKind::CannotPassInRegs;
876 return cir::ArgPassingKind::CanNeverPassInRegs;
877 }
878 llvm_unreachable("unknown RecordArgPassingKind");
879}
880
881/// Whether the member kinds on \p recordTy answer the record's ABI emptiness
882/// the same way the AST predicate does.
883[[maybe_unused]] static bool
884marksMatchABIEmptiness(const ASTContext &astContext, const RecordDecl *rd,
885 cir::RecordType recordTy) {
886 return recordTy.isEmptyForABI() ==
887 isEmptyRecordForABI(astContext, astContext.getCanonicalTagType(rd));
888}
889
890std::unique_ptr<CIRGenRecordLayout>
892 CIRRecordLowering lowering(*this, rd, /*packed=*/false);
893 assert(ty->isIncomplete() && "recomputing record layout?");
894 lowering.lower(/*nonVirtualBaseType=*/false);
895
896 // If we're in C++, compute the base subobject type. For C++ records baseTy
897 // defaults to the complete object type and is replaced by a distinct,
898 // smaller record only when the record has tail padding an enclosing
899 // [[no_unique_address]] field can reuse. We must populate baseTy even when
900 // it equals ty because callers such as getStorageType(const CXXRecordDecl *)
901 // read it unconditionally when laying out potentially-overlapping
902 // ([[no_unique_address]]) fields; a null baseTy would otherwise propagate as
903 // a null mlir::Type into the members vector and trip the !empty() assertion
904 // in fillOutputFields.
905 cir::RecordType baseTy;
906 if (llvm::isa<CXXRecordDecl>(rd)) {
907 baseTy = *ty;
908 // A record needs a distinct base-subobject type when its tail padding can
909 // be reused by an enclosing [[no_unique_address]] field, i.e. when the
910 // non-virtual size differs from the complete size. This matches classic
911 // CodeGen and covers unions too: a union's non-virtual size already tracks
912 // its reusable tail padding (and stays at the minimum union size when the
913 // union is empty, so a zero-data union does not spuriously qualify).
914 if (lowering.astRecordLayout.getNonVirtualSize() !=
915 lowering.astRecordLayout.getSize()) {
916 CIRRecordLowering baseLowering(*this, rd, /*Packed=*/lowering.packed);
917 baseLowering.lower(/*nonVirtualBaseType=*/true);
918 std::string baseIdentifier = getRecordTypeName(rd, ".base");
919 baseTy = builder.getCompleteNamedRecordType(
920 baseLowering.getFieldTypes(), baseLowering.packed, baseIdentifier,
921 baseLowering.getFieldKinds());
922 // TODO(cir): add something like addRecordTypeName
923
924 // BaseTy and Ty must agree on their packedness for getCIRFieldNo to work
925 // on both of them with the same index. Unions are exempt: CIR derives a
926 // union's packedness from its layout size, which is the data size for the
927 // base subobject but the full size for the complete object, so the two
928 // can legitimately disagree. (Classic CodeGen derives both from the data
929 // size and so needs no such exemption.)
930 assert((rd->isUnion() || lowering.packed == baseLowering.packed) &&
931 "Non-virtual and complete types must agree on packedness");
932 // Emptiness is a property of the decl, so the base subobject must answer
933 // the same way the complete object does. The two are not comparable
934 // mark by mark: they see different sizes and so different tail padding.
935 assert((marksMatchABIEmptiness(astContext, rd, baseTy) ||
936 cgm.getDiags().hasErrorOccurred()) &&
937 "base subobject member kinds must reproduce its ABI emptiness");
938 }
939 }
940
941 // Fill in the record *after* computing the base type. Filling in the body
942 // signifies that the type is no longer opaque and record layout is complete,
943 // but we may need to recursively layout rd while laying D out as a base type.
945 ty->complete(lowering.getFieldTypes(), lowering.packed, lowering.unionPadding,
946 lowering.getFieldKinds());
947
948 // The marks exist so that emptiness can be read off the type, so check that
949 // answer against the AST predicate on every record CIRGen lays out. This
950 // does not check the individual marks, only what they add up to. The marks
951 // themselves are pinned by clang/test/CIR/CodeGen/record-member-kinds.*.
952 assert((marksMatchABIEmptiness(astContext, rd, *ty) ||
953 cgm.getDiags().hasErrorOccurred()) &&
954 "member kinds must reproduce the ABI emptiness of the record");
955
956 // Queue ABI metadata for the module-level cir.record_layouts attribute.
957 if (ty->getName()) {
958 mlir::MLIRContext *mlirCtx = ty->getContext();
959 cir::ArgPassingKind apk =
961
962 bool hasTrivialDestructor = true;
963 if (auto *cxxRD = dyn_cast<CXXRecordDecl>(rd))
964 hasTrivialDestructor = cxxRD->hasTrivialDestructor();
965 const auto &astLayout = astContext.getASTRecordLayout(rd);
966 uint64_t recordAlignInBytes = astLayout.getAlignment().getQuantity();
967 uint64_t unadjustedAlignInBytes =
968 astLayout.getUnadjustedAlignment().getQuantity();
969 bool isTransparentUnion = rd->hasAttr<TransparentUnionAttr>();
970
971 cgm.addRecordLayout(
972 ty->getName(),
973 cir::RecordLayoutAttr::get(mlirCtx, apk, hasTrivialDestructor,
974 recordAlignInBytes, unadjustedAlignInBytes,
976 }
977
978 auto rl = std::make_unique<CIRGenRecordLayout>(
979 ty ? *ty : cir::RecordType{}, baseTy ? baseTy : cir::RecordType{},
980 (bool)lowering.zeroInitializable, (bool)lowering.zeroInitializableAsBase);
981
982 rl->nonVirtualBases.swap(lowering.nonVirtualBases);
983 rl->completeObjectVirtualBases.swap(lowering.virtualBases);
984
985 // Add all the field numbers.
986 rl->fieldIdxMap.swap(lowering.fieldIdxMap);
987
988 rl->bitFields.swap(lowering.bitFields);
989
990 // Dump the layout, if requested.
991 if (getASTContext().getLangOpts().DumpRecordLayouts) {
992 llvm::outs() << "\n*** Dumping CIRgen Record Layout\n";
993 llvm::outs() << "Record: ";
994 rd->dump(llvm::outs());
995 llvm::outs() << "\nLayout: ";
996 rl->print(llvm::outs());
997 }
998
999 // TODO: implement verification
1000 return rl;
1001}
1002
1003void CIRGenRecordLayout::print(raw_ostream &os) const {
1004 os << "<CIRecordLayout\n";
1005 os << " CIR Type:" << completeObjectType << "\n";
1006 if (baseSubobjectType)
1007 os << " NonVirtualBaseCIRType:" << baseSubobjectType << "\n";
1008 os << " IsZeroInitializable:" << zeroInitializable << "\n";
1009 os << " BitFields:[\n";
1010 std::vector<std::pair<unsigned, const CIRGenBitFieldInfo *>> bitInfo;
1011 for (auto &[decl, info] : bitFields) {
1012 const RecordDecl *rd = decl->getParent();
1013 unsigned index = 0;
1014 for (RecordDecl::field_iterator it = rd->field_begin(); *it != decl; ++it)
1015 ++index;
1016 bitInfo.push_back(std::make_pair(index, &info));
1017 }
1018 llvm::array_pod_sort(bitInfo.begin(), bitInfo.end());
1019 for (std::pair<unsigned, const CIRGenBitFieldInfo *> &info : bitInfo) {
1020 os.indent(4);
1021 info.second->print(os);
1022 os << "\n";
1023 }
1024 os << " ]>\n";
1025}
1026
1027void CIRGenBitFieldInfo::print(raw_ostream &os) const {
1028 os << "<CIRBitFieldInfo" << " name:" << name << " offset:" << offset
1029 << " size:" << size << " isSigned:" << isSigned
1030 << " storageSize:" << storageSize
1031 << " storageOffset:" << storageOffset.getQuantity()
1032 << " volatileOffset:" << volatileOffset
1033 << " volatileStorageSize:" << volatileStorageSize
1034 << " volatileStorageOffset:" << volatileStorageOffset.getQuantity() << ">";
1035}
1036
1037void CIRGenRecordLayout::dump() const { print(llvm::errs()); }
1038
1039void CIRGenBitFieldInfo::dump() const { print(llvm::errs()); }
1040
1041void CIRRecordLowering::lowerUnion(bool nonVirtualBaseType) {
1042 // The base-subobject layout of a union is sized to its data size rather than
1043 // its full size. A union can have reusable tail padding when one of its
1044 // members is a [[no_unique_address]] field that itself has tail padding, so
1045 // an enclosing [[no_unique_address]] union field must use this smaller type.
1046 CharUnits layoutSize = nonVirtualBaseType ? astRecordLayout.getDataSize()
1047 : astRecordLayout.getSize();
1048 // Accumulate bitfields and fields, and figure out what our difference between
1049 // storage type and padding is.
1050
1051 // First, accumulate all the types.
1052 for (const FieldDecl *field : recordDecl->fields()) {
1053 mlir::Type fieldType;
1054 cir::RecordMemberKind fieldKind;
1055 if (field->isBitField()) {
1056 if (field->isZeroLengthBitField())
1057 continue;
1058 // Every variant starts at offset zero, so a bit-field variant is an
1059 // access unit of its own, holding that one field.
1060 mlir::Type unitStorage =
1061 getBitfieldStorageType(field->getBitWidthValue());
1062 setBitFieldInfo(field, CharUnits::Zero(), unitStorage);
1063 MemberInfo unit = makeAccessUnitInfo(CharUnits::Zero(), unitStorage,
1064 getBitFieldDecl(field));
1065 fieldType = unit.data;
1066 fieldKind = unit.memberKind;
1067 } else {
1068 fieldType = getStorageType(field);
1069 fieldKind = getFieldMemberKind(field);
1070 }
1071
1072 fieldIdxMap[field->getCanonicalDecl()] = 0;
1073 addField(fieldType, fieldKind);
1074 }
1075
1076 // Compute zero-initializable status.
1077 // This union might not be zero initialized: it may contain a pointer to
1078 // data member which might have some exotic initialization sequence.
1079 // This chooses the first 'named' member and is zero-initializable based on
1080 // that.
1081 auto hasNamedMember = [](const FieldDecl *curField) -> bool {
1082 const auto *rd = curField->getType()->getAsRecordDecl();
1083 return rd && rd->findFirstNamedDataMember();
1084 };
1085 // Whether this is usable for zero-init as a 'named member'. It is a field
1086 // with a name (or a record type with a named member itself), that isn't a
1087 // zero-width bitfield.
1088 auto isNamedMember = [hasNamedMember](const FieldDecl *curField) -> bool {
1089 if (curField->isZeroLengthBitField())
1090 return false;
1091 return curField->getIdentifier() || hasNamedMember(curField);
1092 };
1093 auto firstNamedMemberItr = llvm::find_if(recordDecl->fields(), isNamedMember);
1094
1095 if (firstNamedMemberItr != recordDecl->fields().end() &&
1096 !isZeroInitializable(*firstNamedMemberItr))
1097 zeroInitializable = zeroInitializableAsBase = false;
1098
1099 // If we have no candidates for storage, we are JUST padding.
1100 if (getFieldTypes().empty()) {
1101 appendPaddingBytes(layoutSize);
1102 return;
1103 }
1104
1105 mlir::Type storageType =
1106 cir::UnionType::getUnionStorageType(dataLayout.layout, getFieldTypes());
1107
1108 // If our storage size was bigger than our required size (can happen in the
1109 // case of packed bitfields on Itanium) then just use an I8 array.
1110 if (layoutSize < getSize(storageType))
1111 storageType = getByteArrayType(layoutSize);
1112
1113 // The base-subobject record is built as a struct from fieldTypes, so add
1114 // the storage type and any trailing padding as ordinary fields rather than
1115 // routing padding through the union's single tail-padding slot.
1116 if (nonVirtualBaseType) {
1117 // A bit-field mark here says the stand-in's extent is not a declared
1118 // extent, not that its storage came from a bit-field: UnionBitAndWide in
1119 // clang/test/CIR/CodeGen/no-unique-address.cpp takes its double as storage
1120 // and still marks bitfield. The stand-in describes every variant, so it
1121 // takes the storage type rather than any one variant's `!cir.bitfield`,
1122 // and is the one bit-field-marked member that is not one. Computed before
1123 // clearFields() drops the variant marks.
1124 const cir::RecordMemberKind storageKind = makeMemberKind(
1125 /*holdsData=*/cir::anyMemberHoldsDataForABI(getFieldKinds()),
1126 /*isNamedBitField=*/llvm::any_of(getFieldKinds(),
1128 clearFields();
1129 addField(storageType, storageKind);
1130 CharUnits padding = layoutSize - getSize(storageType);
1131 if (!padding.isZero())
1132 addField(getByteArrayType(padding), cir::RecordMemberKind::Pad);
1133 } else {
1134 // Else we just add padding normally.
1135 appendPaddingBytes(layoutSize - getSize(storageType));
1136 }
1137 packed = !layoutSize.isMultipleOf(getMemberAlignment(storageType));
1138}
1139
1140/// The AAPCS that defines that, when possible, bit-fields should
1141/// be accessed using containers of the declared type width:
1142/// When a volatile bit-field is read, and its container does not overlap with
1143/// any non-bit-field member or any zero length bit-field member, its container
1144/// must be read exactly once using the access width appropriate to the type of
1145/// the container. When a volatile bit-field is written, and its container does
1146/// not overlap with any non-bit-field member or any zero-length bit-field
1147/// member, its container must be read exactly once and written exactly once
1148/// using the access width appropriate to the type of the container. The two
1149/// accesses are not atomic.
1150///
1151/// Enforcing the width restriction can be disabled using
1152/// -fno-aapcs-bitfield-width.
1153void CIRRecordLowering::computeVolatileBitfields() {
1154 if (!CodeGenUtils::isAAPCS(astContext.getTargetInfo()) ||
1155 !cirGenTypes.getCGModule().getCodeGenOpts().AAPCSBitfieldWidth)
1156 return;
1157
1158 for (auto &[field, info] : bitFields) {
1159 mlir::Type resLTy = cirGenTypes.convertTypeForMem(field->getType());
1160
1161 if (astContext.toBits(astRecordLayout.getAlignment()) <
1162 getSizeInBits(resLTy).getQuantity())
1163 continue;
1164
1165 // CIRRecordLowering::setBitFieldInfo() pre-adjusts the bit-field offsets
1166 // for big-endian targets, but it assumes a container of width
1167 // info.storageSize. Since AAPCS uses a different container size (width
1168 // of the type), we first undo that calculation here and redo it once
1169 // the bit-field offset within the new container is calculated.
1170 const unsigned oldOffset =
1171 isBigEndian() ? info.storageSize - (info.offset + info.size)
1172 : info.offset;
1173 // Offset to the bit-field from the beginning of the struct.
1174 const unsigned absoluteOffset =
1175 astContext.toBits(info.storageOffset) + oldOffset;
1176
1177 // Container size is the width of the bit-field type.
1178 const unsigned storageSize = getSizeInBits(resLTy).getQuantity();
1179 // Nothing to do if the access uses the desired
1180 // container width and is naturally aligned.
1181 if (info.storageSize == storageSize && (oldOffset % storageSize == 0))
1182 continue;
1183
1184 // Offset within the container.
1185 unsigned offset = absoluteOffset & (storageSize - 1);
1186 // Bail out if an aligned load of the container cannot cover the entire
1187 // bit-field. This can happen for example, if the bit-field is part of a
1188 // packed struct. AAPCS does not define access rules for such cases, we let
1189 // clang to follow its own rules.
1190 if (offset + info.size > storageSize)
1191 continue;
1192
1193 // Re-adjust offsets for big-endian targets.
1194 if (isBigEndian())
1195 offset = storageSize - (offset + info.size);
1196
1197 const CharUnits storageOffset =
1198 astContext.toCharUnitsFromBits(absoluteOffset & ~(storageSize - 1));
1199 const CharUnits end = storageOffset +
1200 astContext.toCharUnitsFromBits(storageSize) -
1202
1203 const ASTRecordLayout &layout =
1204 astContext.getASTRecordLayout(field->getParent());
1205 // If we access outside memory outside the record, than bail out.
1206 const CharUnits recordSize = layout.getSize();
1207 if (end >= recordSize)
1208 continue;
1209
1210 // Bail out if performing this load would access non-bit-fields members.
1211 bool conflict = false;
1212 for (const auto *f : recordDecl->fields()) {
1213 // Allow sized bit-fields overlaps.
1214 if (f->isBitField() && !f->isZeroLengthBitField())
1215 continue;
1216
1217 const CharUnits fOffset = astContext.toCharUnitsFromBits(
1218 layout.getFieldOffset(f->getFieldIndex()));
1219
1220 // As C11 defines, a zero sized bit-field defines a barrier, so
1221 // fields after and before it should be race condition free.
1222 // The AAPCS acknowledges it and imposes no restritions when the
1223 // natural container overlaps a zero-length bit-field.
1224 if (f->isZeroLengthBitField()) {
1225 if (end > fOffset && storageOffset < fOffset) {
1226 conflict = true;
1227 break;
1228 }
1229 }
1230
1231 const CharUnits fEnd =
1232 fOffset +
1233 astContext.toCharUnitsFromBits(
1234 getSizeInBits(cirGenTypes.convertTypeForMem(f->getType()))
1235 .getQuantity()) -
1237 // If no overlap, continue.
1238 if (end < fOffset || fEnd < storageOffset)
1239 continue;
1240
1241 // The desired load overlaps a non-bit-field member, bail out.
1242 conflict = true;
1243 break;
1244 }
1245
1246 if (conflict)
1247 continue;
1248 // Write the new bit-field access parameters.
1249 // As the storage offset now is defined as the number of elements from the
1250 // start of the structure, we should divide the Offset by the element size.
1251 info.volatileStorageOffset =
1252 storageOffset /
1253 astContext.toCharUnitsFromBits(storageSize).getQuantity();
1254 info.volatileStorageSize = storageSize;
1255 info.volatileOffset = offset;
1256 }
1257}
1258
1259void CIRRecordLowering::accumulateBases() {
1260 // If we've got a primary virtual base, we need to add it with the bases.
1261 if (astRecordLayout.isPrimaryBaseVirtual()) {
1262 const CXXRecordDecl *baseDecl = astRecordLayout.getPrimaryBase();
1263 members.push_back(MemberInfo(CharUnits::Zero(), MemberInfo::InfoKind::Base,
1264 getStorageType(baseDecl),
1265 getBaseMemberKind(baseDecl), baseDecl));
1266 }
1267
1268 // Accumulate the non-virtual bases.
1269 for (const auto &base : cxxRecordDecl->bases()) {
1270 if (base.isVirtual())
1271 continue;
1272 // Bases can be zero-sized even if not technically empty if they
1273 // contain only a trailing array member.
1274 const CXXRecordDecl *baseDecl = base.getType()->getAsCXXRecordDecl();
1275 if (!baseDecl->isEmpty() &&
1276 !astContext.getASTRecordLayout(baseDecl).getNonVirtualSize().isZero()) {
1277 members.push_back(MemberInfo(astRecordLayout.getBaseClassOffset(baseDecl),
1278 MemberInfo::InfoKind::Base,
1279 getStorageType(baseDecl),
1280 getBaseMemberKind(baseDecl), baseDecl));
1281 }
1282 }
1283}
1284
1285void CIRRecordLowering::accumulateVBases() {
1286 for (const auto &base : cxxRecordDecl->vbases()) {
1287 const CXXRecordDecl *baseDecl = base.getType()->getAsCXXRecordDecl();
1288 if (CodeGenUtils::isEmptyRecordForLayout(astContext, base.getType()))
1289 continue;
1290 CharUnits offset = astRecordLayout.getVBaseClassOffset(baseDecl);
1291 // If the vbase is a primary virtual base of some base, then it doesn't
1292 // get its own storage location but instead lives inside of that base.
1293 if (CodeGenUtils::isOverlappingVBaseABI(astContext) &&
1294 astContext.isNearlyEmpty(baseDecl) &&
1295 !CodeGenUtils::hasOwnStorage(astContext, cxxRecordDecl, baseDecl)) {
1296 members.push_back(MemberInfo(offset, MemberInfo::InfoKind::VBase, nullptr,
1297 cir::RecordMemberKind::Data, baseDecl));
1298 continue;
1299 }
1300 // If we've got a vtordisp, add it as a storage type.
1301 if (astRecordLayout.getVBaseOffsetsMap()
1302 .find(baseDecl)
1303 ->second.hasVtorDisp())
1304 members.push_back(makeStorageInfo(offset - CharUnits::fromQuantity(4),
1305 getUIntNType(32),
1306 cir::RecordMemberKind::Data));
1307 members.push_back(MemberInfo(offset, MemberInfo::InfoKind::VBase,
1308 getStorageType(baseDecl),
1309 getBaseMemberKind(baseDecl), baseDecl));
1310 }
1311}
1312
1313void CIRRecordLowering::accumulateVPtrs() {
1314 if (astRecordLayout.hasOwnVFPtr())
1315 members.push_back(MemberInfo(CharUnits::Zero(), MemberInfo::InfoKind::VFPtr,
1316 getVFPtrType(), cir::RecordMemberKind::Data));
1317
1318 if (astRecordLayout.hasOwnVBPtr())
1319 cirGenTypes.getCGModule().errorNYI(recordDecl->getSourceRange(),
1320 "accumulateVPtrs: hasOwnVBPtr");
1321}
1322
1323mlir::Type CIRRecordLowering::getVFPtrType() {
1324 return cir::VPtrType::get(builder.getContext());
1325}
Defines the clang::ASTContext interface.
static bool marksMatchABIEmptiness(const ASTContext &astContext, const RecordDecl *rd, cir::RecordType recordTy)
Whether the member kinds on recordTy answer the record's ABI emptiness the same way the AST predicate...
static cir::ArgPassingKind convertRecordArgPassingKind(RecordArgPassingKind kind)
static bool isTransparentUnion(QualType T)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static void print(llvm::raw_ostream &OS, const T &V, const Context &Ctx, QualType Ty)
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
mlir::DataLayout layout
bool isBigEndian() const
llvm::TypeSize getTypeAllocSizeInBits(mlir::Type ty) const
Returns the offset in bits between successive objects of the specified type, including alignment padd...
C++ view class that accepts both !cir.struct and !cir.union types.
Definition CIRTypes.h:150
bool isIncomplete() const
Definition CIRTypes.cpp:658
bool isEmptyForABI() const
Whether no member holds data.
Definition CIRTypes.cpp:741
mlir::StringAttr getName() const
Definition CIRTypes.cpp:653
void complete(llvm::ArrayRef< mlir::Type > members, bool packed, mlir::Type padding, llvm::ArrayRef< RecordMemberKind > memberKinds)
padding is union-only.
Definition CIRTypes.cpp:696
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:245
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
bool isNearlyEmpty(const CXXRecordDecl *RD) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:971
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
bool hasOwnVBPtr() const
hasOwnVBPtr - Does this class provide its own virtual-base table pointer, rather than inheriting one ...
CharUnits getSize() const
getSize - Get the record size in characters.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getDataSize() const
getDataSize() - Get the record data size, which is the record size without tail padding,...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
const clang::CodeGenOptions & getCodeGenOpts() const
This class organizes the cross-module state that is used while lowering AST types to CIR types.
Definition CIRGenTypes.h:51
CIRGenModule & getCGModule() const
Definition CIRGenTypes.h:91
std::string getRecordTypeName(const clang::RecordDecl *, llvm::StringRef suffix)
clang::ASTContext & getASTContext() const
std::unique_ptr< CIRGenRecordLayout > computeRecordLayout(const clang::RecordDecl *rd, cir::RecordType *ty)
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
Definition DeclCXX.h:1196
This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
bool isZero() const
Test whether the quantity equals zero.
Definition CharUnits.h:101
CharUnits alignTo(CharUnits Align) const
Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is a multiple...
Definition CharUnits.h:171
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
Definition CharUnits.h:155
static CharUnits One()
Construct a CharUnits quantity of one.
Definition CharUnits.h:55
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
Definition CharUnits.h:122
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:58
static CharUnits Zero()
Construct a CharUnits quantity of zero.
Definition CharUnits.h:52
void dump() const
bool hasAttr() const
Definition DeclBase.h:586
Represents a member of a struct/union/class.
Definition Decl.h:3341
bool isBitField() const
Determines whether this field is a bitfield.
Definition Decl.h:3444
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
Definition Decl.cpp:4854
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
Definition Decl.h:3588
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
Definition Decl.h:3447
bool isZeroLengthBitField() const
Is this a zero-length bit-field?
Definition Decl.cpp:4863
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:303
Represents a struct/union/class.
Definition Decl.h:4506
RecordArgPassingKind getArgPassingRestrictions() const
Definition Decl.h:4647
const FieldDecl * findFirstNamedDataMember() const
Finds the first data member which has a name.
Definition Decl.cpp:5512
specific_decl_iterator< FieldDecl > field_iterator
Definition Decl.h:4706
field_iterator field_begin() const
Definition Decl.cpp:5383
bool isUnion() const
Definition Decl.h:4109
virtual unsigned getRegisterWidth() const
Return the "preferred" register width on this target.
Definition TargetInfo.h:902
bool hasCheapUnalignedBitFieldAccess() const
Return true iff unaligned accesses are cheap.
Definition TargetInfo.h:916
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
Definition Type.cpp:2415
QualType getType() const
Definition Decl.h:725
mlir::Type memberStorageType(mlir::Type memberTy)
The storage a member is stored as: the access unit for a bit-field member, and the member type itself...
Definition CIRTypes.h:135
bool memberOwnsBytes(mlir::Type memberTy)
Whether a record member occupies bytes of its record.
Definition CIRTypes.h:126
bool isValidFundamentalIntWidth(unsigned width)
bool anyMemberHoldsDataForABI(llvm::ArrayRef< RecordMemberKind > kinds)
Whether any member holds data for argument passing on its mark alone.
Definition CIRTypes.h:53
bool isNamedBitField(RecordMemberKind kind)
Whether a member of this kind is an access unit the source can read a bit-field of.
Definition CIRTypes.h:65
bool isEmptyRecordForABI(const ASTContext &context, QualType t)
isEmptyRecordForABI - Return true if a structure contains only empty base classes and fields.
bool isEmptyFieldForABI(const ASTContext &context, const FieldDecl *fd)
isEmptyFieldForABI - Return true if the field is "empty", that is, it is a zero-width bit-field or an...
bool isAAPCS(const TargetInfo &TargetInfo)
Helper method to check if the underlying ABI is AAPCS.
bool isDiscreteBitFieldABI(const ASTContext &Ctx, const RecordDecl *RD)
The Microsoft bitfield layout rule allocates discrete storage units of the field's formal type and on...
bool hasOwnStorage(const ASTContext &Ctx, const CXXRecordDecl *Decl, const CXXRecordDecl *Query)
Recursively searches all of the bases of Decl to find out whether Query is not the primary vbase of s...
bool isOverlappingVBaseABI(const ASTContext &Ctx)
The Itanium base layout rule allows virtual bases to overlap other bases, which complicates layout in...
bool isEmptyFieldForLayout(const ASTContext &Ctx, const FieldDecl *FD)
Return true iff the field is "empty", that is, either a zero-width bit-field or an isEmptyRecordForLa...
bool isEmptyRecordForLayout(const ASTContext &Ctx, QualType T)
Return true iff a structure contains only empty base classes (per isEmptyRecordForLayout) and fields ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl > cxxRecordDecl
Matches C++ class declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, RecordDecl > recordDecl
Matches class, struct, and union declarations.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition PrimType.h:218
void info(bool Verbose, unsigned Level, const char *Fmt, Ts &&...Args)
Prints an indented note to stderr when Verbose is set.
Definition Utils.h:57
RangeSelector member(std::string ID)
Given a MemberExpr, selects the member token. ID is the node's binding in the match result.
Stencil run(MatchConsumer< std::string > C)
Wraps a MatchConsumer in a Stencil, so that it can be used in a Stencil.
Definition Stencil.cpp:489
Top level wrappers for InstallAPI frontend operations.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
RecordArgPassingKind
Enum that represents the different ways arguments are passed to and returned from function calls.
Definition Decl.h:4483
@ CanPassInRegs
The argument of this type can be passed directly in registers.
Definition Decl.h:4485
@ CanNeverPassInRegs
The argument of this type cannot be passed directly in registers.
Definition Decl.h:4499
@ CannotPassInRegs
The argument of this type cannot be passed directly in registers.
Definition Decl.h:4494
unsigned long uint64_t
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
void __ovld __conv barrier(cl_mem_fence_flags)
All work-items in a work-group executing the kernel on a processor must execute this function before ...
#define true
Definition stdbool.h:25
static bool noUniqueAddressLayout()
static bool checkBitfieldClipping()
static bool astRecordDeclAttr()
unsigned offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
void print(llvm::raw_ostream &os) const
unsigned storageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned volatileStorageSize
The storage size in bits which should be used when accessing this bitfield.
clang::CharUnits storageOffset
The offset of the bitfield storage from the start of the record.
unsigned size
The total size of the bit-field, in bits.
unsigned isSigned
Whether the bit-field is signed.
clang::CharUnits volatileStorageOffset
The offset of the bitfield storage from the start of the record.
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.