Skip to content

Commit 19fbe5b

Browse files
Merge pull request #72034 from nate-chandler/rdar123560548-onone
[IRGen] Outlined consume functions call noncopyable deinits.
2 parents c2eb9cc + f638918 commit 19fbe5b

15 files changed

+1124
-153
lines changed

lib/IRGen/GenArchetype.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "IRGenDebugInfo.h"
4949
#include "IRGenFunction.h"
5050
#include "IRGenModule.h"
51+
#include "LocalTypeData.h"
5152
#include "MetadataRequest.h"
5253
#include "Outlining.h"
5354
#include "ProtocolInfo.h"
@@ -75,6 +76,25 @@ irgen::emitArchetypeTypeMetadataRef(IRGenFunction &IGF,
7576
return emitOpaqueTypeMetadataRef(IGF, opaque, request);
7677
}
7778

79+
#ifndef NDEBUG
80+
if (!archetype->getParent()) {
81+
llvm::errs() << "Metadata for archetype not bound in function.\n"
82+
<< " The metadata could be missing entirely because it needs "
83+
"to be passed to the function.\n"
84+
<< " Or the metadata is present and not bound in which case "
85+
"setScopedLocalTypeMetadata or similar must be called.\n";
86+
llvm::errs() << "Archetype without metadata: " << archetype << "\n";
87+
archetype->dump(llvm::errs());
88+
llvm::errs() << "Function:\n";
89+
IGF.CurFn->print(llvm::errs());
90+
if (auto localTypeData = IGF.getLocalTypeData()) {
91+
llvm::errs() << "LocalTypeData:\n";
92+
localTypeData->dump();
93+
} else {
94+
llvm::errs() << "No LocalTypeDataCache for this function!\n";
95+
}
96+
}
97+
#endif
7898
// If there's no local or opaque metadata, it must be a nested type.
7999
assert(archetype->getParent() && "Not a nested archetype");
80100

@@ -115,7 +135,7 @@ class OpaqueArchetypeTypeInfo
115135
void collectMetadataForOutlining(OutliningMetadataCollector &collector,
116136
SILType T) const override {
117137
// We'll need formal type metadata for this archetype.
118-
collector.collectTypeMetadataForLayout(T);
138+
collector.collectTypeMetadata(T);
119139
}
120140

121141
TypeLayoutEntry

lib/IRGen/GenEnum.cpp

Lines changed: 85 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ namespace {
631631
return;
632632
getSingleton()->collectMetadataForOutlining(collector,
633633
getSingletonType(collector.IGF.IGM, T));
634-
collector.collectTypeMetadataForLayout(T);
634+
collector.collectTypeMetadata(T);
635635
}
636636

