@@ -631,7 +631,7 @@ namespace {
631
631
return ;
632
632
getSingleton ()->collectMetadataForOutlining (collector,
633
633
getSingletonType (collector.IGF .IGM , T));
634
- collector.collectTypeMetadataForLayout (T);
634
+ collector.collectTypeMetadata (T);
635
635
}
636
636
637
637
void reexplode (Explosion &src, Explosion &dest)
@@ -1639,10 +1639,11 @@ namespace {
1639
1639
return {payload, extraTag};
1640
1640
}
1641
1641
std::pair<EnumPayload, llvm::Value *>
1642
- getPayloadAndExtraTagFromExplosionOutlined (IRGenFunction &IGF,
1643
- Explosion &src) const {
1642
+ getPayloadAndExtraTagFromExplosionOutlined (
1643
+ IRGenFunction &IGF, Explosion &src,
1644
+ OutliningMetadataCollector *collector) const {
1644
1645
EnumPayload payload;
1645
- unsigned claimSZ = src.size ();
1646
+ unsigned claimSZ = src.size () - (collector ? collector-> size () : 0 ) ;
1646
1647
if (ExtraTagBitCount > 0 ) {
1647
1648
--claimSZ;
1648
1649
}
@@ -1833,7 +1834,7 @@ namespace {
1833
1834
EnumPayload payload;
1834
1835
llvm::Value *extraTag;
1835
1836
std::tie (payload, extraTag) =
1836
- getPayloadAndExtraTagFromExplosionOutlined (IGF, src);
1837
+ getPayloadAndExtraTagFromExplosionOutlined (IGF, src, nullptr );
1837
1838
llvm::BasicBlock *endBB =
1838
1839
testFixedEnumContainsPayload (IGF, payload, extraTag);
1839
1840
@@ -1854,15 +1855,35 @@ namespace {
1854
1855
return func;
1855
1856
}
1856
1857
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 {
1859
1878
IRGenMangler Mangler;
1860
1879
auto manglingBits =
1861
1880
getTypeAndGenericSignatureForManglingOutlineFunction (theEnumType);
1862
1881
std::string name =
1863
1882
Mangler.mangleOutlinedConsumeFunction (manglingBits.first ,
1864
1883
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);
1866
1887
1867
1888
IRGenFunction IGF (IGM, func);
1868
1889
Explosion src = IGF.collectParameters ();
@@ -1872,7 +1893,8 @@ namespace {
1872
1893
EnumPayload payload;
1873
1894
llvm::Value *extraTag;
1874
1895
std::tie (payload, extraTag) =
1875
- getPayloadAndExtraTagFromExplosionOutlined (IGF, src);
1896
+ getPayloadAndExtraTagFromExplosionOutlined (IGF, src, &collector);
1897
+ collector.bindPolymorphicParameters (IGF, src);
1876
1898
llvm::BasicBlock *endBB =
1877
1899
testFixedEnumContainsPayload (IGF, payload, extraTag);
1878
1900
@@ -2666,8 +2688,10 @@ namespace {
2666
2688
}
2667
2689
}
2668
2690
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 {
2671
2695
assert (out.empty () && " Out explosion must be empty!" );
2672
2696
EnumPayload payload;
2673
2697
llvm::Value *extraTag;
@@ -2676,8 +2700,16 @@ namespace {
2676
2700
payload.explode (IGM, out);
2677
2701
if (extraTag)
2678
2702
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
+ }
2679
2711
}
2680
-
2712
+
2681
2713
void unpackIntoPayloadExplosion (IRGenFunction &IGF,
2682
2714
Explosion &asEnumIn,
2683
2715
Explosion &asPayloadOut) const {
@@ -2737,7 +2769,7 @@ namespace {
2737
2769
if (!copyEnumFunction)
2738
2770
copyEnumFunction = emitCopyEnumFunction (IGM, loweredType);
2739
2771
Explosion tmp;
2740
- fillExplosionForOutlinedCall (IGF, src, tmp);
2772
+ fillExplosionForOutlinedCall (IGF, src, tmp, nullptr );
2741
2773
llvm::CallInst *call = IGF.Builder .CreateCallWithoutDbgLoc (
2742
2774
copyEnumFunction->getFunctionType (), copyEnumFunction,
2743
2775
tmp.getAll ());
@@ -2806,14 +2838,7 @@ namespace {
2806
2838
IGF.Builder .emitBlock (endBB);
2807
2839
return ;
2808
2840
}
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);
2817
2842
return ;
2818
2843
}
2819
2844
@@ -3239,7 +3264,7 @@ namespace {
3239
3264
auto payloadT = getPayloadType (IGM, T);
3240
3265
getPayloadTypeInfo ().collectMetadataForOutlining (collector, payloadT);
3241
3266
}
3242
- collector.collectTypeMetadataForLayout (T);
3267
+ collector.collectTypeMetadata (T);
3243
3268
}
3244
3269
3245
3270
void storeTag (IRGenFunction &IGF,
@@ -3715,7 +3740,7 @@ namespace {
3715
3740
Explosion src = IGF.collectParameters ();
3716
3741
if (IGM.DebugInfo )
3717
3742
IGM.DebugInfo ->emitArtificialFunction (IGF, IGF.CurFn );
3718
- auto parts = destructureAndTagLoadableEnumFromOutlined (IGF, src);
3743
+ auto parts = destructureAndTagLoadableEnumFromOutlined (IGF, src, nullptr );
3719
3744
3720
3745
forNontrivialPayloads (IGF, parts.tag , [&](unsigned tagIndex,
3721
3746
EnumImplStrategy::Element elt) {
@@ -3732,21 +3757,26 @@ namespace {
3732
3757
return func;
3733
3758
}
3734
3759
3735
- llvm::Function *emitConsumeEnumFunction (IRGenModule &IGM,
3736
- SILType type) const {
3760
+ llvm::Function *
3761
+ emitConsumeEnumFunction (IRGenModule &IGM, SILType type,
3762
+ OutliningMetadataCollector &collector) const {
3737
3763
IRGenMangler Mangler;
3738
3764
auto manglingBits =
3739
3765
getTypeAndGenericSignatureForManglingOutlineFunction (type);
3740
3766
std::string name =
3741
3767
Mangler.mangleOutlinedConsumeFunction (manglingBits.first ,
3742
3768
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);
3744
3772
3745
3773
IRGenFunction IGF (IGM, func);
3746
3774
if (IGM.DebugInfo )
3747
3775
IGM.DebugInfo ->emitArtificialFunction (IGF, IGF.CurFn );
3748
3776
Explosion src = IGF.collectParameters ();
3749
- auto parts = destructureAndTagLoadableEnumFromOutlined (IGF, src);
3777
+ auto parts =
3778
+ destructureAndTagLoadableEnumFromOutlined (IGF, src, &collector);
3779
+ collector.bindPolymorphicParameters (IGF, src);
3750
3780
3751
3781
forNontrivialPayloads (IGF, parts.tag , [&](unsigned tagIndex,
3752
3782
EnumImplStrategy::Element elt) {
@@ -3801,12 +3831,15 @@ namespace {
3801
3831
bool allTriviallyDestroyable = true ;
3802
3832
bool allBitwiseTakable = true ;
3803
3833
bool allSingleRefcount = true ;
3834
+ bool allCopyable = true ;
3804
3835
bool haveRefcounting = false ;
3805
3836
for (auto &elt : ElementsWithPayload) {
3806
3837
if (!elt.ti ->isTriviallyDestroyable (ResilienceExpansion::Maximal))
3807
3838
allTriviallyDestroyable = false ;
3808
3839
if (!elt.ti ->isBitwiseTakable (ResilienceExpansion::Maximal))
3809
3840
allBitwiseTakable = false ;
3841
+ if (!elt.ti ->isCopyable (ResilienceExpansion::Maximal))
3842
+ allCopyable = false ;
3810
3843
3811
3844
// refcounting is only set in the else branches
3812
3845
ReferenceCounting refcounting;
@@ -3836,7 +3869,7 @@ namespace {
3836
3869
} else if (allSingleRefcount
3837
3870
&& ElementsWithNoPayload.size () <= 1 ) {
3838
3871
CopyDestroyKind = TaggedRefcounted;
3839
- } else if (allBitwiseTakable) {
3872
+ } else if (allBitwiseTakable && allCopyable ) {
3840
3873
CopyDestroyKind = BitwiseTakable;
3841
3874
}
3842
3875
}
@@ -4023,11 +4056,11 @@ namespace {
4023
4056
4024
4057
return {destructured.payload , destructured.extraTagBits , tag};
4025
4058
}
4026
- DestructuredAndTaggedLoadableEnum
4027
- destructureAndTagLoadableEnumFromOutlined ( IRGenFunction &IGF,
4028
- Explosion &src ) const {
4059
+ DestructuredAndTaggedLoadableEnum destructureAndTagLoadableEnumFromOutlined (
4060
+ IRGenFunction &IGF, Explosion &src ,
4061
+ OutliningMetadataCollector *collector ) const {
4029
4062
EnumPayload payload;
4030
- unsigned claimSZ = src.size ();
4063
+ unsigned claimSZ = src.size () - (collector ? collector-> size () : 0 ) ;
4031
4064
if (ExtraTagBitCount > 0 ) {
4032
4065
--claimSZ;
4033
4066
}
@@ -4697,13 +4730,23 @@ namespace {
4697
4730
payload.emitApplyAndMask (IGF, mask);
4698
4731
}
4699
4732
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 {
4702
4737
assert (out.empty () && " Out explosion must be empty!" );
4703
4738
auto parts = destructureAndTagLoadableEnum (IGF, src);
4704
4739
parts.payload .explode (IGM, out);
4705
4740
if (parts.extraTagBits )
4706
4741
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
+ }
4707
4750
}
4708
4751
4709
4752
public:
@@ -4761,7 +4804,7 @@ namespace {
4761
4804
if (!copyEnumFunction)
4762
4805
copyEnumFunction = emitCopyEnumFunction (IGM, loweredType);
4763
4806
Explosion tmp;
4764
- fillExplosionForOutlinedCall (IGF, src, tmp);
4807
+ fillExplosionForOutlinedCall (IGF, src, tmp, nullptr );
4765
4808
llvm::CallInst *call = IGF.Builder .CreateCallWithoutDbgLoc (
4766
4809
copyEnumFunction->getFunctionType (), copyEnumFunction,
4767
4810
tmp.getAll ());
@@ -4824,10 +4867,13 @@ namespace {
4824
4867
});
4825
4868
return ;
4826
4869
}
4870
+ OutliningMetadataCollector collector (T, IGF, LayoutIsNotNeeded,
4871
+ DeinitIsNeeded);
4872
+ IGF.getTypeInfo (T).collectMetadataForOutlining (collector, T);
4827
4873
if (!consumeEnumFunction)
4828
- consumeEnumFunction = emitConsumeEnumFunction (IGM, loweredType );
4874
+ consumeEnumFunction = emitConsumeEnumFunction (IGM, T, collector );
4829
4875
Explosion tmp;
4830
- fillExplosionForOutlinedCall (IGF, src, tmp);
4876
+ fillExplosionForOutlinedCall (IGF, src, tmp, &collector );
4831
4877
llvm::CallInst *call = IGF.Builder .CreateCallWithoutDbgLoc (
4832
4878
consumeEnumFunction->getFunctionType (), consumeEnumFunction,
4833
4879
tmp.claimAll ());
@@ -5134,7 +5180,7 @@ namespace {
5134
5180
auto &payloadTI = *payloadCasePair.ti ;
5135
5181
payloadTI.collectMetadataForOutlining (collector, payloadT);
5136
5182
}
5137
- collector.collectTypeMetadataForLayout (T);
5183
+ collector.collectTypeMetadata (T);
5138
5184
}
5139
5185
5140
5186
void destroy (IRGenFunction &IGF, Address addr, SILType T,
@@ -6051,7 +6097,7 @@ namespace {
6051
6097
6052
6098
void collectMetadataForOutlining (OutliningMetadataCollector &collector,
6053
6099
SILType T) const override {
6054
- collector.collectTypeMetadataForLayout (T);
6100
+ collector.collectTypeMetadata (T);
6055
6101
}
6056
6102
6057
6103
void destroy (IRGenFunction &IGF, Address addr, SILType T,
0 commit comments