@@ -1361,7 +1361,9 @@ deleteAndReenqueueForEmissionValuesDependentOnCanonicalPrespecializedMetadataRec
13611361void IRGenerator::emitLazyDefinitions () {
13621362 if (SIL.getASTContext ().LangOpts .hasFeature (Feature::Embedded)) {
13631363 // In embedded Swift, the compiler cannot emit any metadata, etc.
1364- assert (LazyTypeMetadata.empty ());
1364+ // Other than to support existentials.
1365+ assert (LazyTypeMetadata.empty () ||
1366+ SIL.getASTContext ().LangOpts .hasFeature (Feature::EmbeddedExistentials));
13651367 assert (LazySpecializedTypeMetadataRecords.empty ());
13661368 assert (LazyTypeContextDescriptors.empty ());
13671369 assert (LazyOpaqueTypeDescriptors.empty ());
@@ -1388,7 +1390,8 @@ void IRGenerator::emitLazyDefinitions() {
13881390 !LazyCanonicalSpecializedMetadataAccessors.empty () ||
13891391 !LazyMetadataAccessors.empty () ||
13901392 !LazyClassMetadata.empty () ||
1391- !LazySpecializedClassMetadata.empty ()
1393+ !LazySpecializedClassMetadata.empty () ||
1394+ !LazySpecializedValueMetadata.empty ()
13921395 ) {
13931396 // Emit any lazy type metadata we require.
13941397 while (!LazyTypeMetadata.empty ()) {
@@ -1514,6 +1517,12 @@ void IRGenerator::emitLazyDefinitions() {
15141517 CurrentIGMPtr IGM = getGenModule (classType->getClassOrBoundGenericClass ());
15151518 emitLazySpecializedClassMetadata (*IGM.get (), classType);
15161519 }
1520+
1521+ while (!LazySpecializedValueMetadata.empty ()) {
1522+ CanType valueType = LazySpecializedValueMetadata.pop_back_val ();
1523+ CurrentIGMPtr IGM = getGenModule (valueType->getNominalOrBoundGenericNominal ());
1524+ emitLazySpecializedValueMetadata (*IGM.get (), valueType);
1525+ }
15171526 }
15181527
15191528 FinishedEmittingLazyDefinitions = true ;
@@ -1580,6 +1589,14 @@ bool IRGenerator::hasLazyMetadata(TypeDecl *type) {
15801589 if (found != HasLazyMetadata.end ())
15811590 return found->second ;
15821591
1592+ if (SIL.getASTContext ().LangOpts .hasFeature (Feature::EmbeddedExistentials) &&
1593+ (isa<StructDecl>(type) || isa<EnumDecl>(type))) {
1594+ bool isGeneric = cast<NominalTypeDecl>(type)->isGenericContext ();
1595+ HasLazyMetadata[type] = !isGeneric;
1596+
1597+ return !isGeneric;
1598+ }
1599+
15831600 auto canBeLazy = [&]() -> bool {
15841601 auto *dc = type->getDeclContext ();
15851602 if (isa<ClangModuleUnit>(dc->getModuleScopeContext ())) {
@@ -1628,11 +1645,17 @@ void IRGenerator::noteUseOfClassMetadata(CanType classType) {
16281645}
16291646
16301647void IRGenerator::noteUseOfSpecializedClassMetadata (CanType classType) {
1631- if (LazilyEmittedSpecializedClassMetadata .insert (classType.getPointer ()).second ) {
1648+ if (LazilyEmittedSpecializedMetadata .insert (classType.getPointer ()).second ) {
16321649 LazySpecializedClassMetadata.push_back (classType);
16331650 }
16341651}
16351652
1653+ void IRGenerator::noteUseOfSpecializedValueMetadata (CanType valueType) {
1654+ if (LazilyEmittedSpecializedMetadata.insert (valueType.getPointer ()).second ) {
1655+ LazySpecializedValueMetadata.push_back (valueType);
1656+ }
1657+ }
1658+
16361659void IRGenerator::noteUseOfTypeGlobals (NominalTypeDecl *type,
16371660 bool isUseOfMetadata,
16381661 RequireMetadata_t requireMetadata) {
@@ -5298,6 +5321,9 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(
52985321 if (Context.LangOpts .hasFeature (Feature::Embedded)) {
52995322 entity = LinkEntity::forTypeMetadata (concreteType,
53005323 TypeMetadataAddress::AddressPoint);
5324+ if (Context.LangOpts .hasFeature (Feature::EmbeddedExistentials))
5325+ entity = LinkEntity::forTypeMetadata (concreteType,
5326+ TypeMetadataAddress::FullMetadata);
53015327 }
53025328
53035329 auto DbgTy = DebugTypeInfo::getGlobalMetadata (MetatypeType::get (concreteType),
@@ -5320,7 +5346,8 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(
53205346 LinkInfo link = LinkInfo::get (*this , entity, ForDefinition);
53215347 markGlobalAsUsedBasedOnLinkage (*this , link, var);
53225348
5323- if (Context.LangOpts .hasFeature (Feature::Embedded)) {
5349+ if (Context.LangOpts .hasFeature (Feature::Embedded) &&
5350+ !Context.LangOpts .hasFeature (Feature::EmbeddedExistentials)) {
53245351 return var;
53255352 }
53265353
@@ -5331,12 +5358,15 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(
53315358 if (auto nominal = concreteType->getAnyNominal ()) {
53325359 // Keep type metadata around for all types (except @_objcImplementation,
53335360 // since we're using ObjC metadata for that).
5334- if (!isObjCImpl)
5361+ if (!isObjCImpl &&
5362+ !Context.LangOpts .hasFeature (Feature::EmbeddedExistentials))
53355363 addRuntimeResolvableType (nominal);
53365364
53375365 // Don't define the alias for foreign type metadata, prespecialized
53385366 // generic metadata, or @_objcImplementation classes, since they're not ABI.
5339- if (requiresForeignTypeMetadata (nominal) || isPrespecialized || isObjCImpl)
5367+ if (requiresForeignTypeMetadata (nominal) ||
5368+ (isPrespecialized && !Context.LangOpts .hasFeature (Feature::EmbeddedExistentials)) ||
5369+ isObjCImpl)
53405370 return var;
53415371
53425372 // Native Swift class metadata has a destructor before the address point.
@@ -5349,6 +5379,10 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(
53495379 }
53505380 }
53515381
5382+ if (Context.LangOpts .hasFeature (Feature::EmbeddedExistentials)) {
5383+ adjustmentIndex = MetadataAdjustmentIndex::EmbeddedWithExistentials;
5384+ }
5385+
53525386 llvm::Constant *indices[] = {
53535387 llvm::ConstantInt::get (Int32Ty, 0 ),
53545388 llvm::ConstantInt::get (Int32Ty, adjustmentIndex)};
@@ -5390,7 +5424,10 @@ IRGenModule::getAddrOfTypeMetadata(CanType concreteType,
53905424
53915425 llvm::Type *defaultVarTy;
53925426 unsigned adjustmentIndex;
5393- if (concreteType->isAny () || concreteType->isAnyObject () || concreteType->isVoid () || concreteType->is <TupleType>() || concreteType->is <BuiltinType>()) {
5427+ if (Context.LangOpts .hasFeature (Feature::EmbeddedExistentials)) {
5428+ adjustmentIndex = 0 ;
5429+ defaultVarTy = EmbeddedExistentialsMetadataStructTy;
5430+ } else if (concreteType->isAny () || concreteType->isAnyObject () || concreteType->isVoid () || concreteType->is <TupleType>() || concreteType->is <BuiltinType>()) {
53945431 defaultVarTy = FullExistentialTypeMetadataStructTy;
53955432 adjustmentIndex = MetadataAdjustmentIndex::NoTypeLayoutString;
53965433 } else if (fullMetadata) {
@@ -5433,6 +5470,18 @@ IRGenModule::getAddrOfTypeMetadata(CanType concreteType,
54335470 }
54345471 }
54355472 }
5473+
5474+ if (Context.LangOpts .hasFeature (Feature::EmbeddedExistentials)) {
5475+ if ((isa<StructDecl>(nominal) || isa<EnumDecl>(nominal)) &&
5476+ nominal->isGenericContext ()) {
5477+ IRGen.noteUseOfSpecializedValueMetadata (concreteType);
5478+ }
5479+ }
5480+ }
5481+
5482+ if (Context.LangOpts .hasFeature (Feature::EmbeddedExistentials) &&
5483+ isa<TupleType>(concreteType)) {
5484+ IRGen.noteUseOfSpecializedValueMetadata (concreteType);
54365485 }
54375486
54385487 if (shouldPrespecializeGenericMetadata ()) {
0 commit comments