@@ -3740,7 +3740,7 @@ namespace {
37403740 Explosion src = IGF.collectParameters ();
37413741 if (IGM.DebugInfo )
37423742 IGM.DebugInfo ->emitArtificialFunction (IGF, IGF.CurFn );
3743- auto parts = destructureAndTagLoadableEnumFromOutlined (IGF, src);
3743+ auto parts = destructureAndTagLoadableEnumFromOutlined (IGF, src, nullptr );
37443744
37453745 forNontrivialPayloads (IGF, parts.tag , [&](unsigned tagIndex,
37463746 EnumImplStrategy::Element elt) {
@@ -3757,21 +3757,26 @@ namespace {
37573757 return func;
37583758 }
37593759
3760- llvm::Function *emitConsumeEnumFunction (IRGenModule &IGM,
3761- SILType type) const {
3760+ llvm::Function *
3761+ emitConsumeEnumFunction (IRGenModule &IGM, SILType type,
3762+ OutliningMetadataCollector &collector) const {
37623763 IRGenMangler Mangler;
37633764 auto manglingBits =
37643765 getTypeAndGenericSignatureForManglingOutlineFunction (type);
37653766 std::string name =
37663767 Mangler.mangleOutlinedConsumeFunction (manglingBits.first ,
37673768 manglingBits.second );
3768- auto func = createOutlineLLVMFunction (IGM, name, PayloadTypesAndTagType);
3769+ SmallVector<llvm::Type *, 2 > params (PayloadTypesAndTagType);
3770+ collector.addPolymorphicParameterTypes (params);
3771+ auto func = createOutlineLLVMFunction (IGM, name, params);
37693772
37703773 IRGenFunction IGF (IGM, func);
37713774 if (IGM.DebugInfo )
37723775 IGM.DebugInfo ->emitArtificialFunction (IGF, IGF.CurFn );
37733776 Explosion src = IGF.collectParameters ();
3774- auto parts = destructureAndTagLoadableEnumFromOutlined (IGF, src);
3777+ auto parts =
3778+ destructureAndTagLoadableEnumFromOutlined (IGF, src, &collector);
3779+ collector.bindPolymorphicParameters (IGF, src);
37753780
37763781 forNontrivialPayloads (IGF, parts.tag , [&](unsigned tagIndex,
37773782 EnumImplStrategy::Element elt) {
@@ -3826,12 +3831,15 @@ namespace {
38263831 bool allTriviallyDestroyable = true ;
38273832 bool allBitwiseTakable = true ;
38283833 bool allSingleRefcount = true ;
3834+ bool allCopyable = true ;
38293835 bool haveRefcounting = false ;
38303836 for (auto &elt : ElementsWithPayload) {
38313837 if (!elt.ti ->isTriviallyDestroyable (ResilienceExpansion::Maximal))
38323838 allTriviallyDestroyable = false ;
38333839 if (!elt.ti ->isBitwiseTakable (ResilienceExpansion::Maximal))
38343840 allBitwiseTakable = false ;
3841+ if (!elt.ti ->isCopyable (ResilienceExpansion::Maximal))
3842+ allCopyable = false ;
38353843
38363844 // refcounting is only set in the else branches
38373845 ReferenceCounting refcounting;
@@ -3861,7 +3869,7 @@ namespace {
38613869 } else if (allSingleRefcount
38623870 && ElementsWithNoPayload.size () <= 1 ) {
38633871 CopyDestroyKind = TaggedRefcounted;
3864- } else if (allBitwiseTakable) {
3872+ } else if (allBitwiseTakable && allCopyable ) {
38653873 CopyDestroyKind = BitwiseTakable;
38663874 }
38673875 }
@@ -4048,11 +4056,11 @@ namespace {
40484056
40494057 return {destructured.payload , destructured.extraTagBits , tag};
40504058 }
4051- DestructuredAndTaggedLoadableEnum
4052- destructureAndTagLoadableEnumFromOutlined ( IRGenFunction &IGF,
4053- Explosion &src ) const {
4059+ DestructuredAndTaggedLoadableEnum destructureAndTagLoadableEnumFromOutlined (
4060+ IRGenFunction &IGF, Explosion &src ,
4061+ OutliningMetadataCollector *collector ) const {
40544062 EnumPayload payload;
4055- unsigned claimSZ = src.size ();
4063+ unsigned claimSZ = src.size () - (collector ? collector-> size () : 0 ) ;
40564064 if (ExtraTagBitCount > 0 ) {
40574065 --claimSZ;
40584066 }
@@ -4722,13 +4730,23 @@ namespace {
47224730 payload.emitApplyAndMask (IGF, mask);
47234731 }
47244732
4725- void fillExplosionForOutlinedCall (IRGenFunction &IGF, Explosion &src,
4726- Explosion &out) const {
4733+ void
4734+ fillExplosionForOutlinedCall (IRGenFunction &IGF, Explosion &src,
4735+ Explosion &out,
4736+ OutliningMetadataCollector *collector) const {
47274737 assert (out.empty () && " Out explosion must be empty!" );
47284738 auto parts = destructureAndTagLoadableEnum (IGF, src);
47294739 parts.payload .explode (IGM, out);
47304740 if (parts.extraTagBits )
47314741 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+ }
47324750 }
47334751
47344752 public:
@@ -4786,7 +4804,7 @@ namespace {
47864804 if (!copyEnumFunction)
47874805 copyEnumFunction = emitCopyEnumFunction (IGM, loweredType);
47884806 Explosion tmp;
4789- fillExplosionForOutlinedCall (IGF, src, tmp);
4807+ fillExplosionForOutlinedCall (IGF, src, tmp, nullptr );
47904808 llvm::CallInst *call = IGF.Builder .CreateCallWithoutDbgLoc (
47914809 copyEnumFunction->getFunctionType (), copyEnumFunction,
47924810 tmp.getAll ());
@@ -4849,10 +4867,13 @@ namespace {
48494867 });
48504868 return ;
48514869 }
4870+ OutliningMetadataCollector collector (T, IGF, LayoutIsNotNeeded,
4871+ DeinitIsNeeded);
4872+ IGF.getTypeInfo (T).collectMetadataForOutlining (collector, T);
48524873 if (!consumeEnumFunction)
4853- consumeEnumFunction = emitConsumeEnumFunction (IGM, loweredType );
4874+ consumeEnumFunction = emitConsumeEnumFunction (IGM, T, collector );
48544875 Explosion tmp;
4855- fillExplosionForOutlinedCall (IGF, src, tmp);
4876+ fillExplosionForOutlinedCall (IGF, src, tmp, &collector );
48564877 llvm::CallInst *call = IGF.Builder .CreateCallWithoutDbgLoc (
48574878 consumeEnumFunction->getFunctionType (), consumeEnumFunction,
48584879 tmp.claimAll ());
0 commit comments