@@ -235,15 +235,10 @@ irgen::EnumImplStrategy::getTagIndex(EnumElementDecl *Case) const {
235
235
llvm_unreachable (" couldn't find case" );
236
236
}
237
237
238
- int
239
- irgen::EnumImplStrategy::getResilientTagIndex (EnumElementDecl *Case) const {
240
- return getTagIndex (Case) - ElementsWithPayload.size ();
241
- }
242
-
243
238
static void emitResilientTagIndex (IRGenModule &IGM,
244
239
const EnumImplStrategy *strategy,
245
240
EnumElementDecl *Case) {
246
- auto resilientIdx = strategy->getResilientTagIndex (Case);
241
+ auto resilientIdx = strategy->getTagIndex (Case);
247
242
auto global = IGM.getAddrOfEnumCase (Case, ForDefinition);
248
243
cast<llvm::GlobalVariable>(global.getAddress ())
249
244
->setInitializer (llvm::ConstantInt::get (IGM.Int32Ty , resilientIdx));
@@ -312,11 +307,7 @@ namespace {
312
307
llvm::Value *
313
308
emitGetEnumTag (IRGenFunction &IGF, SILType T, Address enumAddr)
314
309
const override {
315
- // Convert fragile tag index into resilient tag index.
316
- // - -1 -- if we have a payload
317
- // - 0 -- if there's no payload
318
- return llvm::ConstantInt::get (IGF.IGM .Int32Ty ,
319
- !ElementsWithPayload.empty () ? -1 : 0 );
310
+ return llvm::ConstantInt::get (IGF.IGM .Int32Ty , 0 );
320
311
}
321
312
322
313
llvm::Value *
@@ -755,10 +746,7 @@ namespace {
755
746
Explosion value;
756
747
loadAsTake (IGF, enumAddr, value);
757
748
758
- // Converting fragile tag index into resilient tag index is
759
- // not necessary; there are no payload tags.
760
- return IGF.Builder .CreateZExtOrTrunc (value.claimNext (),
761
- IGF.IGM .Int32Ty );
749
+ return IGF.Builder .CreateZExtOrTrunc (value.claimNext (), IGF.IGM .Int32Ty );
762
750
}
763
751
764
752
llvm::Value *emitValueCaseTest (IRGenFunction &IGF,
@@ -1668,8 +1656,7 @@ namespace {
1668
1656
}
1669
1657
1670
1658
// / Emit a call into the runtime to get the current enum payload tag.
1671
- // / This returns a tag index in the range
1672
- // / [-ElementsWithPayload..ElementsWithNoPayload-1].
1659
+ // / This returns a tag index in the range [0..NumElements-1].
1673
1660
llvm::Value *emitGetEnumTag (IRGenFunction &IGF, SILType T,
1674
1661
Address enumAddr) const override {
1675
1662
auto numEmptyCases =
@@ -2033,8 +2020,7 @@ namespace {
2033
2020
2034
2021
auto emitCase = [&](Element elt) {
2035
2022
auto tagVal =
2036
- llvm::ConstantInt::get (IGF.IGM .Int32Ty ,
2037
- getResilientTagIndex (elt.decl ));
2023
+ llvm::ConstantInt::get (IGF.IGM .Int32Ty , getTagIndex (elt.decl ));
2038
2024
auto found = destMap.find (elt.decl );
2039
2025
if (found != destMap.end ())
2040
2026
swi->addCase (tagVal, found->second );
@@ -2100,7 +2086,8 @@ namespace {
2100
2086
2101
2087
// Non-payload cases use extra inhabitants, if any, or are discriminated
2102
2088
// by setting the tag bits.
2103
- unsigned tagIndex = getResilientTagIndex (elt);
2089
+ // Use the index from ElementsWithNoPayload.
2090
+ unsigned tagIndex = getTagIndex (elt) - 1 ;
2104
2091
unsigned numExtraInhabitants = getNumExtraInhabitantTagValues ();
2105
2092
APInt payload;
2106
2093
unsigned extraTagValue;
@@ -2251,9 +2238,9 @@ namespace {
2251
2238
// Ask the runtime what case we have.
2252
2239
llvm::Value *which = emitGetEnumTag (IGF, T, addr);
2253
2240
2254
- // If it's -1 then we have the payload.
2255
- llvm::Value *hasPayload = IGF.Builder .CreateICmpEQ (which,
2256
- llvm::ConstantInt::getSigned (IGF.IGM .Int32Ty , - 1 ));
2241
+ // If it's 0 then we have the payload.
2242
+ llvm::Value *hasPayload = IGF.Builder .CreateICmpEQ (
2243
+ which, llvm::ConstantInt::get (IGF.IGM .Int32Ty , 0 ));
2257
2244
IGF.Builder .CreateCondBr (hasPayload, payloadBB, noPayloadBB);
2258
2245
2259
2246
IGF.Builder .emitBlock (payloadBB);
@@ -2508,7 +2495,7 @@ namespace {
2508
2495
2509
2496
auto PayloadT = getPayloadType (IGF.IGM , T);
2510
2497
auto Addr = Address (opaqueAddr, dest.getAlignment ());
2511
- auto *whichCase = llvm::ConstantInt::getSigned (IGF.IGM .Int32Ty , - 1 );
2498
+ auto *whichCase = llvm::ConstantInt::get (IGF.IGM .Int32Ty , 0 );
2512
2499
auto *numEmptyCases =
2513
2500
llvm::ConstantInt::get (IGF.IGM .Int32Ty , ElementsWithNoPayload.size ());
2514
2501
emitStoreEnumTagSinglePayloadCall (IGF, PayloadT, whichCase, numEmptyCases,
@@ -2778,14 +2765,14 @@ namespace {
2778
2765
// If the enum isn't fixed-layout, get the runtime to do this for us.
2779
2766
llvm::Value *caseIndex;
2780
2767
if (Case == getPayloadElement ()) {
2781
- caseIndex = llvm::ConstantInt::getSigned (IGF.IGM .Int32Ty , - 1 );
2768
+ caseIndex = llvm::ConstantInt::get (IGF.IGM .Int32Ty , 0 );
2782
2769
} else {
2783
2770
auto found = std::find_if (ElementsWithNoPayload.begin (),
2784
2771
ElementsWithNoPayload.end (),
2785
2772
[&](Element a) { return a.decl == Case; });
2786
2773
assert (found != ElementsWithNoPayload.end () &&
2787
2774
" case not in enum?!" );
2788
- unsigned caseIndexVal = found - ElementsWithNoPayload.begin ();
2775
+ unsigned caseIndexVal = found - ElementsWithNoPayload.begin () + 1 ;
2789
2776
caseIndex = llvm::ConstantInt::get (IGF.IGM .Int32Ty , caseIndexVal);
2790
2777
}
2791
2778
@@ -2824,7 +2811,7 @@ namespace {
2824
2811
}
2825
2812
2826
2813
// / Constructs an enum value using a tag index in the range
2827
- // / [-ElementsWithPayload..ElementsWithNoPayload -1].
2814
+ // / [0..NumElements -1].
2828
2815
void emitStoreTag (IRGenFunction &IGF, SILType T, Address enumAddr,
2829
2816
llvm::Value *tag) const override {
2830
2817
auto PayloadT = getPayloadType (IGF.IGM , T);
@@ -3410,8 +3397,7 @@ namespace {
3410
3397
3411
3398
public:
3412
3399
3413
- // / Returns a tag index in the range
3414
- // / [-ElementsWithPayload..ElementsWithNoPayload+1].
3400
+ // / Returns a tag index in the range [0..NumElements-1].
3415
3401
llvm::Value *
3416
3402
emitGetEnumTag (IRGenFunction &IGF, SILType T, Address addr)
3417
3403
const override {
@@ -3421,10 +3407,7 @@ namespace {
3421
3407
3422
3408
if (TIK < Fixed) {
3423
3409
// Ask the runtime to extract the dynamically-placed tag.
3424
- llvm::Value *tagValue = loadDynamicTag (IGF, addr, T);
3425
-
3426
- // Convert fragile tag index into resilient tag index.
3427
- return IGF.Builder .CreateSub (tagValue, payloadCases);
3410
+ return loadDynamicTag (IGF, addr, T);
3428
3411
}
3429
3412
3430
3413
// For fixed-size enums, the currently inhabited case is a function of
@@ -3442,15 +3425,6 @@ namespace {
3442
3425
llvm::Value *tagValue = extractPayloadTag (IGF, payload, extraTagBits);
3443
3426
tagValue = IGF.Builder .CreateZExtOrTrunc (tagValue, IGF.IGM .Int32Ty );
3444
3427
3445
- // Subtract number of payload cases from the payload tag.
3446
- //
3447
- // If we have a payload case, this yields a negative value, which is the
3448
- // final resilient tag index.
3449
- //
3450
- // If we have a no-payload case, this yields a non-negative value, which
3451
- // is the most significant bits of the current case index.
3452
- tagValue = IGF.Builder .CreateSub (tagValue, payloadCases);
3453
-
3454
3428
// If we don't have any no-payload cases, we are done -- the payload tag
3455
3429
// alone is enough to distinguish between all cases.
3456
3430
if (ElementsWithNoPayload.empty ())
@@ -3480,21 +3454,27 @@ namespace {
3480
3454
// The no-payload cases are distributed between multiple payload tags;
3481
3455
// combine the payload tag with the payload value.
3482
3456
3457
+ // First, subtract number of payload cases from the payload tag to get
3458
+ // the most significant bits of the current case.
3459
+ currentCase = IGF.Builder .CreateSub (tagValue, payloadCases);
3460
+
3483
3461
// Shift the most significant bits of the tag value into place.
3484
3462
llvm::Constant *numCaseBitsVal =
3485
3463
llvm::ConstantInt::get (IGF.IGM .Int32Ty , numCaseBits);
3486
- currentCase = IGF.Builder .CreateShl (tagValue , numCaseBitsVal);
3464
+ currentCase = IGF.Builder .CreateShl (currentCase , numCaseBitsVal);
3487
3465
3488
3466
// Add the payload value to the shifted payload tag.
3489
3467
//
3490
3468
// The result is a tag index in the range [0..ElementsWithNoPayload],
3491
3469
// so we are done.
3492
3470
currentCase = IGF.Builder .CreateOr (currentCase, payloadValue);
3493
3471
}
3472
+ // Now, we have the index of a no-payload case. Add the number of payload
3473
+ // cases back, to get an index of a case.
3474
+ currentCase = IGF.Builder .CreateAdd (currentCase, payloadCases);
3494
3475
3495
3476
// Test if this is a payload or no-payload case.
3496
- llvm::Value *match = IGF.Builder .CreateICmpSGE (tagValue,
3497
- llvm::ConstantInt::get (IGF.IGM .Int32Ty , 0 ));
3477
+ llvm::Value *match = IGF.Builder .CreateICmpUGE (tagValue, payloadCases);
3498
3478
3499
3479
// Return one of the two values we computed based on the above.
3500
3480
return IGF.Builder .CreateSelect (match, currentCase, tagValue);
@@ -3734,8 +3714,7 @@ namespace {
3734
3714
3735
3715
auto emitCase = [&](Element elt) {
3736
3716
auto tagVal =
3737
- llvm::ConstantInt::get (IGF.IGM .Int32Ty ,
3738
- getTagIndex (elt.decl ));
3717
+ llvm::ConstantInt::get (IGF.IGM .Int32Ty , getTagIndex (elt.decl ));
3739
3718
auto found = destMap.find (elt.decl );
3740
3719
if (found != destMap.end ())
3741
3720
tagSwitch->addCase (tagVal, found->second );
@@ -4666,17 +4645,11 @@ namespace {
4666
4645
4667
4646
// Use the runtime to initialize dynamic cases.
4668
4647
if (TIK < Fixed) {
4669
- // Convert resilient tag index into fragile tag index.
4670
- tag = IGF.Builder .CreateAdd (tag, numPayloadCases);
4671
-
4672
4648
return storeDynamicTag (IGF, enumAddr, tag, T);
4673
4649
}
4674
4650
4675
4651
// If there are no empty cases, don't need a conditional.
4676
4652
if (ElementsWithNoPayload.empty ()) {
4677
- // Convert resilient tag index into fragile tag index.
4678
- tag = IGF.Builder .CreateAdd (tag, numPayloadCases);
4679
-
4680
4653
storePayloadTag (IGF, enumAddr, tag, T);
4681
4654
return ;
4682
4655
}
@@ -4686,24 +4659,21 @@ namespace {
4686
4659
auto payloadBB = llvm::BasicBlock::Create (C);
4687
4660
auto endBB = llvm::BasicBlock::Create (C);
4688
4661
4689
- llvm::Value *cond = IGF.Builder .CreateICmpSGE (tag,
4690
- llvm::ConstantInt::get (IGF.IGM .Int32Ty , 0 ));
4662
+ llvm::Value *cond = IGF.Builder .CreateICmpUGE (tag, numPayloadCases);
4691
4663
IGF.Builder .CreateCondBr (cond, noPayloadBB, payloadBB);
4692
4664
4693
4665
IGF.Builder .emitBlock (noPayloadBB);
4694
4666
{
4695
4667
ConditionalDominanceScope condition (IGF);
4696
- storeNoPayloadTag (IGF, enumAddr, tag, T);
4668
+ storeNoPayloadTag (IGF, enumAddr,
4669
+ IGF.Builder .CreateSub (tag, numPayloadCases), T);
4697
4670
IGF.Builder .CreateBr (endBB);
4698
4671
}
4699
4672
4700
4673
IGF.Builder .emitBlock (payloadBB);
4701
4674
{
4702
4675
ConditionalDominanceScope condition (IGF);
4703
4676
4704
- // Convert resilient tag index into fragile tag index.
4705
- tag = IGF.Builder .CreateAdd (tag, numPayloadCases);
4706
-
4707
4677
storePayloadTag (IGF, enumAddr, tag, T);
4708
4678
IGF.Builder .CreateBr (endBB);
4709
4679
}
@@ -4883,11 +4853,6 @@ namespace {
4883
4853
std::move(WithNoPayload))
4884
4854
{ }
4885
4855
4886
- int getResilientTagIndex (EnumElementDecl *) const override {
4887
- // Resilient enum's should load the tag index from a global.
4888
- llvm_unreachable (" Use loadResilientTagIndex instead" );
4889
- }
4890
-
4891
4856
llvm::Value *loadResilientTagIndex (IRGenFunction &IGF,
4892
4857
EnumElementDecl *Case) const {
4893
4858
auto address = IGF.IGM .getAddrOfEnumCase (Case, NotForDefinition);
@@ -5223,9 +5188,8 @@ EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
5223
5188
5224
5189
// Resilient enums are manipulated as opaque values, except we still
5225
5190
// make the following assumptions:
5226
- // 1) Physical case indices won't change
5227
- // 2) The indirect-ness of cases won't change
5228
- // 3) Payload types won't change in a non-resilient way
5191
+ // 1) The indirect-ness of cases won't change
5192
+ // 2) Payload types won't change in a non-resilient way
5229
5193
bool isResilient = TC.IGM .isResilient (theEnum, ResilienceExpansion::Maximal);
5230
5194
5231
5195
// The most general resilience scope where the enum type is visible.
@@ -5310,12 +5274,6 @@ EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
5310
5274
}
5311
5275
}
5312
5276
5313
-
5314
- // Resilient tag numbering decreases for payload tags, so reverse the
5315
- // payload tags if this enum is resilient from any context.
5316
- if (TC.IGM .isResilient (theEnum, ResilienceExpansion::Minimal))
5317
- std::reverse (elementsWithPayload.begin (), elementsWithPayload.end ());
5318
-
5319
5277
assert (numElements == elementsWithPayload.size ()
5320
5278
+ elementsWithNoPayload.size ()
5321
5279
&& " not all elements accounted for" );
0 commit comments