Skip to content

Commit 1f9b452

Browse files
committed
Update comments, varnames and asserts.
1 parent a10cbbe commit 1f9b452

File tree

1 file changed

+141
-80
lines changed

1 file changed

+141
-80
lines changed

clang/lib/CodeGen/CGRecordLayoutBuilder.cpp

Lines changed: 141 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -482,23 +482,22 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
482482
// to keep access-units naturally aligned, to avoid similar bit
483483
// manipulation synthesizing larger unaligned accesses.
484484

485-
// We do this in two phases, processing a sequential run of bitfield
486-
// declarations.
487-
488-
// a) Bitfields that share parts of a single byte are, of necessity, placed in
489-
// the same access unit. That unit will encompass a consecutive
490-
// run where adjacent bitfields share parts of a byte. (The first bitfield of
491-
// such an access unit will start at the beginning of a byte.)
492-
493-
// b) Accumulate adjacent access units when the combined unit is naturally
494-
// sized, no larger than a register, and on a strict alignment ISA,
495-
// aligned. Note that this requires lookahead to one or more subsequent access
496-
// units. For instance, consider a 2-byte access-unit followed by 2 1-byte
497-
// units. We can merge that into a 4-byte access-unit, but we would not want
498-
// to merge a 2-byte followed by a single 1-byte (and no available tail
499-
// padding).
500-
501-
// This accumulation is prevented when:
485+
// Bitfields that share parts of a single byte are, of necessity, placed in
486+
// the same access unit. That unit will encompass a consecutive run where
487+
// adjacent bitfields share parts of a byte. (The first bitfield of such an
488+
// access unit will start at the beginning of a byte.)
489+
490+
// We then try and accumulate adjacent access units when the combined unit is
491+
// naturally sized, no larger than a register, and (on a strict alignment
492+
// ISA), naturally aligned. Note that this requires lookahead to one or more
493+
// subsequent access units. For instance, consider a 2-byte access-unit
494+
// followed by 2 1-byte units. We can merge that into a 4-byte access-unit,
495+
// but we would not want to merge a 2-byte followed by a single 1-byte (and no
496+
// available tail padding). We keep track of the best access unit seen so far,
497+
// and use that when we determine we cannot accumulate any more. Then we start
498+
// again at the bitfield following that best one.
499+
500+
// The accumulation is also prevented when:
502501
// *) it would cross a zero-width bitfield (ABI-dependent), or
503502
// *) one of the candidate access units contains a volatile bitfield, or
504503
// *) fine-grained bitfield access option is in effect.
@@ -507,124 +506,186 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
507506
bitsToCharUnits(Context.getTargetInfo().getRegisterWidth());
508507
unsigned CharBits = Context.getCharWidth();
509508

509+
// Data about the start of the span we're accumulating to create an access
510+
// unit from. Begin is the first bitfield of the span. If Begin is FieldEnd,
511+
// we've not got a current span. The span starts at the BeginOffset character
512+
// boundary. BitSizeSinceBegin is the size (in bits) of the span -- this might
513+
// include padding when we've advanced to a subsequent bitfield run.
510514
RecordDecl::field_iterator Begin = FieldEnd;
511-
CharUnits StartOffset;
512-
uint64_t BitSize;
513-
CharUnits BestEndOffset;
515+
CharUnits BeginOffset;
516+
uint64_t BitSizeSinceBegin;
517+
518+
// The (non-inclusive) end of the largest acceptable access unit we've found
519+
// since Begin. If this is Begin, we're gathering the initial set of bitfields
520+
// of a new span. BestEndOffset is the end of that acceptable access unit --
521+
// it might extend beyond the last character of the bitfield run, using
522+
// available padding characters.
514523
RecordDecl::field_iterator BestEnd = Begin;
515-
bool Volatile;
524+
CharUnits BestEndOffset;
525+
526+
bool Volatile; // True iff the initial span or post-BestEnd span contains a
527+
// volatile bitfield. We do not want to merge spans containing
528+
// a volatile bitfield.
516529

