mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/master' into master-rebranch
This commit is contained in:
@@ -1426,7 +1426,22 @@ void IRGenerator::noteUseOfCanonicalSpecializedMetadataAccessor(
|
||||
}
|
||||
}
|
||||
|
||||
static bool typeKindCanBePrespecialized(TypeKind theKind) {
|
||||
switch (theKind) {
|
||||
case TypeKind::Struct:
|
||||
case TypeKind::BoundGenericStruct:
|
||||
case TypeKind::Enum:
|
||||
case TypeKind::BoundGenericEnum:
|
||||
case TypeKind::Class:
|
||||
case TypeKind::BoundGenericClass:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void IRGenerator::noteUseOfSpecializedGenericTypeMetadata(CanType type) {
|
||||
assert(typeKindCanBePrespecialized(type->getKind()));
|
||||
auto key = type->getAnyNominal();
|
||||
assert(key);
|
||||
assert(key->isGenericContext());
|
||||
@@ -3736,6 +3751,22 @@ IRGenModule::getAddrOfTypeMetadataLazyCacheVariable(CanType type) {
|
||||
return variable;
|
||||
}
|
||||
|
||||
llvm::Constant *
|
||||
IRGenModule::getAddrOfNoncanonicalSpecializedGenericTypeMetadataCacheVariable(CanType type) {
|
||||
assert(!type->hasArchetype() && !type->hasTypeParameter());
|
||||
LinkEntity entity = LinkEntity::forNoncanonicalSpecializedGenericTypeMetadataCacheVariable(type);
|
||||
if (auto &entry = GlobalVars[entity]) {
|
||||
return entry;
|
||||
}
|
||||
auto variable =
|
||||
getAddrOfLLVMVariable(entity, ForDefinition, DebugTypeInfo());
|
||||
|
||||
cast<llvm::GlobalVariable>(variable)->setInitializer(
|
||||
llvm::ConstantPointerNull::get(TypeMetadataPtrTy));
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
/// Get or create a type metadata cache variable. These are an
|
||||
/// implementation detail of type metadata access functions.
|
||||
llvm::Constant *
|
||||
@@ -3817,6 +3848,9 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
|
||||
llvm::StringRef section) {
|
||||
assert(init);
|
||||
|
||||
auto isPrespecialized = concreteType->getAnyGeneric() &&
|
||||
concreteType->getAnyGeneric()->isGenericContext();
|
||||
|
||||
if (isPattern) {
|
||||
assert(isConstant && "Type metadata patterns must be constant");
|
||||
auto addr = getAddrOfTypeMetadataPattern(concreteType->getAnyNominal(),
|
||||
@@ -3844,7 +3878,13 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
|
||||
adjustmentIndex = MetadataAdjustmentIndex::ValueType;
|
||||
}
|
||||
|
||||
auto entity = LinkEntity::forTypeMetadata(concreteType, addrKind);
|
||||
auto entity =
|
||||
(isPrespecialized &&
|
||||
!irgen::isCanonicalInitializableTypeMetadataStaticallyAddressable(
|
||||
*this, concreteType))
|
||||
? LinkEntity::forNoncanonicalSpecializedGenericTypeMetadata(
|
||||
concreteType)
|
||||
: LinkEntity::forTypeMetadata(concreteType, addrKind);
|
||||
|
||||
auto DbgTy = DebugTypeInfo::getMetadata(MetatypeType::get(concreteType),
|
||||
entity.getDefaultDeclarationType(*this)->getPointerTo(),
|
||||
@@ -3868,9 +3908,7 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
|
||||
|
||||
// Don't define the alias for foreign type metadata or prespecialized generic
|
||||
// metadata, since neither is ABI.
|
||||
if ((nominal && requiresForeignTypeMetadata(nominal)) ||
|
||||
(concreteType->getAnyGeneric() &&
|
||||
concreteType->getAnyGeneric()->isGenericContext()))
|
||||
if ((nominal && requiresForeignTypeMetadata(nominal)) || isPrespecialized)
|
||||
return var;
|
||||
|
||||
// For concrete metadata, declare the alias to its address point.
|
||||
@@ -3892,13 +3930,18 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
|
||||
}
|
||||
|
||||
/// Fetch the declaration of the (possibly uninitialized) metadata for a type.
|
||||
llvm::Constant *IRGenModule::getAddrOfTypeMetadata(CanType concreteType) {
|
||||
return getAddrOfTypeMetadata(concreteType,
|
||||
SymbolReferenceKind::Absolute).getDirectValue();
|
||||
llvm::Constant *
|
||||
IRGenModule::getAddrOfTypeMetadata(CanType concreteType,
|
||||
TypeMetadataCanonicality canonicality) {
|
||||
return getAddrOfTypeMetadata(concreteType, SymbolReferenceKind::Absolute,
|
||||
canonicality)
|
||||
.getDirectValue();
|
||||
}
|
||||
|
||||
ConstantReference IRGenModule::getAddrOfTypeMetadata(CanType concreteType,
|
||||
SymbolReferenceKind refKind) {
|
||||
ConstantReference
|
||||
IRGenModule::getAddrOfTypeMetadata(CanType concreteType,
|
||||
SymbolReferenceKind refKind,
|
||||
TypeMetadataCanonicality canonicality) {
|
||||
assert(!isa<UnboundGenericType>(concreteType));
|
||||
|
||||
auto nominal = concreteType->getAnyNominal();
|
||||
@@ -3952,12 +3995,20 @@ ConstantReference IRGenModule::getAddrOfTypeMetadata(CanType concreteType,
|
||||
Optional<LinkEntity> entity;
|
||||
DebugTypeInfo DbgTy;
|
||||
|
||||
if (fullMetadata) {
|
||||
entity = LinkEntity::forTypeMetadata(concreteType,
|
||||
TypeMetadataAddress::FullMetadata);
|
||||
} else {
|
||||
entity = LinkEntity::forTypeMetadata(concreteType,
|
||||
TypeMetadataAddress::AddressPoint);
|
||||
switch (canonicality) {
|
||||
case TypeMetadataCanonicality::Canonical:
|
||||
if (fullMetadata) {
|
||||
entity = LinkEntity::forTypeMetadata(concreteType,
|
||||
TypeMetadataAddress::FullMetadata);
|
||||
} else {
|
||||
entity = LinkEntity::forTypeMetadata(concreteType,
|
||||
TypeMetadataAddress::AddressPoint);
|
||||
}
|
||||
break;
|
||||
case TypeMetadataCanonicality::Noncanonical:
|
||||
entity =
|
||||
LinkEntity::forNoncanonicalSpecializedGenericTypeMetadata(concreteType);
|
||||
break;
|
||||
}
|
||||
DbgTy = DebugTypeInfo::getMetadata(MetatypeType::get(concreteType),
|
||||
defaultVarTy->getPointerTo(), Size(0),
|
||||
|
||||
Reference in New Issue
Block a user