@@ -223,9 +223,9 @@ void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
223
223
224
224
if (info.size > info.storageSize )
225
225
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
229
229
// least-significant-bit.
230
230
assert (!cir::MissingFeatures::isBigEndian ());
231
231
@@ -292,35 +292,25 @@ void CIRRecordLowering::fillOutputFields() {
292
292
293
293
void CIRRecordLowering::accumulateBitFields (
294
294
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
297
297
// bitfield run is a contiguous collection of bitfields that can be stored in
298
298
// the same storage block. Zero-sized bitfields and bitfields that would
299
299
// cross an alignment boundary break a run and start a new one.
300
300
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
302
302
// 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 .
304
304
uint64_t startBitOffset, tail = 0 ;
305
305
assert (!cir::MissingFeatures::isDiscreteBitFieldABI ());
306
306
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
308
308
// as a single field run. When OffsetInRecord has legal integer width, and
309
309
// its bitfield offset is naturally aligned, it is better to make the
310
310
// bitfield a separate storage component so as it can be accessed directly
311
311
// 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 ());
321
313
322
- // The start field is better as a single field run.
323
- bool startFieldAsSingleRun = false ;
324
314
for (;;) {
325
315
// Check to see if we need to start a new run.
326
316
if (run == fieldEnd) {
@@ -332,27 +322,34 @@ void CIRRecordLowering::accumulateBitFields(
332
322
run = field;
333
323
startBitOffset = getFieldBitOffset (*field);
334
324
tail = startBitOffset + field->getBitWidthValue ();
335
- startFieldAsSingleRun =
336
- isBetterAsSingleFieldRun (tail - startBitOffset, startBitOffset);
325
+ assert (!cir::MissingFeatures::nonFineGrainedBitfields ());
337
326
}
338
327
++field;
339
328
continue ;
340
329
}
341
330
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.
349
346
uint64_t nextTail = tail;
350
347
if (field != fieldEnd)
351
348
nextTail += field->getBitWidthValue ();
352
349
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 &&
356
353
(!field->isZeroLengthBitField () ||
357
354
(!astContext.getTargetInfo ().useZeroLengthBitfieldAlignment () &&
358
355
!astContext.getTargetInfo ().useBitFieldTypeAlignment ())) &&
@@ -373,7 +370,6 @@ void CIRRecordLowering::accumulateBitFields(
373
370
members.push_back (MemberInfo (bitsToCharUnits (startBitOffset),
374
371
MemberInfo::InfoKind::Field, nullptr , *run));
375
372
run = fieldEnd;
376
- startFieldAsSingleRun = false ;
377
373
}
378
374
}
379
375
0 commit comments