@@ -3740,7 +3740,7 @@ namespace {
3740
3740
Explosion src = IGF.collectParameters ();
3741
3741
if (IGM.DebugInfo )
3742
3742
IGM.DebugInfo ->emitArtificialFunction (IGF, IGF.CurFn );
3743
- auto parts = destructureAndTagLoadableEnumFromOutlined (IGF, src);
3743
+ auto parts = destructureAndTagLoadableEnumFromOutlined (IGF, src, nullptr );
3744
3744
3745
3745
forNontrivialPayloads (IGF, parts.tag , [&](unsigned tagIndex,
3746
3746
EnumImplStrategy::Element elt) {
@@ -3757,21 +3757,26 @@ namespace {
3757
3757
return func;
3758
3758
}
3759
3759
3760
- llvm::Function *emitConsumeEnumFunction (IRGenModule &IGM,
3761
- SILType type) const {
3760
+ llvm::Function *
3761
+ emitConsumeEnumFunction (IRGenModule &IGM, SILType type,
3762
+ OutliningMetadataCollector &collector) const {
3762
3763
IRGenMangler Mangler;
3763
3764
auto manglingBits =
3764
3765
getTypeAndGenericSignatureForManglingOutlineFunction (type);
3765
3766
std::string name =
3766
3767
Mangler.mangleOutlinedConsumeFunction (manglingBits.first ,
3767
3768
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);
3769
3772
3770
3773
IRGenFunction IGF (IGM, func);
3771
3774
if (IGM.DebugInfo )
3772
3775
IGM.DebugInfo ->emitArtificialFunction (IGF, IGF.CurFn );
3773
3776
Explosion src = IGF.collectParameters ();
3774
- auto parts = destructureAndTagLoadableEnumFromOutlined (IGF, src);
3777
+ auto parts =
3778
+ destructureAndTagLoadableEnumFromOutlined (IGF, src, &collector);
3779
+ collector.bindPolymorphicParameters (IGF, src);
3775
3780
3776
3781
forNontrivialPayloads (IGF, parts.tag , [&](unsigned tagIndex,
3777
3782
EnumImplStrategy::Element elt) {
@@ -3826,12 +3831,15 @@ namespace {
3826
3831
bool allTriviallyDestroyable = true ;
3827
3832
bool allBitwiseTakable = true ;
3828
3833
bool allSingleRefcount = true ;
3834
+ bool allCopyable = true ;
3829
3835
bool haveRefcounting = false ;
3830
3836
for (auto &elt : ElementsWithPayload) {
3831
3837
if (!elt.ti ->isTriviallyDestroyable (ResilienceExpansion::Maximal))
3832
3838
allTriviallyDestroyable = false ;
3833
3839
if (!elt.ti ->isBitwiseTakable (ResilienceExpansion::Maximal))
3834
3840
allBitwiseTakable = false ;
3841
+ if (!elt.ti ->isCopyable (ResilienceExpansion::Maximal))
3842
+ allCopyable = false ;
3835
3843
3836
3844
// refcounting is only set in the else branches
3837
3845
ReferenceCounting refcounting;
@@ -3861,7 +3869,7 @@ namespace {
3861
3869
} else if (allSingleRefcount
3862
3870
&& ElementsWithNoPayload.size () <= 1 ) {
3863
3871
CopyDestroyKind = TaggedRefcounted;
3864
- } else if (allBitwiseTakable) {
3872
+ } else if (allBitwiseTakable && allCopyable ) {
3865
3873
CopyDestroyKind = BitwiseTakable;
3866
3874
}
3867
3875
}
@@ -4048,11 +4056,11 @@ namespace {
4048
4056
4049
4057
return {destructured.payload , destructured.extraTagBits , tag};
4050
4058
}
4051
- DestructuredAndTaggedLoadableEnum
4052
- destructureAndTagLoadableEnumFromOutlined ( IRGenFunction &IGF,
4053
- Explosion &src ) const {
4059
+ DestructuredAndTaggedLoadableEnum destructureAndTagLoadableEnumFromOutlined (
4060
+ IRGenFunction &IGF, Explosion &src ,
4061
+ OutliningMetadataCollector *collector ) const {
4054
4062
EnumPayload payload;
4055
- unsigned claimSZ = src.size ();
4063
+ unsigned claimSZ = src.size () - (collector ? collector-> size () : 0 ) ;
4056
4064
if (ExtraTagBitCount > 0 ) {
4057
4065
--claimSZ;
4058
4066
}
@@ -4722,13 +4730,23 @@ namespace {
4722
4730
payload.emitApplyAndMask (IGF, mask);
4723
4731
}
4724
4732
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 {
4727
4737
assert (out.empty () && " Out explosion must be empty!" );
4728
4738
auto parts = destructureAndTagLoadableEnum (IGF, src);
4729
4739
parts.payload .explode (IGM, out);
4730
4740
if (parts.extraTagBits )
4731
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
+ }
4732
4750
}
4733
4751
4734
4752
public:
@@ -4786,7 +4804,7 @@ namespace {
4786
4804
if (!copyEnumFunction)
4787
4805
copyEnumFunction = emitCopyEnumFunction (IGM, loweredType);
4788
4806
Explosion tmp;
4789
- fillExplosionForOutlinedCall (IGF, src, tmp);
4807
+ fillExplosionForOutlinedCall (IGF, src, tmp, nullptr );
4790
4808
llvm::CallInst *call = IGF.Builder .CreateCallWithoutDbgLoc (
4791
4809
copyEnumFunction->getFunctionType (), copyEnumFunction,
4792
4810
tmp.getAll ());
@@ -4849,10 +4867,13 @@ namespace {
4849
4867
});
4850
4868
return ;
4851
4869
}
4870
+ OutliningMetadataCollector collector (T, IGF, LayoutIsNotNeeded,
4871
+ DeinitIsNeeded);
4872
+ IGF.getTypeInfo (T).collectMetadataForOutlining (collector, T);
4852
4873
if (!consumeEnumFunction)
4853
- consumeEnumFunction = emitConsumeEnumFunction (IGM, loweredType );
4874
+ consumeEnumFunction = emitConsumeEnumFunction (IGM, T, collector );
4854
4875
Explosion tmp;
4855
- fillExplosionForOutlinedCall (IGF, src, tmp);
4876
+ fillExplosionForOutlinedCall (IGF, src, tmp, &collector );
4856
4877
llvm::CallInst *call = IGF.Builder .CreateCallWithoutDbgLoc (
4857
4878
consumeEnumFunction->getFunctionType (), consumeEnumFunction,
4858
4879
tmp.claimAll ());
0 commit comments