================ @@ -223,21 +272,114 @@ void CIRRecordLowering::fillOutputFields() { fieldTypes.size() - 1; // A field without storage must be a bitfield. assert(!cir::MissingFeatures::bitfields()); + if (!member.data) + setBitFieldInfo(member.fieldDecl, member.offset, fieldTypes.back()); } assert(!cir::MissingFeatures::cxxSupport()); } } +void CIRRecordLowering::accumulateBitFields( + RecordDecl::field_iterator field, RecordDecl::field_iterator fieldEnd) { + // Run stores the first element of the current run of bitfields. FieldEnd is + // used as a special value to note that we don't have a current run. A + // bitfield run is a contiguous collection of bitfields that can be stored in + // the same storage block. Zero-sized bitfields and bitfields that would + // cross an alignment boundary break a run and start a new one. + RecordDecl::field_iterator run = fieldEnd; + // Tail is the offset of the first bit off the end of the current run. It's + // used to determine if the ASTRecordLayout is treating these two bitfields as + // contiguous. StartBitOffset is offset of the beginning of the Run. + uint64_t startBitOffset, tail = 0; + assert(!cir::MissingFeatures::isDiscreteBitFieldABI()); + + // Check if OffsetInRecord (the size in bits of the current run) is better + // as a single field run. When OffsetInRecord has legal integer width, and + // its bitfield offset is naturally aligned, it is better to make the + // bitfield a separate storage component so as it can be accessed directly + // with lower cost. + auto isBetterAsSingleFieldRun = [&](uint64_t offsetInRecord, + uint64_t startBitOffset, + uint64_t nextTail = 0) { + if (!cirGenTypes.getCGModule().getCodeGenOpts().FineGrainedBitfieldAccesses) + return false; + cirGenTypes.getCGModule().errorNYI(field->getSourceRange(), + "NYI FineGrainedBitfield"); + return true; + }; + + // The start field is better as a single field run. + bool startFieldAsSingleRun = false; + for (;;) { + // Check to see if we need to start a new run. + if (run == fieldEnd) { + // If we're out of fields, return. + if (field == fieldEnd) + break; + // Any non-zero-length bitfield can start a new run. + if (!field->isZeroLengthBitField()) { + run = field; + startBitOffset = getFieldBitOffset(*field); + tail = startBitOffset + field->getBitWidthValue(); + startFieldAsSingleRun = + isBetterAsSingleFieldRun(tail - startBitOffset, startBitOffset); + } + ++field; + continue; + } + + // If the start field of a new run is better as a single run, or if current + // field (or consecutive fields) is better as a single run, or if current + // field has zero width bitfield and either UseZeroLengthBitfieldAlignment + // or UseBitFieldTypeAlignment is set to true, or if the offset of current + // field is inconsistent with the offset of previous field plus its offset, + // skip the block below and go ahead to emit the storage. Otherwise, try to + // add bitfields to the run. ---------------- andykaylor wrote:
This comment is really hard to follow. I would suggest an alternative, but I'm really not sure what it's saying. It seems to be a literal rendering of the compound condition on lines 342-348 without explaining what the goal of the conditions is. https://github.com/llvm/llvm-project/pull/142041 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits