Skip to content

Commit 7beb3dd

Browse files
authored
Merge pull request swiftlang#5040 from jckarter/enum-no-unusual-integer-size
IRGen: Don't represent enums with weird-sized LLVM integer types.
2 parents 36aae65 + 74fd15f commit 7beb3dd

File tree

9 files changed

+311
-272
lines changed

9 files changed

+311
-272
lines changed

lib/IRGen/EnumPayload.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
675738
llvm::Value *
676739
EnumPayload::emitGatherSpareBits(IRGenFunction &IGF,
677740
const SpareBitVector &spareBits,

0 commit comments

Comments
 (0)