Skip to content

Commit 75d9e56

Browse files
authored
Merge pull request #18630 from jckarter/extra-inhabitants-from-any-fixed-layout-struct-field
IRGen: Use any field of fixed-layout structs for extra inhabitants.
2 parents 2fe4235 + 9f02ecd commit 75d9e56

18 files changed

+562
-106
lines changed

lib/IRGen/FixedTypeInfo.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ class FixedTypeInfo : public TypeInfo {
168168
/// Map an extra inhabitant representation in memory to a unique 31-bit
169169
/// identifier, and map a valid representation of the type to -1.
170170
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
171-
Address src, SILType T) const override {
171+
Address src, SILType T,
172+
bool isOutlined) const override {
172173
return getSpareBitExtraInhabitantIndex(IGF, src);
173174
}
174175

@@ -181,7 +182,8 @@ class FixedTypeInfo : public TypeInfo {
181182
/// to memory.
182183
void storeExtraInhabitant(IRGenFunction &IGF,
183184
llvm::Value *index,
184-
Address dest, SILType T) const override {
185+
Address dest, SILType T,
186+
bool isOutlined) const override {
185187
storeSpareBitExtraInhabitant(IGF, index, dest);
186188
}
187189

lib/IRGen/GenEnum.cpp

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,8 @@ namespace {
641641
}
642642

643643
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
644-
Address src, SILType T)
644+
Address src, SILType T,
645+
bool isOutlined)
645646
const override {
646647
if (!getSingleton()) {
647648
// Any empty value is a valid value.
@@ -650,19 +651,22 @@ namespace {
650651

651652
return getSingleton()->getExtraInhabitantIndex(IGF,
652653
getSingletonAddress(IGF, src),
653-
getSingletonType(IGF.IGM, T));
654+
getSingletonType(IGF.IGM, T),
655+
isOutlined);
654656
}
655657

656658
void storeExtraInhabitant(IRGenFunction &IGF,
657659
llvm::Value *index,
658-
Address dest, SILType T) const override {
660+
Address dest, SILType T,
661+
bool isOutlined) const override {
659662
if (!getSingleton()) {
660663
// Nothing to store for empty singletons.
661664
return;
662665
}
663666
getSingleton()->storeExtraInhabitant(IGF, index,
664667
getSingletonAddress(IGF, dest),
665-
getSingletonType(IGF.IGM, T));
668+
getSingletonType(IGF.IGM, T),
669+
isOutlined);
666670
}
667671

