@@ -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