@@ -482,23 +482,22 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
482
482
// to keep access-units naturally aligned, to avoid similar bit
483
483
// manipulation synthesizing larger unaligned accesses.
484
484
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:
502
501
// *) it would cross a zero-width bitfield (ABI-dependent), or
503
502
// *) one of the candidate access units contains a volatile bitfield, or
504
503
// *) fine-grained bitfield access option is in effect.
@@ -507,124 +506,186 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
507
506
bitsToCharUnits (Context.getTargetInfo ().getRegisterWidth ());
508
507
unsigned CharBits = Context.getCharWidth ();
509
508
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.
510
514
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.
514
523
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.
516
529
517
530
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 ;
521
538
522
539
if (Field != FieldEnd && Field->isBitField ()) {
523
540
uint64_t BitOffset = getFieldBitOffset (*Field);
524
541
if (Begin == FieldEnd) {
525
- // Beginning a new access unit .
542
+ // Beginning a new span .
526
543
Begin = Field;
527
544
BestEnd = Begin;
528
545
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 ;
532
549
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 &&
536
554
" Concatenating non-contiguous bitfields" );
537
555
} 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);
541
558
if (Field->isZeroLengthBitField (Context) &&
542
559
(Context.getTargetInfo ().useZeroLengthBitfieldAlignment () ||
543
560
Context.getTargetInfo ().useBitFieldTypeAlignment ()))
544
561
Barrier = true ;
545
- Install = true ;
562
+ AtAlignedBoundary = true ;
546
563
}
547
564
} else if (Begin == FieldEnd) {
548
565
// Completed the bitfields.
549
566
break ;
550
567
} 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.)
552
573
auto Probe = Field;
553
574
while (Probe != FieldEnd && Probe->isZeroSize (Context))
554
575
++Probe;
555
576
// We can't necessarily use tail padding in C++ structs, so the NonVirtual
556
577
// 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 ();
560
582
Barrier = true ;
561
- Install = true ;
583
+ AtAlignedBoundary = true ;
562
584
}
563
585
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 );
569
595
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.
571
598
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));
582
620
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.
585
625
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 ;
589
634
}
590
635
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 ;
597
642
BestEnd = Field;
598
643
}
599
644
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 ;
603
654
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);
605
658
}
606
659
}
607
660
}
608
661
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 ()) {
612
668
// Add the storage member for the access unit to the record. The
613
669
// bitfields get the offset of their storage but come afterward and
614
670
// 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));
617
673
for (; Begin != BestEnd; ++Begin)
618
674
if (!Begin->isZeroLengthBitField (Context))
619
675
Members.push_back (
620
- MemberInfo (StartOffset , MemberInfo::Field, nullptr , *Begin));
676
+ MemberInfo (BeginOffset , MemberInfo::Field, nullptr , *Begin));
621
677
}
622
- // Reset to start a new Access Unit .
678
+ // Reset to start a new span .
623
679
Field = BestEnd;
624
680
Begin = FieldEnd;
625
681
} 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);
628
689
if (Field->getType ().isVolatileQualified ())
629
690
Volatile = true ;
630
691
++Field;
0 commit comments