@@ -1125,54 +1125,44 @@ class MultiPayloadEnumDescriptorBuilder : public ReflectionMetadataBuilder {
11251125 void layout () override {
11261126 auto &strategy = getEnumImplStrategy (IGM, typeInContext);
11271127 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" );
11291130
11301131 const TypeInfo &TI = strategy.getTypeInfo ();
11311132 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" );
11341135
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 ();
11511137
11521138 // Never write an MPE descriptor bigger than 16k
11531139 // The runtime will fall back on its own internal
11541140 // spare bits calculation for this (very rare) case.
1155- if (bytesInMask > 16384 ) {
1141+ if (!spareBitsMaskInfo)
11561142 return ;
1157- }
1143+
1144+ auto bits = spareBitsMaskInfo->bits ;
11581145
11591146 addTypeRef (type, CanGenericSignature ());
11601147
1148+ bool usesPayloadSpareBits = spareBitsMaskInfo->bytesInMask > 0 ;
1149+
11611150 // MPE record contents are a multiple of 32-bits
11621151 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 ();
11671155 }
1156+
11681157 uint32_t flags = usesPayloadSpareBits ? 1 : 0 ;
11691158
11701159 B.addInt32 ((contentsSizeInWords << 16 ) | flags);
11711160
1172- if (bytesInMask > 0 ) {
1173- B.addInt32 ((byteOffset << 16 ) | bytesInMask);
1161+ if (usesPayloadSpareBits) {
1162+ B.addInt32 ((spareBitsMaskInfo->byteOffset << 16 ) |
1163+ spareBitsMaskInfo->bytesInMask );
11741164 // TODO: Endianness??
1175- for (unsigned i = 0 ; i < wordsInMask; ++i) {
1165+ for (unsigned i = 0 ; i < spareBitsMaskInfo-> wordsInMask () ; ++i) {
11761166 uint32_t nextWord = bits.extractBitsAsZExtValue (32 , 0 );
11771167 B.addInt32 (nextWord);
11781168 bits.lshrInPlace (32 );
0 commit comments