668672
unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override {
@@ -1014,7 +1018,8 @@ namespace {
10141018
}
10151019

10161020
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
1017-
Address src, SILType T)
1021+
Address src, SILType T,
1022+
bool isOutlined)
10181023
const override {
10191024
auto &C = IGF.IGM.getLLVMContext();
10201025

@@ -1044,7 +1049,8 @@ namespace {
10441049

10451050
void storeExtraInhabitant(IRGenFunction &IGF,
10461051
llvm::Value *index,
1047-
Address dest, SILType T) const override {
1052+
Address dest, SILType T,
1053+
bool isOutlined) const override {
10481054
auto &C = IGF.IGM.getLLVMContext();
10491055
auto payloadTy = llvm::IntegerType::get(C,
10501056
cast<FixedTypeInfo>(TI)->getFixedSize().getValueInBits());
@@ -1119,13 +1125,15 @@ namespace {
11191125
}
11201126

11211127
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
1122-
Address src, SILType T) const override {
1128+
Address src, SILType T,
1129+
bool isOutlined) const override {
11231130
llvm_unreachable("no extra inhabitants");
11241131
}
11251132

11261133
void storeExtraInhabitant(IRGenFunction &IGF,
11271134
llvm::Value *index,
1128-
Address dest, SILType T) const override {
1135+
Address dest, SILType T,
1136+
bool isOutlined) const override {
11291137
llvm_unreachable("no extra inhabitants");
11301138
}
11311139

@@ -2915,11 +2923,13 @@ namespace {
29152923

29162924
llvm::Value *
29172925
getExtraInhabitantIndex(IRGenFunction &IGF,
2918-
Address src, SILType T) const override {
2926+
Address src, SILType T,
2927+
bool isOutlined) const override {
29192928
auto payload = projectPayloadData(IGF, src);
29202929
llvm::Value *index
29212930
= getPayloadTypeInfo().getExtraInhabitantIndex(IGF, payload,
2922-
getPayloadType(IGF.IGM, T));
2931+
getPayloadType(IGF.IGM, T),
2932+
isOutlined);
29232933

29242934
// Offset the payload extra inhabitant index by the number of inhabitants
29252935
// we used. If less than zero, it's a valid value of the enum type.
@@ -2935,14 +2945,16 @@ namespace {
29352945

29362946
void storeExtraInhabitant(IRGenFunction &IGF,
29372947
llvm::Value *index,
2938-
Address dest, SILType T) const override {
2948+
Address dest, SILType T,
2949+
bool isOutlined) const override {
29392950
// Offset the index to skip the extra inhabitants we used.
29402951
index = IGF.Builder.CreateAdd(index,
29412952
llvm::ConstantInt::get(IGF.IGM.Int32Ty, ElementsWithNoPayload.size()));
29422953

29432954
auto payload = projectPayloadData(IGF, dest);
29442955
getPayloadTypeInfo().storeExtraInhabitant(IGF, index, payload,
2945-
getPayloadType(IGF.IGM, T));
2956+
getPayloadType(IGF.IGM, T),
2957+
isOutlined);
29462958
}
29472959

29482960
APInt
@@ -4811,14 +4823,16 @@ namespace {
48114823

48124824
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
48134825
Address src,
4814-
SILType T) const override {
4826+
SILType T,
4827+
bool isOutlined) const override {
48154828
llvm_unreachable("extra inhabitants for multi-payload enums not implemented");
48164829
}
48174830

48184831
void storeExtraInhabitant(IRGenFunction &IGF,
48194832
llvm::Value *index,
48204833
Address dest,
4821-
SILType T) const override {
4834+
SILType T,
4835+
bool isOutlined) const override {
48224836
llvm_unreachable("extra inhabitants for multi-payload enums not implemented");
48234837
}
48244838

@@ -5204,14 +5218,16 @@ namespace {
52045218

52055219
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
52065220
Address src,
5207-
SILType T) const override {
5221+
SILType T,
5222+
bool isOutlined) const override {
52085223
return emitGetExtraInhabitantIndexCall(IGF, T, src);
52095224
}
52105225

52115226
void storeExtraInhabitant(IRGenFunction &IGF,
52125227
llvm::Value *index,
52135228
Address dest,
5214-
SILType T) const override {
5229+
SILType T,
5230+
bool isOutlined) const override {
52155231
emitStoreExtraInhabitantCall(IGF, T, index, dest);
52165232
}
52175233

@@ -5436,14 +5452,16 @@ namespace {
54365452
}
54375453
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
54385454
Address src,
5439-
SILType T) const override {
5440-
return Strategy.getExtraInhabitantIndex(IGF, src, T);
5455+
SILType T,
5456+
bool isOutlined) const override {
5457+
return Strategy.getExtraInhabitantIndex(IGF, src, T, isOutlined);
54415458
}
54425459
void storeExtraInhabitant(IRGenFunction &IGF,
54435460
llvm::Value *index,
54445461
Address dest,
5445-
SILType T) const override {
5446-
return Strategy.storeExtraInhabitant(IGF, index, dest, T);
5462+
SILType T,
5463+
bool isOutlined) const override {
5464+
return Strategy.storeExtraInhabitant(IGF, index, dest, T, isOutlined);
54475465
}
54485466
bool isSingleRetainablePointer(ResilienceExpansion expansion,
54495467
ReferenceCounting *rc) const override {

lib/IRGen/GenEnum.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,13 @@ class EnumImplStrategy {
375375

376376
virtual llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
377377
Address src,
378-
SILType T) const = 0;
378+
SILType T,
379+
bool isOutlined) const = 0;
379380
virtual void storeExtraInhabitant(IRGenFunction &IGF,
380381
llvm::Value *index,
381382
Address dest,
382-
SILType T) const = 0;
383+
SILType T,
384+
bool isOutlined) const = 0;
383385

384386
/// \group Delegated FixedTypeInfo operations
385387

lib/IRGen/GenExistential.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -554,20 +554,21 @@ namespace {
554554
}
555555

556556
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src,
557-
SILType T)
557+
SILType T, bool isOutlined)
558558
const override {
559559
// NB: We assume that the witness table slots are zero if an extra
560560
// inhabitant is stored in the container.
561561
src = projectValue(IGF, src);
562562
return asDerived().getValueTypeInfoForExtraInhabitants(IGF.IGM)
563-
.getExtraInhabitantIndex(IGF, src, SILType());
563+
.getExtraInhabitantIndex(IGF, src, SILType(), isOutlined);
564564
}
565565

566566
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index,
567-
Address dest, SILType T) const override {
567+
Address dest, SILType T, bool isOutlined)
568+
const override {
568569
Address valueDest = projectValue(IGF, dest);
569570
asDerived().getValueTypeInfoForExtraInhabitants(IGF.IGM)
570-
.storeExtraInhabitant(IGF, index, valueDest, SILType());
571+
.storeExtraInhabitant(IGF, index, valueDest, SILType(), isOutlined);
571572
}
572573

