@@ -1125,54 +1125,44 @@ class MultiPayloadEnumDescriptorBuilder : public ReflectionMetadataBuilder {
1125
1125
void layout () override {
1126
1126
auto &strategy = getEnumImplStrategy (IGM, typeInContext);
1127
1127
bool isMPE = strategy.getElementsWithPayload ().size () > 1 ;
1128
- assert (isMPE && " Cannot emit Multi-Payload Enum data for an enum that doesn't have multiple payloads" );
1128
+ assert (isMPE && " Cannot emit Multi-Payload Enum data for an enum that "
1129
+ " doesn't have multiple payloads" );
1129
1130
1130
1131
const TypeInfo &TI = strategy.getTypeInfo ();
1131
1132
auto fixedTI = dyn_cast<FixedTypeInfo>(&TI);
1132
- assert (fixedTI != nullptr
1133
- && " MPE reflection records can only be emitted for fixed-layout enums" );
1133
+ assert (fixedTI != nullptr &&
1134
+ " MPE reflection records can only be emitted for fixed-layout enums" );
1134
1135
1135
- // Get the spare bits mask for the enum payloads.
1136
- SpareBitVector spareBits;
1137
- for (auto enumCase : strategy.getElementsWithPayload ()) {
1138
- cast<FixedTypeInfo>(enumCase.ti )->applyFixedSpareBitsMask (IGM, spareBits);
1139
- }
1140
-
1141
- // Trim leading/trailing zero bytes, then pad to a multiple of 32 bits
1142
- llvm::APInt bits = spareBits.asAPInt ();
1143
- uint32_t byteOffset = bits.countTrailingZeros () / 8 ;
1144
- bits.lshrInPlace (byteOffset * 8 ); // Trim zero bytes from bottom end
1145
-
1146
- auto bitsInMask = bits.getActiveBits (); // Ignore high-order zero bits
1147
- auto usesPayloadSpareBits = bitsInMask > 0 ;
1148
- uint32_t bytesInMask = (bitsInMask + 7 ) / 8 ;
1149
- auto wordsInMask = (bytesInMask + 3 ) / 4 ;
1150
- bits = bits.zextOrTrunc (wordsInMask * 32 );
1136
+ auto spareBitsMaskInfo = strategy.calculateSpareBitsMask ();
1151
1137
1152
1138
// Never write an MPE descriptor bigger than 16k
1153
1139
// The runtime will fall back on its own internal
1154
1140
// spare bits calculation for this (very rare) case.
1155
- if (bytesInMask > 16384 ) {
1141
+ if (!spareBitsMaskInfo)
1156
1142
return ;
1157
- }
1143
+
1144
+ auto bits = spareBitsMaskInfo->bits ;
1158
1145
1159
1146
addTypeRef (type, CanGenericSignature ());
1160
1147
1148
+ bool usesPayloadSpareBits = spareBitsMaskInfo->bytesInMask > 0 ;
1149
+
1161
1150
// MPE record contents are a multiple of 32-bits
1162
1151
uint32_t contentsSizeInWords = 1 ; /* Size + flags is mandatory */
1163
- if (wordsInMask > 0 ) {
1164
- contentsSizeInWords +=
1165
- 1 /* SpareBits byte count */
1166
- + wordsInMask;
1152
+ if (usesPayloadSpareBits) {
1153
+ contentsSizeInWords += 1 /* SpareBits byte count */
1154
+ + spareBitsMaskInfo->wordsInMask ();
1167
1155
}
1156
+
1168
1157
uint32_t flags = usesPayloadSpareBits ? 1 : 0 ;
1169
1158
1170
1159
B.addInt32 ((contentsSizeInWords << 16 ) | flags);
1171
1160
1172
- if (bytesInMask > 0 ) {
1173
- B.addInt32 ((byteOffset << 16 ) | bytesInMask);
1161
+ if (usesPayloadSpareBits) {
1162
+ B.addInt32 ((spareBitsMaskInfo->byteOffset << 16 ) |
1163
+ spareBitsMaskInfo->bytesInMask );
1174
1164
// TODO: Endianness??
1175
- for (unsigned i = 0 ; i < wordsInMask; ++i) {
1165
+ for (unsigned i = 0 ; i < spareBitsMaskInfo-> wordsInMask () ; ++i) {
1176
1166
uint32_t nextWord = bits.extractBitsAsZExtValue (32 , 0 );
1177
1167
B.addInt32 (nextWord);
1178
1168
bits.lshrInPlace (32 );
0 commit comments