@@ -672,6 +672,69 @@ EnumPayload::emitApplyOrMask(IRGenFunction &IGF,
672672 }
673673}
674674
675+ // / Gather spare bits into the low bits of a smaller integer value.
676+ llvm::Value *irgen::emitGatherSpareBits (IRGenFunction &IGF,
677+ const SpareBitVector &spareBitMask,
678+ llvm::Value *spareBits,
679+ unsigned resultLowBit,
680+ unsigned resultBitWidth) {
681+ auto destTy
682+ = llvm::IntegerType::get (IGF.IGM .getLLVMContext (), resultBitWidth);
683+ unsigned usedBits = resultLowBit;
684+ llvm::Value *result = nullptr ;
685+
686+ auto spareBitEnumeration = spareBitMask.enumerateSetBits ();
687+ for (auto optSpareBit = spareBitEnumeration.findNext ();
688+ optSpareBit.hasValue () && usedBits < resultBitWidth;
689+ optSpareBit = spareBitEnumeration.findNext ()) {
690+ unsigned u = optSpareBit.getValue ();
691+ assert (u >= (usedBits - resultLowBit) &&
692+ " used more bits than we've processed?!" );
693+
694+ // Shift the bits into place.
695+ llvm::Value *newBits;
696+ if (u > usedBits)
697+ newBits = IGF.Builder .CreateLShr (spareBits, u - usedBits);
698+ else if (u < usedBits)
699+ newBits = IGF.Builder .CreateShl (spareBits, usedBits - u);
700+ else
701+ newBits = spareBits;
702+ newBits = IGF.Builder .CreateZExtOrTrunc (newBits, destTy);
703+
704+ // See how many consecutive bits we have.
705+ unsigned numBits = 1 ;
706+ ++u;
707+ // We don't need more bits than the size of the result.
708+ unsigned maxBits = resultBitWidth - usedBits;
709+ for (unsigned e = spareBitMask.size ();
710+ u < e && numBits < maxBits && spareBitMask[u];
711+ ++u) {
712+ ++numBits;
713+ (void ) spareBitEnumeration.findNext ();
714+ }
715+
716+ // Mask out the selected bits.
717+ auto val = APInt::getAllOnesValue (numBits);
718+ if (numBits < resultBitWidth)
719+ val = val.zext (resultBitWidth);
720+ val = val.shl (usedBits);
721+ auto *mask = llvm::ConstantInt::get (IGF.IGM .getLLVMContext (), val);
722+ newBits = IGF.Builder .CreateAnd (newBits, mask);
723+
724+ // Accumulate the result.
725+ if (result)
726+ result = IGF.Builder .CreateOr (result, newBits);
727+ else
728+ result = newBits;
729+
730+ usedBits += numBits;
731+ }
732+
733+ return result;
734+ }
735+
736+
737+
675738llvm::Value *
676739EnumPayload::emitGatherSpareBits (IRGenFunction &IGF,
677740 const SpareBitVector &spareBits,
0 commit comments