@@ -300,9 +300,10 @@ EnumImplStrategy::emitResilientTagIndices(IRGenModule &IGM) const {
300
300
301
301
llvm::Value *
302
302
EnumImplStrategy::emitFixedGetEnumTag (IRGenFunction &IGF, SILType T,
303
- Address enumAddr) const {
303
+ Address enumAddr,
304
+ bool maskExtraTagBits) const {
304
305
assert (TIK >= Fixed);
305
- return emitGetEnumTag (IGF, T, enumAddr);
306
+ return emitGetEnumTag (IGF, T, enumAddr, maskExtraTagBits );
306
307
}
307
308
308
309
llvm::Value *
@@ -418,9 +419,8 @@ namespace {
418
419
T, getTypeInfo ());
419
420
}
420
421
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 {
424
424
return llvm::ConstantInt::get (IGF.IGM .Int32Ty , 0 );
425
425
}
426
426
@@ -943,9 +943,8 @@ namespace {
943
943
return Size ((getDiscriminatorType ()->getBitWidth () + 7 ) / 8 );
944
944
}
945
945
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 {
949
948
Explosion value;
950
949
loadAsTake (IGF, enumAddr, value);
951
950
@@ -1654,16 +1653,23 @@ namespace {
1654
1653
return {payload, extraTag};
1655
1654
}
1656
1655
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 {
1659
1659
llvm::Value *extraTag = nullptr ;
1660
1660
auto payload = EnumPayload::load (IGF, projectPayload (IGF, addr),
1661
1661
PayloadSchema);
1662
- if (ExtraTagBitCount > 0 )
1662
+ if (ExtraTagBitCount > 0 ) {
1663
1663
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
+ }
1664
1670
return {std::move (payload), extraTag};
1665
1671
}
1666
-
1672
+
1667
1673
void packIntoEnumPayload (IRGenModule &IGM,
1668
1674
IRBuilder &builder,
1669
1675
EnumPayload &outerPayload,
@@ -1968,8 +1974,8 @@ namespace {
1968
1974
1969
1975
// / Emit a call into the runtime to get the current enum payload tag.
1970
1976
// / 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 {
1973
1979
auto numEmptyCases =
1974
1980
llvm::ConstantInt::get (IGF.IGM .Int32Ty , ElementsWithNoPayload.size ());
1975
1981
@@ -1983,9 +1989,9 @@ namespace {
1983
1989
opaqueAddr);
1984
1990
}
1985
1991
1986
-
1987
1992
llvm::Value *emitFixedGetEnumTag (IRGenFunction &IGF, SILType T,
1988
- Address enumAddr) const override {
1993
+ Address enumAddr,
1994
+ bool maskExtraTagBits) const override {
1989
1995
assert (TIK >= Fixed);
1990
1996
auto numEmptyCases =
1991
1997
llvm::ConstantInt::get (IGF.IGM .Int32Ty , ElementsWithNoPayload.size ());
@@ -4067,9 +4073,8 @@ namespace {
4067
4073
public:
4068
4074
4069
4075
// / 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 {
4073
4078
unsigned numPayloadCases = ElementsWithPayload.size ();
4074
4079
llvm::Constant *payloadCases =
4075
4080
llvm::ConstantInt::get (IGM.Int32Ty , numPayloadCases);
@@ -4087,8 +4092,8 @@ namespace {
4087
4092
4088
4093
// Load the fixed-size representation and derive the tags.
4089
4094
EnumPayload payload; llvm::Value *extraTagBits;
4090
- std::tie (payload, extraTagBits)
4091
- = emitPrimitiveLoadPayloadAndExtraTag (IGF, addr);
4095
+ std::tie (payload, extraTagBits) =
4096
+ emitPrimitiveLoadPayloadAndExtraTag (IGF, addr, maskExtraTagBits );
4092
4097
4093
4098
// Load the payload tag.
4094
4099
llvm::Value *tagValue = extractPayloadTag (IGF, payload, extraTagBits);
@@ -6150,9 +6155,8 @@ namespace {
6150
6155
6151
6156
// / \group Operations for emitting type metadata
6152
6157
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 {
6156
6160
llvm_unreachable (" resilient enums cannot be defined" );
6157
6161
}
6158
6162
0 commit comments