@@ -2872,23 +2872,101 @@ static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
2872
2872
IGF.Builder .CreateLifetimeEnd (fields, IGM.getPointerSize () * numFields);
2873
2873
}
2874
2874
2875
+ static void emitInitializeFieldOffsetVectorWithLayoutString (
2876
+ IRGenFunction &IGF, SILType T, llvm::Value *metadata, bool isVWTMutable,
2877
+ MetadataDependencyCollector *collector) {
2878
+ auto &IGM = IGF.IGM ;
2879
+ assert (IGM.Context .LangOpts .hasFeature (
2880
+ Feature::LayoutStringValueWitnessesInstantiation));
2881
+
2882
+ auto *target = T.getStructOrBoundGenericStruct ();
2883
+
2884
+ llvm::Value *fieldVector =
2885
+ emitAddressOfFieldOffsetVector (IGF, metadata, target).getAddress ();
2886
+
2887
+ // Collect the stored properties of the type.
2888
+ unsigned numFields = getNumFields (target);
2889
+
2890
+ // Ask the runtime to lay out the struct or class.
2891
+ auto numFieldsV = IGM.getSize (Size (numFields));
2892
+
2893
+ // Fill out an array with the field type metadata records.
2894
+ Address fieldsMetadata =
2895
+ IGF.createAlloca (llvm::ArrayType::get (IGM.TypeMetadataPtrTy , numFields),
2896
+ IGM.getPointerAlignment (), " fieldsMetadata" );
2897
+ IGF.Builder .CreateLifetimeStart (fieldsMetadata,
2898
+ IGM.getPointerSize () * numFields);
2899
+ fieldsMetadata = IGF.Builder .CreateStructGEP (fieldsMetadata, 0 , Size (0 ));
2900
+
2901
+ unsigned index = 0 ;
2902
+ forEachField (IGM, target, [&](Field field) {
2903
+ assert (field.isConcrete () &&
2904
+ " initializing offset vector for type with missing member?" );
2905
+ SILType propTy = field.getType (IGM, T);
2906
+ llvm::Value *fieldMetatype;
2907
+ if (auto ownership = propTy.getReferenceStorageOwnership ()) {
2908
+ switch (*ownership) {
2909
+ case ReferenceOwnership::Weak:
2910
+ fieldMetatype = llvm::Constant::getIntegerValue (
2911
+ IGM.TypeMetadataPtrTy , APInt (IGM.IntPtrTy ->getBitWidth (), 0x7 ));
2912
+ break ;
2913
+ case ReferenceOwnership::Strong:
2914
+ case ReferenceOwnership::Unowned:
2915
+ case ReferenceOwnership::Unmanaged:
2916
+ llvm_unreachable (" Unmanaged reference should have been lowered" );
2917
+ }
2918
+ } else {
2919
+ auto request = DynamicMetadataRequest::getNonBlocking (
2920
+ MetadataState::LayoutComplete, collector);
2921
+ fieldMetatype = IGF.emitTypeMetadataRefForLayout (propTy, request);
2922
+ }
2923
+
2924
+ Address fieldMetatypeAddr = IGF.Builder .CreateConstArrayGEP (
2925
+ fieldsMetadata, index, IGM.getPointerSize ());
2926
+ IGF.Builder .CreateStore (fieldMetatype, fieldMetatypeAddr);
2927
+ ++index;
2928
+ });
2929
+ assert (index == numFields);
2930
+
2931
+ // Compute struct layout flags.
2932
+ StructLayoutFlags flags = StructLayoutFlags::Swift5Algorithm;
2933
+ if (isVWTMutable)
2934
+ flags |= StructLayoutFlags::IsVWTMutable;
2935
+
2936
+ // Call swift_initStructMetadataWithLayoutString().
2937
+ IGF.Builder .CreateCall (
2938
+ IGM.getInitStructMetadataWithLayoutStringFunctionPointer (),
2939
+ {metadata, IGM.getSize (Size (uintptr_t (flags))), numFieldsV,
2940
+ fieldsMetadata.getAddress (), fieldVector});
2941
+
2942
+ IGF.Builder .CreateLifetimeEnd (fieldsMetadata,
2943
+ IGM.getPointerSize () * numFields);
2944
+ }
2945
+
2875
2946
static void emitInitializeValueMetadata (IRGenFunction &IGF,
2876
2947
NominalTypeDecl *nominalDecl,
2877
2948
llvm::Value *metadata,
2878
2949
bool isVWTMutable,
2879
2950
MetadataDependencyCollector *collector) {
2880
- auto loweredTy =
2881
- IGF. IGM .getLoweredType (nominalDecl->getDeclaredTypeInContext ());
2951
+ auto &IGM = IGF. IGM ;
2952
+ auto loweredTy = IGM.getLoweredType (nominalDecl->getDeclaredTypeInContext ());
2882
2953
2883
2954
if (isa<StructDecl>(nominalDecl)) {
2884
- auto &fixedTI = IGF. IGM .getTypeInfo (loweredTy);
2955
+ auto &fixedTI = IGM.getTypeInfo (loweredTy);
2885
2956
if (isa<FixedTypeInfo>(fixedTI)) return ;
2886
2957
2887
- emitInitializeFieldOffsetVector (IGF, loweredTy, metadata, isVWTMutable,
2888
- collector);
2958
+ if (IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses) &&
2959
+ IGM.Context .LangOpts .hasFeature (
2960
+ Feature::LayoutStringValueWitnessesInstantiation)) {
2961
+ emitInitializeFieldOffsetVectorWithLayoutString (IGF, loweredTy, metadata,
2962
+ isVWTMutable, collector);
2963
+ } else {
2964
+ emitInitializeFieldOffsetVector (IGF, loweredTy, metadata, isVWTMutable,
2965
+ collector);
2966
+ }
2889
2967
} else {
2890
2968
assert (isa<EnumDecl>(nominalDecl));
2891
- auto &strategy = getEnumImplStrategy (IGF. IGM , loweredTy);
2969
+ auto &strategy = getEnumImplStrategy (IGM, loweredTy);
2892
2970
strategy.initializeMetadata (IGF, metadata, isVWTMutable, loweredTy,
2893
2971
collector);
2894
2972
}
@@ -2996,11 +3074,15 @@ namespace {
2996
3074
llvm::Constant *emitLayoutString () {
2997
3075
if (!IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses))
2998
3076
return nullptr ;
2999
- auto lowered = getLoweredType ();
3000
- auto &typeLayoutEntry = IGM.getTypeLayoutEntry (lowered, /* useStructLayouts*/ true );
3077
+ auto lowered = getLoweredTypeInPrimaryContext (
3078
+ IGM, Target->getDeclaredType ()->getCanonicalType ());
3079
+ auto &ti = IGM.getTypeInfo (lowered);
3080
+ auto *typeLayoutEntry =
3081
+ ti.buildTypeLayoutEntry (IGM, lowered, /* useStructLayouts*/ true );
3001
3082
auto genericSig =
3002
3083
lowered.getNominalOrBoundGenericNominal ()->getGenericSignature ();
3003
- return typeLayoutEntry.layoutString (IGM, genericSig);
3084
+
3085
+ return typeLayoutEntry->layoutString (IGM, genericSig);
3004
3086
}
3005
3087
3006
3088
llvm::Constant *getLayoutString () {
@@ -3072,12 +3154,11 @@ namespace {
3072
3154
if (HasDependentMetadata)
3073
3155
asImpl ().emitInitializeMetadata (IGF, metadata, false , collector);
3074
3156
3075
-
3076
- if (!IGM. Context . LangOpts . hasFeature ( Feature::LayoutStringValueWitnesses)) {
3157
+ if (IGM. Context . LangOpts . hasFeature (
3158
+ Feature::LayoutStringValueWitnesses)) {
3077
3159
if (auto *layoutString = getLayoutString ()) {
3078
3160
auto layoutStringCast = IGF.Builder .CreateBitCast (layoutString,
3079
3161
IGM.Int8PtrTy );
3080
-
3081
3162
IGF.Builder .CreateCall (
3082
3163
IGM.getGenericInstantiateLayoutStringFunctionPointer (),
3083
3164
{layoutStringCast, metadata});
@@ -3650,11 +3731,15 @@ namespace {
3650
3731
llvm::Constant *emitLayoutString () {
3651
3732
if (!IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses))
3652
3733
return nullptr ;
3653
- auto lowered = getLoweredType ();
3654
- auto &typeLayoutEntry = IGM.getTypeLayoutEntry (lowered, /* useStructLayouts*/ true );
3734
+ auto lowered = getLoweredTypeInPrimaryContext (
3735
+ IGM, Target->getDeclaredType ()->getCanonicalType ());
3736
+ auto &ti = IGM.getTypeInfo (lowered);
3737
+ auto *typeLayoutEntry =
3738
+ ti.buildTypeLayoutEntry (IGM, lowered, /* useStructLayouts*/ true );
3655
3739
auto genericSig =
3656
3740
lowered.getNominalOrBoundGenericNominal ()->getGenericSignature ();
3657
- return typeLayoutEntry.layoutString (IGM, genericSig);
3741
+
3742
+ return typeLayoutEntry->layoutString (IGM, genericSig);
3658
3743
}
3659
3744
3660
3745
llvm::Constant *getLayoutString () {
@@ -4843,11 +4928,22 @@ namespace {
4843
4928
B.addInt (IGM.MetadataKindTy , unsigned (getMetadataKind (Target)));
4844
4929
}
4845
4930
4931
+ bool hasLayoutString () {
4932
+ if (!IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses)) {
4933
+ return false ;
4934
+ }
4935
+
4936
+ if (IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnessesInstantiation)) {
4937
+ return !!getLayoutString () || needsSingletonMetadataInitialization (IGM, Target);
4938
+ }
4939
+
4940
+ return !!getLayoutString ();
4941
+ }
4942
+
4846
4943
llvm::Constant *emitNominalTypeDescriptor () {
4847
- auto hasLayoutString = !!getLayoutString ();
4848
4944
auto descriptor =
4849
4945
StructContextDescriptorBuilder (IGM, Target, RequireMetadata,
4850
- hasLayoutString).emit ();
4946
+ hasLayoutString () ).emit ();
4851
4947
return descriptor;
4852
4948
}
4853
4949
@@ -4878,11 +4974,15 @@ namespace {
4878
4974
llvm::Constant *emitLayoutString () {
4879
4975
if (!IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses))
4880
4976
return nullptr ;
4881
- auto lowered = getLoweredType ();
4882
- auto &typeLayoutEntry = IGM.getTypeLayoutEntry (lowered, /* useStructLayouts*/ true );
4977
+ auto lowered = getLoweredTypeInPrimaryContext (
4978
+ IGM, Target->getDeclaredType ()->getCanonicalType ());
4979
+ auto &ti = IGM.getTypeInfo (lowered);
4980
+ auto *typeLayoutEntry =
4981
+ ti.buildTypeLayoutEntry (IGM, lowered, /* useStructLayouts*/ true );
4883
4982
auto genericSig =
4884
4983
lowered.getNominalOrBoundGenericNominal ()->getGenericSignature ();
4885
- return typeLayoutEntry.layoutString (IGM, genericSig);
4984
+
4985
+ return typeLayoutEntry->layoutString (IGM, genericSig);
4886
4986
}
4887
4987
4888
4988
llvm::Constant *getLayoutString () {
@@ -5021,9 +5121,22 @@ namespace {
5021
5121
// We just assume this might happen.
5022
5122
}
5023
5123
5124
+ bool hasLayoutString () {
5125
+ if (!IGM.Context .LangOpts .hasFeature (
5126
+ Feature::LayoutStringValueWitnesses)) {
5127
+ return false ;
5128
+ }
5129
+ return !!getLayoutString () ||
5130
+ IGM.Context .LangOpts .hasFeature (
5131
+ Feature::LayoutStringValueWitnessesInstantiation);
5132
+ }
5133
+
5024
5134
llvm::Constant *emitNominalTypeDescriptor () {
5025
- return StructContextDescriptorBuilder (IGM, Target, RequireMetadata,
5026
- /* hasLayoutString*/ false ).emit ();
5135
+
5136
+ return StructContextDescriptorBuilder (
5137
+ IGM, Target, RequireMetadata,
5138
+ /* hasLayoutString*/ hasLayoutString ())
5139
+ .emit ();
5027
5140
}
5028
5141
5029
5142
GenericMetadataPatternFlags getPatternFlags () {
@@ -5122,8 +5235,8 @@ namespace {
5122
5235
bool hasCompletionFunction () {
5123
5236
// TODO: Once we store layout string pointers on the metadata pattern, we
5124
5237
// don't have to emit completion functions for all generic types anymore.
5125
- return IGM.Context . LangOpts . hasFeature (Feature::LayoutStringValueWitnesses ) ||
5126
- !isa<FixedTypeInfo>(IGM. getTypeInfo ( getLoweredType ()) );
5238
+ return !isa<FixedTypeInfo>( IGM.getTypeInfo ( getLoweredType ()) ) ||
5239
+ !! getLayoutString ( );
5127
5240
}
5128
5241
};
5129
5242
@@ -5275,11 +5388,15 @@ namespace {
5275
5388
llvm::Constant *emitLayoutString () {
5276
5389
if (!IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses))
5277
5390
return nullptr ;
5278
- auto lowered = getLoweredType ();
5279
- auto &typeLayoutEntry = IGM.getTypeLayoutEntry (lowered, /* useStructLayouts*/ true );
5391
+ auto lowered = getLoweredTypeInPrimaryContext (
5392
+ IGM, Target->getDeclaredType ()->getCanonicalType ());
5393
+ auto &ti = IGM.getTypeInfo (lowered);
5394
+ auto *typeLayoutEntry =
5395
+ ti.buildTypeLayoutEntry (IGM, lowered, /* useStructLayouts*/ true );
5280
5396
auto genericSig =
5281
5397
lowered.getNominalOrBoundGenericNominal ()->getGenericSignature ();
5282
- return typeLayoutEntry.layoutString (IGM, genericSig);
5398
+
5399
+ return typeLayoutEntry->layoutString (IGM, genericSig);
5283
5400
}
5284
5401
5285
5402
llvm::Constant *getLayoutString () {
@@ -5496,8 +5613,9 @@ namespace {
5496
5613
}
5497
5614
5498
5615
llvm::Constant *emitNominalTypeDescriptor () {
5499
- return EnumContextDescriptorBuilder (IGM, Target, RequireMetadata,
5500
- /* hasLayoutString*/ false )
5616
+ return EnumContextDescriptorBuilder (
5617
+ IGM, Target, RequireMetadata,
5618
+ /* hasLayoutString*/ !!getLayoutString ())
5501
5619
.emit ();
5502
5620
}
5503
5621
@@ -5518,7 +5636,8 @@ namespace {
5518
5636
}
5519
5637
5520
5638
bool hasCompletionFunction () {
5521
- return !isa<FixedTypeInfo>(IGM.getTypeInfo (getLoweredType ()));
5639
+ return !isa<FixedTypeInfo>(IGM.getTypeInfo (getLoweredType ())) ||
5640
+ !!getLayoutString ();
5522
5641
}
5523
5642
};
5524
5643
0 commit comments