573574
APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override {
@@ -615,23 +616,25 @@ namespace {
615616
} \
616617
} \
617618
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, \
618-
SILType T) const override { \
619+
SILType T, bool isOutlined) \
620+
const override { \
619621
Address valueSrc = projectValue(IGF, src); \
620622
if (shouldStoreExtraInhabitantsInRef(IGF.IGM)) { \
621623
return IGF.getReferenceStorageExtraInhabitantIndex(valueSrc, \
622624
ReferenceOwnership::Name, Refcounting); \
623625
} else { \
624-
return Super::getExtraInhabitantIndex(IGF, src, T); \
626+
return Super::getExtraInhabitantIndex(IGF, src, T, isOutlined); \
625627
} \
626628
} \
627629
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, \
628-
Address dest, SILType T) const override { \
630+
Address dest, SILType T, bool isOutlined) \
631+
const override { \
629632
Address valueDest = projectValue(IGF, dest); \
630633
if (shouldStoreExtraInhabitantsInRef(IGF.IGM)) { \
631634
return IGF.storeReferenceStorageExtraInhabitant(index, valueDest, \
632635
ReferenceOwnership::Name, Refcounting); \
633636
} else { \
634-
return Super::storeExtraInhabitant(IGF, index, dest, T); \
637+
return Super::storeExtraInhabitant(IGF, index, dest, T, isOutlined); \
635638
} \
636639
} \
637640
APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override { \

lib/IRGen/GenFunc.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,14 @@ namespace {
165165
}
166166

167167
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src,
168-
SILType T)
168+
SILType T, bool isOutlined)
169169
const override {
170170
return getFunctionPointerExtraInhabitantIndex(IGF, src);
171171
}
172172

173173
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index,
174-
Address dest, SILType T) const override {
174+
Address dest, SILType T, bool isOutlined)
175+
const override {
175176
return storeFunctionPointerExtraInhabitant(IGF, index, dest);
176177
}
177178
};
@@ -411,7 +412,8 @@ namespace {
411412
}
412413

413414
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src,
414-
SILType T) const override {
415+
SILType T, bool isOutlined)
416+
const override {
415417
src = projectFunction(IGF, src);
416418
return getFunctionPointerExtraInhabitantIndex(IGF, src);
417419
}
@@ -425,7 +427,8 @@ namespace {
425427
}
426428

427429
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index,
428-
Address dest, SILType T) const override {
430+
Address dest, SILType T, bool isOutlined)
431+
const override {
429432
dest = projectFunction(IGF, dest);
430433
return storeFunctionPointerExtraInhabitant(IGF, index, dest);
431434
}

lib/IRGen/GenHeap.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,15 @@ namespace {
9797
ReferenceCounting::Nativeness); \
9898
} \
9999
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, \
100-
SILType T) const override { \
100+
SILType T, bool isOutlined) \
101+
const override { \
101102
return IGF.getReferenceStorageExtraInhabitantIndex(src, \
102103
ReferenceOwnership::Name, \
103104
ReferenceCounting::Nativeness); \
104105
} \
105106
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, \
106-
Address dest, SILType T) const override { \
107+
Address dest, SILType T, bool isOutlined) \
108+
const override { \
107109
return IGF.storeReferenceStorageExtraInhabitant(index, dest, \
108110
ReferenceOwnership::Name, \
109111
ReferenceCounting::Nativeness); \
@@ -166,13 +168,15 @@ namespace {
166168
ReferenceCounting::Nativeness); \
167169
} \
168170
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, \
169-
SILType T) const override { \
171+
SILType T, bool isOutlined) \
172+
const override { \
170173
return IGF.getReferenceStorageExtraInhabitantIndex(src, \
171174
ReferenceOwnership::Name, \
172175
ReferenceCounting::Nativeness); \
173176
} \
174177
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, \
175-
Address dest, SILType T) const override { \
178+
Address dest, SILType T, bool isOutlined) \
179+
const override { \
176180
return IGF.storeReferenceStorageExtraInhabitant(index, dest, \
177181
ReferenceOwnership::Name, \
178182
ReferenceCounting::Nativeness); \
@@ -217,12 +221,13 @@ namespace {
217221
index + IsOptional, 0); \
218222
} \
219223
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, \
220-
SILType T) \
224+
SILType T, bool isOutlined) \
221225
const override { \
222226
return getHeapObjectExtraInhabitantIndex(IGF, src); \
223227
} \
224228
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, \
225-
Address dest, SILType T) const override { \
229+
Address dest, SILType T, bool isOutlined) \
230+
const override { \
226231
return storeHeapObjectExtraInhabitant(IGF, index, dest); \
227232
} \
228233
};

lib/IRGen/GenObjC.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ namespace {
278278
return APInt(bits, 0);
279279
}
280280
llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src,
281-
SILType T) const override {
281+
SILType T,
282+
bool isOutlined) const override {
282283
src = IGF.Builder.CreateBitCast(src, IGF.IGM.SizeTy->getPointerTo());
283284
auto val = IGF.Builder.CreateLoad(src);
284285
auto isNonzero = IGF.Builder.CreateICmpNE(val,
@@ -288,7 +289,8 @@ namespace {
288289
return IGF.Builder.CreateSExt(isNonzero, IGF.IGM.Int32Ty);
289290
}
290291
void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index,
291-
Address dest, SILType T) const override {
292+
Address dest, SILType T, bool isOutlined)
293+
const override {
292294
// There's only one extra inhabitant, 0.
293295
dest = IGF.Builder.CreateBitCast(dest, IGF.IGM.SizeTy->getPointerTo());
294296
IGF.Builder.CreateStore(llvm::ConstantInt::get(IGF.IGM.SizeTy, 0), dest);

0 commit comments

Comments
 (0)