Skip to content

Commit 19fe31f

Browse files
committed
IRGen: Emit and use accessors for generic type metadata
Instead of directly emitting calls to swift_getGenericMetadata*() and referencing metadata templates, call a metadata accessor function corresponding to the UnboundGenericType of the NominalTypeDecl. The body of this accessor forwards arguments to a runtime metadata instantiation function, together with the template. Also, move some code around, so that metadata accesses which are only done as part of the body of a metadata accessor function are handled separately in emitTypeMetadataAccessFunction(). Apart from protocol conformances, this means metadata templates are no longer referenced from outside the module where they were defined.
1 parent 0515889 commit 19fe31f

17 files changed

+365
-266
lines changed

docs/Runtime.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,6 @@ detail used to implement resilient per-type metadata accessor functions.
282282
000000000001f1f0 T _swift_getFunctionTypeMetadata2
283283
000000000001f250 T _swift_getFunctionTypeMetadata3
284284
000000000001e940 T _swift_getGenericMetadata
285-
000000000001e9c0 T _swift_getGenericMetadata1
286-
000000000001ea60 T _swift_getGenericMetadata2
287-
000000000001eb00 T _swift_getGenericMetadata3
288-
000000000001eba0 T _swift_getGenericMetadata4
289285
0000000000022fd0 T _swift_getMetatypeMetadata
290286
000000000001ec50 T _swift_getObjCClassMetadata
291287
000000000001e6b0 T _swift_getResilientMetadata

include/swift/Runtime/Metadata.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2463,27 +2463,6 @@ extern "C" const Metadata *
24632463
swift_getGenericMetadata(GenericMetadata *pattern,
24642464
const void *arguments);
24652465

2466-
// Fast entry points for swift_getGenericMetadata with a small number of
2467-
// template arguments.
2468-
extern "C" const Metadata *
2469-
swift_getGenericMetadata1(GenericMetadata *pattern,
2470-
const void *arg0);
2471-
extern "C" const Metadata *
2472-
swift_getGenericMetadata2(GenericMetadata *pattern,
2473-
const void *arg0,
2474-
const void *arg1);
2475-
extern "C" const Metadata *
2476-
swift_getGenericMetadata3(GenericMetadata *pattern,
2477-
const void *arg0,
2478-
const void *arg1,
2479-
const void *arg2);
2480-
extern "C" const Metadata *
2481-
swift_getGenericMetadata4(GenericMetadata *pattern,
2482-
const void *arg0,
2483-
const void *arg1,
2484-
const void *arg2,
2485-
const void *arg3);
2486-
24872466
// Callback to allocate a generic class metadata object.
24882467
extern "C" ClassMetadata *
24892468
swift_allocateGenericClassMetadata(GenericMetadata *pattern,

lib/IRGen/GenDecl.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,12 +2165,37 @@ IRGenModule::getAddrOfTypeMetadataAccessFunction(CanType type,
21652165
return entry;
21662166
}
21672167

2168+
/// Fetch the type metadata access function for the given generic type.
2169+
llvm::Function *
2170+
IRGenModule::getAddrOfGenericTypeMetadataAccessFunction(
2171+
NominalTypeDecl *nominal,
2172+
ArrayRef<llvm::Type *> genericArgs,
2173+
ForDefinition_t forDefinition) {
2174+
assert(!genericArgs.empty());
2175+
assert(nominal->isGenericContext());
2176+
2177+
auto type = nominal->getDeclaredType()->getCanonicalType();
2178+
assert(isa<UnboundGenericType>(type));
2179+
LinkEntity entity = LinkEntity::forTypeMetadataAccessFunction(type);
2180+
llvm::Function *&entry = GlobalFuncs[entity];
2181+
if (entry) {
2182+
if (forDefinition) updateLinkageForDefinition(*this, entry, entity);
2183+
return entry;
2184+
}
2185+
2186+
auto fnType = llvm::FunctionType::get(TypeMetadataPtrTy, genericArgs, false);
2187+
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
2188+
entry = link.createFunction(*this, fnType, RuntimeCC, llvm::AttributeSet());
2189+
return entry;
2190+
}
2191+
21682192
/// Get or create a type metadata cache variable. These are an
21692193
/// implementation detail of type metadata access functions.
21702194
llvm::Constant *
21712195
IRGenModule::getAddrOfTypeMetadataLazyCacheVariable(CanType type,
21722196
ForDefinition_t forDefinition) {
21732197
assert(!type->hasArchetype() && !type->hasTypeParameter());
2198+
assert(!type->hasUnboundGenericType());
21742199
LinkEntity entity = LinkEntity::forTypeMetadataLazyCacheVariable(type);
21752200
return getAddrOfLLVMVariable(entity, getPointerAlignment(), forDefinition,
21762201
TypeMetadataPtrTy, DebugTypeInfo());

0 commit comments

Comments
 (0)