@@ -300,9 +300,10 @@ EnumImplStrategy::emitResilientTagIndices(IRGenModule &IGM) const {
300300
301301llvm::Value *
302302EnumImplStrategy::emitFixedGetEnumTag (IRGenFunction &IGF, SILType T,
303- Address enumAddr) const {
303+ Address enumAddr,
304+ bool maskExtraTagBits) const {
304305 assert (TIK >= Fixed);
305- return emitGetEnumTag (IGF, T, enumAddr);
306+ return emitGetEnumTag (IGF, T, enumAddr, maskExtraTagBits );
306307}
307308
308309llvm::Value *
@@ -418,9 +419,8 @@ namespace {
418419 T, getTypeInfo ());
419420 }
420421
421- llvm::Value *
422- emitGetEnumTag (IRGenFunction &IGF, SILType T, Address enumAddr)
423- const override {
422+ llvm::Value *emitGetEnumTag (IRGenFunction &IGF, SILType T, Address enumAddr,
423+ bool maskExtraTagBits) const override {
424424 return llvm::ConstantInt::get (IGF.IGM .Int32Ty , 0 );
425425 }
426426
@@ -943,9 +943,8 @@ namespace {
943943 return Size ((getDiscriminatorType ()->getBitWidth () + 7 ) / 8 );
944944 }
945945
946- llvm::Value *
947- emitGetEnumTag (IRGenFunction &IGF, SILType T, Address enumAddr)
948- const override {
946+ llvm::Value *emitGetEnumTag (IRGenFunction &IGF, SILType T, Address enumAddr,
947+ bool maskExtraTagBits) const override {
949948 Explosion value;
950949 loadAsTake (IGF, enumAddr, value);
951950
@@ -1654,16 +1653,23 @@ namespace {
16541653 return {payload, extraTag};
16551654 }
16561655
1657- std::pair<EnumPayload, llvm::Value*>
1658- emitPrimitiveLoadPayloadAndExtraTag (IRGenFunction &IGF, Address addr) const {
1656+ std::pair<EnumPayload, llvm::Value *>
1657+ emitPrimitiveLoadPayloadAndExtraTag (IRGenFunction &IGF, Address addr,
1658+ bool maskExtraTagBits = false ) const {
16591659 llvm::Value *extraTag = nullptr ;
16601660 auto payload = EnumPayload::load (IGF, projectPayload (IGF, addr),
16611661 PayloadSchema);
1662- if (ExtraTagBitCount > 0 )
1662+ if (ExtraTagBitCount > 0 ) {
16631663 extraTag = IGF.Builder .CreateLoad (projectExtraTagBits (IGF, addr));
1664+ if (maskExtraTagBits) {
1665+ auto maskBits = llvm::NextPowerOf2 (NumExtraTagValues) - 1 ;
1666+ auto mask = llvm::ConstantInt::get (extraTag->getType (), maskBits);
1667+ extraTag = IGF.Builder .CreateAnd (extraTag, mask);
1668+ }
1669+ }
16641670 return {std::move (payload), extraTag};
16651671 }
1666-
1672+
16671673 void packIntoEnumPayload (IRGenModule &IGM,
16681674 IRBuilder &builder,
16691675 EnumPayload &outerPayload,
@@ -1968,8 +1974,8 @@ namespace {
19681974
19691975 // / Emit a call into the runtime to get the current enum payload tag.
19701976 // / This returns a tag index in the range [0..NumElements-1].
1971- llvm::Value *emitGetEnumTag (IRGenFunction &IGF, SILType T,
1972- Address enumAddr ) const override {
1977+ llvm::Value *emitGetEnumTag (IRGenFunction &IGF, SILType T, Address enumAddr,
1978+ bool maskExtraTagBits = false ) const override {
19731979 auto numEmptyCases =
19741980 llvm::ConstantInt::get (IGF.IGM .Int32Ty , ElementsWithNoPayload.size ());
19751981
@@ -1983,9 +1989,9 @@ namespace {
19831989 opaqueAddr);
19841990 }
19851991
1986-
19871992 llvm::Value *emitFixedGetEnumTag (IRGenFunction &IGF, SILType T,
1988- Address enumAddr) const override {
1993+ Address enumAddr,
1994+ bool maskExtraTagBits) const override {
19891995 assert (TIK >= Fixed);
19901996 auto numEmptyCases =
19911997 llvm::ConstantInt::get (IGF.IGM .Int32Ty , ElementsWithNoPayload.size ());
@@ -4067,9 +4073,8 @@ namespace {
40674073 public:
40684074
40694075 // / Returns a tag index in the range [0..NumElements-1].
4070- llvm::Value *
4071- emitGetEnumTag (IRGenFunction &IGF, SILType T, Address addr)
4072- const override {
4076+ llvm::Value *emitGetEnumTag (IRGenFunction &IGF, SILType T, Address addr,
4077+ bool maskExtraTagBits) const override {
40734078 unsigned numPayloadCases = ElementsWithPayload.size ();
40744079 llvm::Constant *payloadCases =
40754080 llvm::ConstantInt::get (IGM.Int32Ty , numPayloadCases);
@@ -4087,8 +4092,8 @@ namespace {
40874092
40884093 // Load the fixed-size representation and derive the tags.
40894094 EnumPayload payload; llvm::Value *extraTagBits;
4090- std::tie (payload, extraTagBits)
4091- = emitPrimitiveLoadPayloadAndExtraTag (IGF, addr);
4095+ std::tie (payload, extraTagBits) =
4096+ emitPrimitiveLoadPayloadAndExtraTag (IGF, addr, maskExtraTagBits );
40924097
40934098 // Load the payload tag.
40944099 llvm::Value *tagValue = extractPayloadTag (IGF, payload, extraTagBits);
@@ -6150,9 +6155,8 @@ namespace {
61506155
61516156 // / \group Operations for emitting type metadata
61526157
6153- llvm::Value *
6154- emitGetEnumTag (IRGenFunction &IGF, SILType T, Address addr)
6155- const override {
6158+ llvm::Value *emitGetEnumTag (IRGenFunction &IGF, SILType T, Address addr,
6159+ bool maskExtraTagBits) const override {
61566160 llvm_unreachable (" resilient enums cannot be defined" );
61576161 }
61586162
0 commit comments