@@ -2872,23 +2872,101 @@ static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
28722872 IGF.Builder .CreateLifetimeEnd (fields, IGM.getPointerSize () * numFields);
28732873}
28742874
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+
28752946static void emitInitializeValueMetadata (IRGenFunction &IGF,
28762947 NominalTypeDecl *nominalDecl,
28772948 llvm::Value *metadata,
28782949 bool isVWTMutable,
28792950 MetadataDependencyCollector *collector) {
2880- auto loweredTy =
2881- IGF. IGM .getLoweredType (nominalDecl->getDeclaredTypeInContext ());
2951+ auto &IGM = IGF. IGM ;
2952+ auto loweredTy = IGM.getLoweredType (nominalDecl->getDeclaredTypeInContext ());
28822953
28832954 if (isa<StructDecl>(nominalDecl)) {
2884- auto &fixedTI = IGF. IGM .getTypeInfo (loweredTy);
2955+ auto &fixedTI = IGM.getTypeInfo (loweredTy);
28852956 if (isa<FixedTypeInfo>(fixedTI)) return ;
28862957
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+ }
28892967 } else {
28902968 assert (isa<EnumDecl>(nominalDecl));
2891- auto &strategy = getEnumImplStrategy (IGF. IGM , loweredTy);
2969+ auto &strategy = getEnumImplStrategy (IGM, loweredTy);
28922970 strategy.initializeMetadata (IGF, metadata, isVWTMutable, loweredTy,
28932971 collector);
28942972 }
@@ -2996,11 +3074,15 @@ namespace {
29963074 llvm::Constant *emitLayoutString () {
29973075 if (!IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses))
29983076 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 );
30013082 auto genericSig =
30023083 lowered.getNominalOrBoundGenericNominal ()->getGenericSignature ();
3003- return typeLayoutEntry.layoutString (IGM, genericSig);
3084+
3085+ return typeLayoutEntry->layoutString (IGM, genericSig);
30043086 }
30053087
30063088 llvm::Constant *getLayoutString () {
@@ -3072,12 +3154,11 @@ namespace {
30723154 if (HasDependentMetadata)
30733155 asImpl ().emitInitializeMetadata (IGF, metadata, false , collector);
30743156
3075-
3076- if (!IGM. Context . LangOpts . hasFeature ( Feature::LayoutStringValueWitnesses)) {
3157+ if (IGM. Context . LangOpts . hasFeature (
3158+ Feature::LayoutStringValueWitnesses)) {
30773159 if (auto *layoutString = getLayoutString ()) {
30783160 auto layoutStringCast = IGF.Builder .CreateBitCast (layoutString,
30793161 IGM.Int8PtrTy );
3080-
30813162 IGF.Builder .CreateCall (
30823163 IGM.getGenericInstantiateLayoutStringFunctionPointer (),
30833164 {layoutStringCast, metadata});
@@ -3650,11 +3731,15 @@ namespace {
36503731 llvm::Constant *emitLayoutString () {
36513732 if (!IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses))
36523733 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 );
36553739 auto genericSig =
36563740 lowered.getNominalOrBoundGenericNominal ()->getGenericSignature ();
3657- return typeLayoutEntry.layoutString (IGM, genericSig);
3741+
3742+ return typeLayoutEntry->layoutString (IGM, genericSig);
36583743 }
36593744
36603745 llvm::Constant *getLayoutString () {
@@ -4843,11 +4928,22 @@ namespace {
48434928 B.addInt (IGM.MetadataKindTy , unsigned (getMetadataKind (Target)));
48444929 }
48454930
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+
48464943 llvm::Constant *emitNominalTypeDescriptor () {
4847- auto hasLayoutString = !!getLayoutString ();
48484944 auto descriptor =
48494945 StructContextDescriptorBuilder (IGM, Target, RequireMetadata,
4850- hasLayoutString).emit ();
4946+ hasLayoutString () ).emit ();
48514947 return descriptor;
48524948 }
48534949
@@ -4878,11 +4974,15 @@ namespace {
48784974 llvm::Constant *emitLayoutString () {
48794975 if (!IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses))
48804976 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 );
48834982 auto genericSig =
48844983 lowered.getNominalOrBoundGenericNominal ()->getGenericSignature ();
4885- return typeLayoutEntry.layoutString (IGM, genericSig);
4984+
4985+ return typeLayoutEntry->layoutString (IGM, genericSig);
48864986 }
48874987
48884988 llvm::Constant *getLayoutString () {
@@ -5021,9 +5121,22 @@ namespace {
50215121 // We just assume this might happen.
50225122 }
50235123
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+
50245134 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 ();
50275140 }
50285141
50295142 GenericMetadataPatternFlags getPatternFlags () {
@@ -5122,8 +5235,8 @@ namespace {
51225235 bool hasCompletionFunction () {
51235236 // TODO: Once we store layout string pointers on the metadata pattern, we
51245237 // 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 ( );
51275240 }
51285241 };
51295242
@@ -5275,11 +5388,15 @@ namespace {
52755388 llvm::Constant *emitLayoutString () {
52765389 if (!IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses))
52775390 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 );
52805396 auto genericSig =
52815397 lowered.getNominalOrBoundGenericNominal ()->getGenericSignature ();
5282- return typeLayoutEntry.layoutString (IGM, genericSig);
5398+
5399+ return typeLayoutEntry->layoutString (IGM, genericSig);
52835400 }
52845401
52855402 llvm::Constant *getLayoutString () {
@@ -5496,8 +5613,9 @@ namespace {
54965613 }
54975614
54985615 llvm::Constant *emitNominalTypeDescriptor () {
5499- return EnumContextDescriptorBuilder (IGM, Target, RequireMetadata,
5500- /* hasLayoutString*/ false )
5616+ return EnumContextDescriptorBuilder (
5617+ IGM, Target, RequireMetadata,
5618+ /* hasLayoutString*/ !!getLayoutString ())
55015619 .emit ();
55025620 }
55035621
@@ -5518,7 +5636,8 @@ namespace {
55185636 }
55195637
55205638 bool hasCompletionFunction () {
5521- return !isa<FixedTypeInfo>(IGM.getTypeInfo (getLoweredType ()));
5639+ return !isa<FixedTypeInfo>(IGM.getTypeInfo (getLoweredType ())) ||
5640+ !!getLayoutString ();
55225641 }
55235642 };
55245643
0 commit comments