637637
void reexplode(Explosion &src, Explosion &dest)
@@ -1639,10 +1639,11 @@ namespace {
16391639
return {payload, extraTag};
16401640
}
16411641
std::pair<EnumPayload, llvm::Value *>
1642-
getPayloadAndExtraTagFromExplosionOutlined(IRGenFunction &IGF,
1643-
Explosion &src) const {
1642+
getPayloadAndExtraTagFromExplosionOutlined(
1643+
IRGenFunction &IGF, Explosion &src,
1644+
OutliningMetadataCollector *collector) const {
16441645
EnumPayload payload;
1645-
unsigned claimSZ = src.size();
1646+
unsigned claimSZ = src.size() - (collector ? collector->size() : 0);
16461647
if (ExtraTagBitCount > 0) {
16471648
--claimSZ;
16481649
}
@@ -1833,7 +1834,7 @@ namespace {
18331834
EnumPayload payload;
18341835
llvm::Value *extraTag;
18351836
std::tie(payload, extraTag) =
1836-
getPayloadAndExtraTagFromExplosionOutlined(IGF, src);
1837+
getPayloadAndExtraTagFromExplosionOutlined(IGF, src, nullptr);
18371838
llvm::BasicBlock *endBB =
18381839
testFixedEnumContainsPayload(IGF, payload, extraTag);
18391840

@@ -1854,15 +1855,35 @@ namespace {
18541855
return func;
18551856
}
18561857

1857-
llvm::Function *emitConsumeEnumFunction(IRGenModule &IGM,
1858-
SILType theEnumType) const {
1858+
void emitCallToConsumeEnumFunction(IRGenFunction &IGF, Explosion &src,
1859+
SILType theEnumType) const {
1860+
OutliningMetadataCollector collector(theEnumType, IGF, LayoutIsNotNeeded,
1861+
DeinitIsNeeded);
1862+
IGF.getTypeInfo(theEnumType)
1863+
.collectMetadataForOutlining(collector, theEnumType);
1864+
if (!consumeEnumFunction)
1865+
consumeEnumFunction =
1866+
emitConsumeEnumFunction(IGF.IGM, theEnumType, collector);
1867+
Explosion tmp;
1868+
fillExplosionForOutlinedCall(IGF, src, tmp, &collector);
1869+
llvm::CallInst *call = IGF.Builder.CreateCallWithoutDbgLoc(
1870+
consumeEnumFunction->getFunctionType(), consumeEnumFunction,
1871+
tmp.claimAll());
1872+
call->setCallingConv(IGM.DefaultCC);
1873+
}
1874+
1875+
llvm::Function *
1876+
emitConsumeEnumFunction(IRGenModule &IGM, SILType theEnumType,
1877+
OutliningMetadataCollector &collector) const {
18591878
IRGenMangler Mangler;
18601879
auto manglingBits =
18611880
getTypeAndGenericSignatureForManglingOutlineFunction(theEnumType);
18621881
std::string name =
18631882
Mangler.mangleOutlinedConsumeFunction(manglingBits.first,
18641883
manglingBits.second);
1865-
auto func = createOutlineLLVMFunction(IGM, name, PayloadTypesAndTagType);
1884+
SmallVector<llvm::Type *, 2> params(PayloadTypesAndTagType);
1885+
collector.addPolymorphicParameterTypes(params);
1886+
auto func = createOutlineLLVMFunction(IGM, name, params);
18661887

18671888
IRGenFunction IGF(IGM, func);
18681889
Explosion src = IGF.collectParameters();
@@ -1872,7 +1893,8 @@ namespace {
18721893
EnumPayload payload;
18731894
llvm::Value *extraTag;
18741895
std::tie(payload, extraTag) =
1875-
getPayloadAndExtraTagFromExplosionOutlined(IGF, src);
1896+
getPayloadAndExtraTagFromExplosionOutlined(IGF, src, &collector);
1897+
collector.bindPolymorphicParameters(IGF, src);
18761898
llvm::BasicBlock *endBB =
18771899
testFixedEnumContainsPayload(IGF, payload, extraTag);
18781900

@@ -2666,8 +2688,10 @@ namespace {
26662688
}
26672689
}
26682690

2669-
void fillExplosionForOutlinedCall(IRGenFunction &IGF, Explosion &src,
2670-
Explosion &out) const {
2691+
void
2692+
fillExplosionForOutlinedCall(IRGenFunction &IGF, Explosion &src,
2693+
Explosion &out,
2694+
OutliningMetadataCollector *collector) const {
26712695
assert(out.empty() && "Out explosion must be empty!");
26722696
EnumPayload payload;
26732697
llvm::Value *extraTag;
@@ -2676,8 +2700,16 @@ namespace {
26762700
payload.explode(IGM, out);
26772701
if (extraTag)
26782702
out.add(extraTag);
2703+
2704+
if (!collector)
2705+
return;
2706+
llvm::SmallVector<llvm::Value *, 4> args;
2707+
collector->addPolymorphicArguments(args);
2708+
for (auto *arg : args) {
2709+
out.add(arg);
2710+
}
26792711
}
2680-
2712+
26812713
void unpackIntoPayloadExplosion(IRGenFunction &IGF,
26822714
Explosion &asEnumIn,
26832715
Explosion &asPayloadOut) const {
@@ -2737,7 +2769,7 @@ namespace {
27372769
if (!copyEnumFunction)
27382770
copyEnumFunction = emitCopyEnumFunction(IGM, loweredType);
27392771
Explosion tmp;
2740-
fillExplosionForOutlinedCall(IGF, src, tmp);
2772+
fillExplosionForOutlinedCall(IGF, src, tmp, nullptr);
27412773
llvm::CallInst *call = IGF.Builder.CreateCallWithoutDbgLoc(
27422774
copyEnumFunction->getFunctionType(), copyEnumFunction,
27432775
tmp.getAll());
@@ -2806,14 +2838,7 @@ namespace {
28062838
IGF.Builder.emitBlock(endBB);
28072839
return;
28082840
}
2809-
if (!consumeEnumFunction)
2810-
consumeEnumFunction = emitConsumeEnumFunction(IGM, loweredType);
2811-
Explosion tmp;
2812-
fillExplosionForOutlinedCall(IGF, src, tmp);
2813-
llvm::CallInst *call = IGF.Builder.CreateCallWithoutDbgLoc(
2814-
consumeEnumFunction->getFunctionType(), consumeEnumFunction,
2815-
tmp.claimAll());
2816-
call->setCallingConv(IGM.DefaultCC);
2841+
emitCallToConsumeEnumFunction(IGF, src, T);
28172842
return;
28182843
}
28192844

@@ -3239,7 +3264,7 @@ namespace {
32393264
auto payloadT = getPayloadType(IGM, T);
32403265
getPayloadTypeInfo().collectMetadataForOutlining(collector, payloadT);
32413266
}
3242-
collector.collectTypeMetadataForLayout(T);
3267+
collector.collectTypeMetadata(T);
32433268
}
32443269

32453270
void storeTag(IRGenFunction &IGF,
@@ -3715,7 +3740,7 @@ namespace {
37153740
Explosion src = IGF.collectParameters();
37163741
if (IGM.DebugInfo)
37173742
IGM.DebugInfo->emitArtificialFunction(IGF, IGF.CurFn);
3718-
auto parts = destructureAndTagLoadableEnumFromOutlined(IGF, src);
3743+
auto parts = destructureAndTagLoadableEnumFromOutlined(IGF, src, nullptr);
37193744

37203745
forNontrivialPayloads(IGF, parts.tag, [&](unsigned tagIndex,
37213746
EnumImplStrategy::Element elt) {
@@ -3732,21 +3757,26 @@ namespace {
37323757
return func;
37333758
}
37343759

3735-
llvm::Function *emitConsumeEnumFunction(IRGenModule &IGM,
3736-
SILType type) const {
3760+
llvm::Function *
3761+
emitConsumeEnumFunction(IRGenModule &IGM, SILType type,
3762+
OutliningMetadataCollector &collector) const {
37373763
IRGenMangler Mangler;
37383764
auto manglingBits =
37393765
getTypeAndGenericSignatureForManglingOutlineFunction(type);
37403766
std::string name =
37413767
Mangler.mangleOutlinedConsumeFunction(manglingBits.first,
37423768
manglingBits.second);
3743-
auto func = createOutlineLLVMFunction(IGM, name, PayloadTypesAndTagType);
3769+
SmallVector<llvm::Type *, 2> params(PayloadTypesAndTagType);
3770+
collector.addPolymorphicParameterTypes(params);
3771+
auto func = createOutlineLLVMFunction(IGM, name, params);
37443772

37453773
IRGenFunction IGF(IGM, func);
37463774
if (IGM.DebugInfo)
37473775
IGM.DebugInfo->emitArtificialFunction(IGF, IGF.CurFn);
37483776
Explosion src = IGF.collectParameters();
3749-
auto parts = destructureAndTagLoadableEnumFromOutlined(IGF, src);
3777+
auto parts =
3778+
destructureAndTagLoadableEnumFromOutlined(IGF, src, &collector);
3779+
collector.bindPolymorphicParameters(IGF, src);
37503780

37513781
forNontrivialPayloads(IGF, parts.tag, [&](unsigned tagIndex,
37523782
EnumImplStrategy::Element elt) {
@@ -3801,12 +3831,15 @@ namespace {
38013831
bool allTriviallyDestroyable = true;
38023832
bool allBitwiseTakable = true;
38033833
bool allSingleRefcount = true;
3834+
bool allCopyable = true;
38043835
bool haveRefcounting = false;
38053836
for (auto &elt : ElementsWithPayload) {
38063837
if (!elt.ti->isTriviallyDestroyable(ResilienceExpansion::Maximal))
38073838
allTriviallyDestroyable = false;
38083839
if (!elt.ti->isBitwiseTakable(ResilienceExpansion::Maximal))
38093840
allBitwiseTakable = false;
3841+
if (!elt.ti->isCopyable(ResilienceExpansion::Maximal))
3842+
allCopyable = false;
38103843

38113844
// refcounting is only set in the else branches
38123845
ReferenceCounting refcounting;
@@ -3836,7 +3869,7 @@ namespace {
38363869
} else if (allSingleRefcount
38373870
&& ElementsWithNoPayload.size() <= 1) {
38383871
CopyDestroyKind = TaggedRefcounted;
3839-
} else if (allBitwiseTakable) {
3872+
} else if (allBitwiseTakable && allCopyable) {
38403873
CopyDestroyKind = BitwiseTakable;
38413874
}
38423875
}
@@ -4023,11 +4056,11 @@ namespace {
40234056

40244057
return {destructured.payload, destructured.extraTagBits, tag};
40254058
}
4026-
DestructuredAndTaggedLoadableEnum
4027-
destructureAndTagLoadableEnumFromOutlined(IRGenFunction &IGF,
4028-
Explosion &src) const {
4059+
DestructuredAndTaggedLoadableEnum destructureAndTagLoadableEnumFromOutlined(
4060+
IRGenFunction &IGF, Explosion &src,
4061+
OutliningMetadataCollector *collector) const {
40294062
EnumPayload payload;
4030-
unsigned claimSZ = src.size();
4063+
unsigned claimSZ = src.size() - (collector ? collector->size() : 0);
40314064
if (ExtraTagBitCount > 0) {
40324065
--claimSZ;
40334066
}
@@ -4697,13 +4730,23 @@ namespace {
46974730
payload.emitApplyAndMask(IGF, mask);
46984731
}
46994732

4700-
void fillExplosionForOutlinedCall(IRGenFunction &IGF, Explosion &src,
4701-
Explosion &out) const {
4733+
void
4734+
fillExplosionForOutlinedCall(IRGenFunction &IGF, Explosion &src,
4735+
Explosion &out,
4736+
OutliningMetadataCollector *collector) const {
47024737
assert(out.empty() && "Out explosion must be empty!");
47034738
auto parts = destructureAndTagLoadableEnum(IGF, src);
47044739
parts.payload.explode(IGM, out);
47054740
if (parts.extraTagBits)
47064741
out.add(parts.extraTagBits);
4742+
4743+
if (!collector)
4744+
return;
4745+
llvm::SmallVector<llvm::Value *, 4> args;
4746+
collector->addPolymorphicArguments(args);
4747+
for (auto *arg : args) {
4748+
out.add(arg);
4749+
}
47074750
}
47084751

47094752
public:
@@ -4761,7 +4804,7 @@ namespace {
47614804
if (!copyEnumFunction)
47624805
copyEnumFunction = emitCopyEnumFunction(IGM, loweredType);
47634806
Explosion tmp;
4764-
fillExplosionForOutlinedCall(IGF, src, tmp);
4807+
fillExplosionForOutlinedCall(IGF, src, tmp, nullptr);
47654808
llvm::CallInst *call = IGF.Builder.CreateCallWithoutDbgLoc(
47664809
copyEnumFunction->getFunctionType(), copyEnumFunction,
47674810
tmp.getAll());
@@ -4824,10 +4867,13 @@ namespace {
48244867
});
48254868
return;
48264869
}
4870+
OutliningMetadataCollector collector(T, IGF, LayoutIsNotNeeded,
4871+
DeinitIsNeeded);
4872+
IGF.getTypeInfo(T).collectMetadataForOutlining(collector, T);
48274873
if (!consumeEnumFunction)
4828-
consumeEnumFunction = emitConsumeEnumFunction(IGM, loweredType);
4874+
consumeEnumFunction = emitConsumeEnumFunction(IGM, T, collector);
48294875
Explosion tmp;
4830-
fillExplosionForOutlinedCall(IGF, src, tmp);
4876+
fillExplosionForOutlinedCall(IGF, src, tmp, &collector);
48314877
llvm::CallInst *call = IGF.Builder.CreateCallWithoutDbgLoc(
48324878
consumeEnumFunction->getFunctionType(), consumeEnumFunction,
48334879
tmp.claimAll());
@@ -5134,7 +5180,7 @@ namespace {
51345180
auto &payloadTI = *payloadCasePair.ti;
51355181
payloadTI.collectMetadataForOutlining(collector, payloadT);
51365182
}
5137-
collector.collectTypeMetadataForLayout(T);
5183+
collector.collectTypeMetadata(T);
51385184
}
51395185

51405186
void destroy(IRGenFunction &IGF, Address addr, SILType T,
@@ -6051,7 +6097,7 @@ namespace {
60516097

60526098
void collectMetadataForOutlining(OutliningMetadataCollector &collector,
60536099
SILType T) const override {
6054-
collector.collectTypeMetadataForLayout(T);
6100+
collector.collectTypeMetadata(T);
60556101
}
60566102

60576103
void destroy(IRGenFunction &IGF, Address addr, SILType T,

0 commit comments

Comments
 (0)