@@ -1426,7 +1426,22 @@ void IRGenerator::noteUseOfCanonicalSpecializedMetadataAccessor(
14261426 }
14271427}
14281428
1429+ static bool typeKindCanBePrespecialized (TypeKind theKind) {
1430+ switch (theKind) {
1431+ case TypeKind::Struct:
1432+ case TypeKind::BoundGenericStruct:
1433+ case TypeKind::Enum:
1434+ case TypeKind::BoundGenericEnum:
1435+ case TypeKind::Class:
1436+ case TypeKind::BoundGenericClass:
1437+ return true ;
1438+ default :
1439+ return false ;
1440+ }
1441+ }
1442+
14291443void IRGenerator::noteUseOfSpecializedGenericTypeMetadata (CanType type) {
1444+ assert (typeKindCanBePrespecialized (type->getKind ()));
14301445 auto key = type->getAnyNominal ();
14311446 assert (key);
14321447 assert (key->isGenericContext ());
@@ -3736,6 +3751,22 @@ IRGenModule::getAddrOfTypeMetadataLazyCacheVariable(CanType type) {
37363751 return variable;
37373752}
37383753
3754+ llvm::Constant *
3755+ IRGenModule::getAddrOfNoncanonicalSpecializedGenericTypeMetadataCacheVariable (CanType type) {
3756+ assert (!type->hasArchetype () && !type->hasTypeParameter ());
3757+ LinkEntity entity = LinkEntity::forNoncanonicalSpecializedGenericTypeMetadataCacheVariable (type);
3758+ if (auto &entry = GlobalVars[entity]) {
3759+ return entry;
3760+ }
3761+ auto variable =
3762+ getAddrOfLLVMVariable (entity, ForDefinition, DebugTypeInfo ());
3763+
3764+ cast<llvm::GlobalVariable>(variable)->setInitializer (
3765+ llvm::ConstantPointerNull::get (TypeMetadataPtrTy));
3766+
3767+ return variable;
3768+ }
3769+
37393770// / Get or create a type metadata cache variable. These are an
37403771// / implementation detail of type metadata access functions.
37413772llvm::Constant *
@@ -3817,6 +3848,9 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
38173848 llvm::StringRef section) {
38183849 assert (init);
38193850
3851+ auto isPrespecialized = concreteType->getAnyGeneric () &&
3852+ concreteType->getAnyGeneric ()->isGenericContext ();
3853+
38203854 if (isPattern) {
38213855 assert (isConstant && " Type metadata patterns must be constant" );
38223856 auto addr = getAddrOfTypeMetadataPattern (concreteType->getAnyNominal (),
@@ -3844,7 +3878,13 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
38443878 adjustmentIndex = MetadataAdjustmentIndex::ValueType;
38453879 }
38463880
3847- auto entity = LinkEntity::forTypeMetadata (concreteType, addrKind);
3881+ auto entity =
3882+ (isPrespecialized &&
3883+ !irgen::isCanonicalInitializableTypeMetadataStaticallyAddressable (
3884+ *this , concreteType))
3885+ ? LinkEntity::forNoncanonicalSpecializedGenericTypeMetadata (
3886+ concreteType)
3887+ : LinkEntity::forTypeMetadata (concreteType, addrKind);
38483888
38493889 auto DbgTy = DebugTypeInfo::getMetadata (MetatypeType::get (concreteType),
38503890 entity.getDefaultDeclarationType (*this )->getPointerTo (),
@@ -3868,9 +3908,7 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
38683908
38693909 // Don't define the alias for foreign type metadata or prespecialized generic
38703910 // metadata, since neither is ABI.
3871- if ((nominal && requiresForeignTypeMetadata (nominal)) ||
3872- (concreteType->getAnyGeneric () &&
3873- concreteType->getAnyGeneric ()->isGenericContext ()))
3911+ if ((nominal && requiresForeignTypeMetadata (nominal)) || isPrespecialized)
38743912 return var;
38753913
38763914 // For concrete metadata, declare the alias to its address point.
@@ -3892,13 +3930,18 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
38923930}
38933931
38943932// / Fetch the declaration of the (possibly uninitialized) metadata for a type.
3895- llvm::Constant *IRGenModule::getAddrOfTypeMetadata (CanType concreteType) {
3896- return getAddrOfTypeMetadata (concreteType,
3897- SymbolReferenceKind::Absolute).getDirectValue ();
3933+ llvm::Constant *
3934+ IRGenModule::getAddrOfTypeMetadata (CanType concreteType,
3935+ TypeMetadataCanonicality canonicality) {
3936+ return getAddrOfTypeMetadata (concreteType, SymbolReferenceKind::Absolute,
3937+ canonicality)
3938+ .getDirectValue ();
38983939}
38993940
3900- ConstantReference IRGenModule::getAddrOfTypeMetadata (CanType concreteType,
3901- SymbolReferenceKind refKind) {
3941+ ConstantReference
3942+ IRGenModule::getAddrOfTypeMetadata (CanType concreteType,
3943+ SymbolReferenceKind refKind,
3944+ TypeMetadataCanonicality canonicality) {
39023945 assert (!isa<UnboundGenericType>(concreteType));
39033946
39043947 auto nominal = concreteType->getAnyNominal ();
@@ -3952,12 +3995,20 @@ ConstantReference IRGenModule::getAddrOfTypeMetadata(CanType concreteType,
39523995 Optional<LinkEntity> entity;
39533996 DebugTypeInfo DbgTy;
39543997
3955- if (fullMetadata) {
3956- entity = LinkEntity::forTypeMetadata (concreteType,
3957- TypeMetadataAddress::FullMetadata);
3958- } else {
3959- entity = LinkEntity::forTypeMetadata (concreteType,
3960- TypeMetadataAddress::AddressPoint);
3998+ switch (canonicality) {
3999+ case TypeMetadataCanonicality::Canonical:
4000+ if (fullMetadata) {
4001+ entity = LinkEntity::forTypeMetadata (concreteType,
4002+ TypeMetadataAddress::FullMetadata);
4003+ } else {
4004+ entity = LinkEntity::forTypeMetadata (concreteType,
4005+ TypeMetadataAddress::AddressPoint);
4006+ }
4007+ break ;
4008+ case TypeMetadataCanonicality::Noncanonical:
4009+ entity =
4010+ LinkEntity::forNoncanonicalSpecializedGenericTypeMetadata (concreteType);
4011+ break ;
39614012 }
39624013 DbgTy = DebugTypeInfo::getMetadata (MetatypeType::get (concreteType),
39634014 defaultVarTy->getPointerTo (), Size (0 ),
0 commit comments