517530
for (;;) {
518-
CharUnits Limit;
519-
bool Barrier;
520-
bool Install = false;
531+
// AtAlignedBoundary is true iff 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 that new
534+
// span cannot be merged into the current one.
535+
bool AtAlignedBoundary = false;
536+
CharUnits LimitOffset;
537+
bool Barrier = false;
521538

522539
if (Field != FieldEnd && Field->isBitField()) {
523540
uint64_t BitOffset = getFieldBitOffset(*Field);
524541
if (Begin == FieldEnd) {
525-
// Beginning a new access unit.
542+
// Beginning a new span.
526543
Begin = Field;
527544
BestEnd = Begin;
528545

529-
assert(!(BitOffset % CharBits) && "Not at start of char");
530-
StartOffset = bitsToCharUnits(BitOffset);
531-
BitSize = 0;
546+
assert((BitOffset % CharBits) == 0 && "Not at start of char");
547+
BeginOffset = bitsToCharUnits(BitOffset);
548+
BitSizeSinceBegin = 0;
532549
Volatile = false;
533-
} else if (BitOffset % CharBits) {
534-
// Bitfield occupies the same char as previous.
535-
assert(BitOffset == Context.toBits(StartOffset) + BitSize &&
550+
} else if ((BitOffset % CharBits) != 0) {
551+
// Bitfield occupies the same char as previous, it must be part of the
552+
// same span.
553+
assert(BitOffset == Context.toBits(BeginOffset) + BitSizeSinceBegin &&
536554
"Concatenating non-contiguous bitfields");
537555
} else {
538-
// Bitfield begins a new access unit.
539-
Limit = bitsToCharUnits(BitOffset);
540-
Barrier = false;
556+
// Bitfield could begin a new span.
557+
LimitOffset = bitsToCharUnits(BitOffset);
541558
if (Field->isZeroLengthBitField(Context) &&
542559
(Context.getTargetInfo().useZeroLengthBitfieldAlignment() ||
543560
Context.getTargetInfo().useBitFieldTypeAlignment()))
544561
Barrier = true;
545-
Install = true;
562+
AtAlignedBoundary = true;
546563
}
547564
} else if (Begin == FieldEnd) {
548565
// Completed the bitfields.
549566
break;
550567
} else {
551-
// End of the bitfield span, with active access unit.
568+
// We've reached the end of the bitfield run while accumulating a span.
569+
// Determine the limit of that span: either the offset of the next field,
570+
// or if we're at the end of the record the end of its non-reuseable tail
571+
// padding. (I.e. treat the next unusable char as the start of an
572+
// unmergeable span.)
552573
auto Probe = Field;
553574
while (Probe != FieldEnd && Probe->isZeroSize(Context))
554575
++Probe;
555576
// We can't necessarily use tail padding in C++ structs, so the NonVirtual
556577
// size is what we must use there.
557-
Limit = Probe != FieldEnd ? bitsToCharUnits(getFieldBitOffset(*Probe))
558-
: RD ? Layout.getNonVirtualSize()
559-
: Layout.getDataSize();
578+
LimitOffset = Probe != FieldEnd
579+
? bitsToCharUnits(getFieldBitOffset(*Probe))
580+
: RD ? Layout.getNonVirtualSize()
581+
: Layout.getDataSize();
560582
Barrier = true;
561-
Install = true;
583+
AtAlignedBoundary = true;
562584
}
563585

564-
if (Install) {
565-
// Found the start of a new access unit. Determine if that completes the
566-
// current one, or potentially extends it.
567-
Install = false;
568-
CharUnits Size = bitsToCharUnits(BitSize + CharBits - 1);
586+
// InstallBest indicates whether we should create an access unit for the
587+
// current best span: fields [Begin, BestEnd) occupying characters
588+
// [BeginOffset, BestEndOffset).
589+
bool InstallBest = false;
590+
if (AtAlignedBoundary) {
591+
// Field is the start of a new span. The just-seen span is now extended to
592+
// BitSizeSinceBegin. Determine if we can accumulate that just-seen span
593+
// into the current accumulation.
594+
CharUnits AccessSize = bitsToCharUnits(BitSizeSinceBegin + CharBits - 1);
569595
if (BestEnd == Begin) {
570-
// This is the initial access unit.
596+
// This is the initial run at the start of a new span. By definition,
597+
// this is the best seen so far.
571598
BestEnd = Field;
572-
BestEndOffset = StartOffset + Size;
573-
if (!BitSize || Types.getCodeGenOpts().FineGrainedBitfieldAccesses)
574-
// A barrier, or we're fine grained.
575-
Install = true;
576-
} else if (Size > RegSize || Volatile)
577-
// Too big to accumulate, or just-seen access unit contains a volatile.
578-
Install = true;
579-
580-
if (!Install) {
581-
llvm::Type *Type = getIntNType(Context.toBits(Size));
599+
BestEndOffset = BeginOffset + AccessSize;
600+
if (Types.getCodeGenOpts().FineGrainedBitfieldAccesses)
601+
// Fine-grained access, so no merging of spans.
602+
InstallBest = true;
603+
else if (!BitSizeSinceBegin)
604+
// A zero-sized initial span -- this will install nothing and reset
605+
// for another.
606+
InstallBest = true;
607+
} else if (Volatile) {
608+
// We've encountered a volatile bitfield in the just-seen non-initial
609+
// span. It should not be merged into the current accumulation.
610+
InstallBest = true;
611+
} else if (AccessSize > RegSize)
612+
// Accumulating the just-seen span would create a multi-register access
613+
// unit, which would increase register pressure.
614+
InstallBest = true;
615+
616+
if (!InstallBest) {
617+
// Determine if accumulating the just-seen span will create an expensive
618+
// access-unit or not.
619+
llvm::Type *Type = getIntNType(Context.toBits(AccessSize));
582620
if (!Context.getTargetInfo().hasCheapUnalignedBitFieldAccess()) {
583-
// This alignment is that of the storage used -- for instance
584-
// (usually) 4 bytes for a 24-bit type.
621+
// Unaligned accesses are expensive. Only accumulate if the new unit
622+
// is naturally aligned. Otherwise install the best we have, which is
623+
// either the initial access unit (can't do better), or a naturally
624+
// aligned subsequent accumulation.
585625
CharUnits Align = getAlignment(Type);
586-
if (Align > Layout.getAlignment() || !StartOffset.isMultipleOf(Align))
587-
// Not naturally aligned.
588-
Install = true;
626+
if (Align > Layout.getAlignment())
627+
// The alignment required is greater than the containing structure
628+
// itself.
629+
InstallBest = true;
630+
else if (!BeginOffset.isMultipleOf(Align))
631+
// The access unit is not at a naturally aligned offset within the
632+
// structure.
633+
InstallBest = true;
589634
}
590635

591-
if (!Install) {
592-
Size = getSize(Type);
593-
if (StartOffset + Size <= Limit) {
594-
// The next unit starts later, extend the current access unit to
595-
// include the just-gathered access unit.
596-
BestEndOffset = StartOffset + Size;
636+
if (!InstallBest) {
637+
CharUnits TypeSize = getSize(Type);
638+
if (BeginOffset + TypeSize <= LimitOffset) {
639+
// There is padding before LimitOffset that we can extend into,
640+
// creating a naturally-sized access unit.
641+
BestEndOffset = BeginOffset + TypeSize;
597642
BestEnd = Field;
598643
}
599644

600-
if (Volatile || Barrier)
601-
// Contained a volatile, or next access unit is a barrier.
602-
Install = true;
645+
if (Barrier)
646+
// The next field is a barrier that we cannot merge-across.
647+
InstallBest = true;
648+
else if (Volatile)
649+
// The initial span contains a volatile bitfield, do not merge any
650+
// subsequent spans. (We can only get here for the initial span, any
651+
// subsequent potential volatile span will have already bailed
652+
// above.)
653+
InstallBest = true;
603654
else
604-
BitSize = Context.toBits(Limit - StartOffset);
655+
// LimitOffset is the offset of the (aligned) next bitfield in this
656+
// case.
657+
BitSizeSinceBegin = Context.toBits(LimitOffset - BeginOffset);
605658
}
606659
}
607660
}
608661

609-
if (Install) {
610-
CharUnits Size = BestEndOffset - StartOffset;
611-
if (!Size.isZero()) {
662+
if (InstallBest) {
663+
assert((Field == FieldEnd || !Field->isBitField() ||
664+
(getFieldBitOffset(*Field) % CharBits) == 0) &&
665+
"Installing but not at an aligned bitfield or limit");
666+
CharUnits AccessSize = BestEndOffset - BeginOffset;
667+
if (!AccessSize.isZero()) {
612668
// Add the storage member for the access unit to the record. The
613669
// bitfields get the offset of their storage but come afterward and
614670
// remain there after a stable sort.
615-
llvm::Type *Type = getIntNType(Context.toBits(Size));
616-
Members.push_back(StorageInfo(StartOffset, Type));
671+
llvm::Type *Type = getIntNType(Context.toBits(AccessSize));
672+
Members.push_back(StorageInfo(BeginOffset, Type));
617673
for (; Begin != BestEnd; ++Begin)
618674
if (!Begin->isZeroLengthBitField(Context))
619675
Members.push_back(
620-
MemberInfo(StartOffset, MemberInfo::Field, nullptr, *Begin));
676+
MemberInfo(BeginOffset, MemberInfo::Field, nullptr, *Begin));
621677
}
622-
// Reset to start a new Access Unit.
678+
// Reset to start a new span.
623679
Field = BestEnd;
624680
Begin = FieldEnd;
625681
} else {
626-
// Accumulate this bitfield into the (potentially) current access unit.
627-
BitSize += Field->getBitWidthValue(Context);
682+
assert(Field != FieldEnd && Field->isBitField() &&
683+
"Accumulating past end of bitfields");
684+
assert(((getFieldBitOffset(*Field) % CharBits) != 0 ||
685+
(!Volatile && !Barrier)) &&
686+
"Accumulating across volatile or barrier");
687+
// Accumulate this bitfield into the current (potential) span.
688+
BitSizeSinceBegin += Field->getBitWidthValue(Context);
628689
if (Field->getType().isVolatileQualified())
629690
Volatile = true;
630691
++Field;

0 commit comments

Comments
 (0)