@@ -223,9 +223,9 @@ void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
223223
224224 if (info.size > info.storageSize )
225225 info.size = info.storageSize ;
226- // Reverse the bit offsets for big endian machines. Because we represent
227- // a bitfield as a single large integer load , we can imagine the bits
228- // counting from the most-significant-bit instead the
226+ // Reverse the bit offsets for big endian machines. Since bitfields are laid
227+ // out as packed bits within an integer-sized unit , we can imagine the bits
228+ // counting from the most-significant-bit instead of the
229229 // least-significant-bit.
230230 assert (!cir::MissingFeatures::isBigEndian ());
231231
@@ -292,35 +292,25 @@ void CIRRecordLowering::fillOutputFields() {
292292
293293void CIRRecordLowering::accumulateBitFields (
294294 RecordDecl::field_iterator field, RecordDecl::field_iterator fieldEnd) {
295- // Run stores the first element of the current run of bitfields. FieldEnd is
296- // used as a special value to note that we don't have a current run. A
295+ // 'run' stores the first element of the current run of bitfields. 'fieldEnd'
296+ // is used as a special value to note that we don't have a current run. A
297297 // bitfield run is a contiguous collection of bitfields that can be stored in
298298 // the same storage block. Zero-sized bitfields and bitfields that would
299299 // cross an alignment boundary break a run and start a new one.
300300 RecordDecl::field_iterator run = fieldEnd;
301- // Tail is the offset of the first bit off the end of the current run. It's
301+ // 'tail' is the offset of the first bit off the end of the current run. It's
302302 // used to determine if the ASTRecordLayout is treating these two bitfields as
303- // contiguous. StartBitOffset is offset of the beginning of the Run .
303+ // contiguous. 'startBitOffset' is offset of the beginning of the run .
304304 uint64_t startBitOffset, tail = 0 ;
305305 assert (!cir::MissingFeatures::isDiscreteBitFieldABI ());
306306
307- // Check if OffsetInRecord (the size in bits of the current run) is better
307+ // Check if 'offsetInRecord' (the size in bits of the current run) is better
308308 // as a single field run. When OffsetInRecord has legal integer width, and
309309 // its bitfield offset is naturally aligned, it is better to make the
310310 // bitfield a separate storage component so as it can be accessed directly
311311 // with lower cost.
312- auto isBetterAsSingleFieldRun = [&](uint64_t offsetInRecord,
313- uint64_t startBitOffset,
314- uint64_t nextTail = 0 ) {
315- if (!cirGenTypes.getCGModule ().getCodeGenOpts ().FineGrainedBitfieldAccesses )
316- return false ;
317- cirGenTypes.getCGModule ().errorNYI (field->getSourceRange (),
318- " NYI FineGrainedBitfield" );
319- return true ;
320- };
312+ assert (!cir::MissingFeatures::nonFineGrainedBitfields ());
321313
322- // The start field is better as a single field run.
323- bool startFieldAsSingleRun = false ;
324314 for (;;) {
325315 // Check to see if we need to start a new run.
326316 if (run == fieldEnd) {
@@ -332,27 +322,34 @@ void CIRRecordLowering::accumulateBitFields(
332322 run = field;
333323 startBitOffset = getFieldBitOffset (*field);
334324 tail = startBitOffset + field->getBitWidthValue ();
335- startFieldAsSingleRun =
336- isBetterAsSingleFieldRun (tail - startBitOffset, startBitOffset);
325+ assert (!cir::MissingFeatures::nonFineGrainedBitfields ());
337326 }
338327 ++field;
339328 continue ;
340329 }
341330
342- // If the start field of a new run is better as a single run, or if current
343- // field (or consecutive fields) is better as a single run, or if current
344- // field has zero width bitfield and either UseZeroLengthBitfieldAlignment
345- // or UseBitFieldTypeAlignment is set to true, or if the offset of current
346- // field is inconsistent with the offset of previous field plus its offset,
347- // skip the block below and go ahead to emit the storage. Otherwise, try to
348- // add bitfields to the run.
331+ // Decide whether to continue extending the current bitfield run.
332+ //
333+ // Skip the block below and go directly to emitting storage if any of the
334+ // following is true:
335+ // - 1. The first field in the run is better treated as its own run.
336+ // - 2. We have reached the end of the fields.
337+ // - 3. The current field (or set of fields) is better as its own run.
338+ // - 4. The current field is a zero-width bitfield or:
339+ // - Zero-length bitfield alignment is enabled, and
340+ // - Bitfield type alignment is enabled.
341+ // - 5. The current field's offset doesn't match the expected tail (i.e.,
342+ // layout isn't contiguous).
343+ //
344+ // If none of the above conditions are met, add the current field to the
345+ // current run.
349346 uint64_t nextTail = tail;
350347 if (field != fieldEnd)
351348 nextTail += field->getBitWidthValue ();
352349
353- if (!startFieldAsSingleRun && field != fieldEnd &&
354- ! isBetterAsSingleFieldRun (tail - startBitOffset, startBitOffset,
355- nextTail) &&
350+ // TODO: add condition 1 and 3
351+ assert (! cir::MissingFeatures::nonFineGrainedBitfields ());
352+ if (field != fieldEnd &&
356353 (!field->isZeroLengthBitField () ||
357354 (!astContext.getTargetInfo ().useZeroLengthBitfieldAlignment () &&
358355 !astContext.getTargetInfo ().useBitFieldTypeAlignment ())) &&
@@ -373,7 +370,6 @@ void CIRRecordLowering::accumulateBitFields(
373370 members.push_back (MemberInfo (bitsToCharUnits (startBitOffset),
374371 MemberInfo::InfoKind::Field, nullptr , *run));
375372 run = fieldEnd;
376- startFieldAsSingleRun = false ;
377373 }
378374}
379375
0 commit comments