Skip to content

Commit b939fde

Browse files
committed
IRGen: Refactor away MetadataAccessStrategy::Direct, NFC
This is a preliminary refactoring toward emitting generic metadata instantiation accessors. This will let us stop exporting metadata template symbols and reference accessors from conformance tables instead. The latter is required to enable conformances where the conforming type is resilient.
1 parent 2b02b0f commit b939fde

File tree

4 files changed

+35
-59
lines changed

4 files changed

+35
-59
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,16 +1051,14 @@ SILLinkage LinkEntity::getLinkage(IRGenModule &IGM,
10511051

10521052
case Kind::TypeMetadataAccessFunction:
10531053
case Kind::TypeMetadataLazyCacheVariable:
1054-
switch (getTypeMetadataAccessStrategy(IGM, getType(),
1055-
/*preferDirectAccess=*/false)) {
1054+
switch (getTypeMetadataAccessStrategy(IGM, getType())) {
10561055
case MetadataAccessStrategy::PublicUniqueAccessor:
10571056
return getSILLinkage(FormalLinkage::PublicUnique, forDefinition);
10581057
case MetadataAccessStrategy::HiddenUniqueAccessor:
10591058
return getSILLinkage(FormalLinkage::HiddenUnique, forDefinition);
10601059
case MetadataAccessStrategy::PrivateAccessor:
10611060
return getSILLinkage(FormalLinkage::Private, forDefinition);
10621061
case MetadataAccessStrategy::NonUniqueAccessor:
1063-
case MetadataAccessStrategy::Direct:
10641062
return SILLinkage::Shared;
10651063
}
10661064
llvm_unreachable("bad metadata access kind");

lib/IRGen/GenMeta.cpp

Lines changed: 27 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,17 @@ bool irgen::hasKnownVTableEntry(IRGenModule &IGM,
416416
return hasKnownSwiftImplementation(IGM, theClass);
417417
}
418418

419-
static bool hasBuiltinTypeMetadata(CanType type) {
419+
/// Is it basically trivial to access the given metadata? If so, we don't
420+
/// need a cache variable in its accessor.
421+
bool irgen::isTypeMetadataAccessTrivial(IRGenModule &IGM, CanType type) {
422+
// Value type metadata only requires dynamic initialization on first
423+
// access if it contains a resilient type.
424+
if (isa<StructType>(type) || isa<EnumType>(type)) {
425+
assert(!cast<NominalType>(type)->getDecl()->isGenericContext() &&
426+
"shouldn't be called for a generic type");
427+
return (IGM.getTypeInfoForLowered(type).isFixedSize());
428+
}
429+
420430
// The empty tuple type has a singleton metadata.
421431
if (auto tuple = dyn_cast<TupleType>(type))
422432
return tuple->getNumElements() == 0;
@@ -431,32 +441,17 @@ static bool hasBuiltinTypeMetadata(CanType type) {
431441
if (isa<SILBoxType>(type))
432442
return true;
433443

434-
return false;
435-
}
436-
437-
/// Is it basically trivial to access the given metadata? If so, we don't
438-
/// need a cache variable in its accessor.
439-
static bool isTypeMetadataAccessTrivial(IRGenModule &IGM, CanType type) {
440-
// Value type metadata only requires dynamic initialization on first
441-
// access if it contains a resilient type.
442-
if (isa<StructType>(type) || isa<EnumType>(type)) {
443-
assert(!cast<NominalType>(type)->getDecl()->isGenericContext() &&
444-
"shouldn't be called for a generic type");
445-
return (IGM.getTypeInfoForLowered(type).isFixedSize());
446-
}
447-
448-
if (hasBuiltinTypeMetadata(type)) {
444+
// DynamicSelfType is actually local.
445+
if (type->hasDynamicSelfType())
449446
return true;
450-
}
451447

452448
return false;
453449
}
454450

455451
/// Return the standard access strategy for getting a non-dependent
456452
/// type metadata object.
457453
MetadataAccessStrategy
458-
irgen::getTypeMetadataAccessStrategy(IRGenModule &IGM, CanType type,
459-
bool preferDirectAccess) {
454+
irgen::getTypeMetadataAccessStrategy(IRGenModule &IGM, CanType type) {
460455
assert(!type->hasArchetype());
461456

462457
// Non-generic structs, enums, and classes are special cases.
@@ -469,10 +464,6 @@ irgen::getTypeMetadataAccessStrategy(IRGenModule &IGM, CanType type,
469464
if (nominal->getDecl()->isGenericContext())
470465
return MetadataAccessStrategy::NonUniqueAccessor;
471466

472-
if (preferDirectAccess &&
473-
isTypeMetadataAccessTrivial(IGM, type))
474-
return MetadataAccessStrategy::Direct;
475-
476467
// If the type doesn't guarantee that it has an access function,
477468
// we might have to use a non-unique accessor.
478469

@@ -492,14 +483,6 @@ irgen::getTypeMetadataAccessStrategy(IRGenModule &IGM, CanType type,
492483
llvm_unreachable("bad formal linkage");
493484
}
494485

495-
// DynamicSelfType is actually local.
496-
if (type->hasDynamicSelfType())
497-
return MetadataAccessStrategy::Direct;
498-
499-
// Some types have special metadata in the runtime.
500-
if (hasBuiltinTypeMetadata(type))
501-
return MetadataAccessStrategy::Direct;
502-
503486
// Everything else requires a shared accessor function.
504487
return MetadataAccessStrategy::NonUniqueAccessor;
505488
}
@@ -1158,22 +1141,20 @@ static llvm::Value *emitCallToTypeMetadataAccessFunction(IRGenFunction &IGF,
11581141

11591142
/// Produce the type metadata pointer for the given type.
11601143
llvm::Value *IRGenFunction::emitTypeMetadataRef(CanType type) {
1161-
if (!type->hasArchetype()) {
1162-
switch (getTypeMetadataAccessStrategy(IGM, type,
1163-
/*preferDirectAccess=*/true)) {
1164-
case MetadataAccessStrategy::Direct:
1165-
return emitDirectTypeMetadataRef(*this, type);
1166-
case MetadataAccessStrategy::PublicUniqueAccessor:
1167-
case MetadataAccessStrategy::HiddenUniqueAccessor:
1168-
case MetadataAccessStrategy::PrivateAccessor:
1169-
return emitCallToTypeMetadataAccessFunction(*this, type, NotForDefinition);
1170-
case MetadataAccessStrategy::NonUniqueAccessor:
1171-
return emitCallToTypeMetadataAccessFunction(*this, type, ForDefinition);
1172-
}
1173-
llvm_unreachable("bad type metadata access strategy");
1144+
if (type->hasArchetype() ||
1145+
isTypeMetadataAccessTrivial(IGM, type)) {
1146+
return emitDirectTypeMetadataRef(*this, type);
11741147
}
11751148

1176-
return emitDirectTypeMetadataRef(*this, type);
1149+
switch (getTypeMetadataAccessStrategy(IGM, type)) {
1150+
case MetadataAccessStrategy::PublicUniqueAccessor:
1151+
case MetadataAccessStrategy::HiddenUniqueAccessor:
1152+
case MetadataAccessStrategy::PrivateAccessor:
1153+
return emitCallToTypeMetadataAccessFunction(*this, type, NotForDefinition);
1154+
case MetadataAccessStrategy::NonUniqueAccessor:
1155+
return emitCallToTypeMetadataAccessFunction(*this, type, ForDefinition);
1156+
}
1157+
llvm_unreachable("bad type metadata access strategy");
11771158
}
11781159

11791160
/// Return the address of a function that will return type metadata
@@ -1183,13 +1164,11 @@ llvm::Function *irgen::getOrCreateTypeMetadataAccessFunction(IRGenModule &IGM,
11831164
assert(!type->hasArchetype() &&
11841165
"cannot create global function to return dependent type metadata");
11851166

1186-
switch (getTypeMetadataAccessStrategy(IGM, type,
1187-
/*preferDirectAccess=*/false)) {
1167+
switch (getTypeMetadataAccessStrategy(IGM, type)) {
11881168
case MetadataAccessStrategy::PublicUniqueAccessor:
11891169
case MetadataAccessStrategy::HiddenUniqueAccessor:
11901170
case MetadataAccessStrategy::PrivateAccessor:
11911171
return getTypeMetadataAccessFunction(IGM, type, NotForDefinition);
1192-
case MetadataAccessStrategy::Direct:
11931172
case MetadataAccessStrategy::NonUniqueAccessor:
11941173
return getTypeMetadataAccessFunction(IGM, type, ForDefinition);
11951174
}

lib/IRGen/GenMeta.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,16 +271,16 @@ namespace irgen {
271271

272272
/// There is no unique accessor function for the given type metadata, but
273273
/// one should be made automatically.
274-
NonUniqueAccessor,
275-
276-
/// The given type metadata should be accessed directly.
277-
Direct,
274+
NonUniqueAccessor
278275
};
279276

277+
/// Is it basically trivial to access the given metadata? If so, we don't
278+
/// need a cache variable in its accessor.
279+
bool isTypeMetadataAccessTrivial(IRGenModule &IGM, CanType type);
280+
280281
/// Determine how the given type metadata should be accessed.
281282
MetadataAccessStrategy getTypeMetadataAccessStrategy(IRGenModule &IGM,
282-
CanType type,
283-
bool preferDirectAccess);
283+
CanType type);
284284

285285
/// Return the address of a function that will return type metadata
286286
/// for the given non-dependent type.

lib/IRGen/LocalTypeData.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,7 @@ addAbstractForFulfillments(IRGenFunction &IGF, FulfillmentMap &&fulfillments,
306306
// the type metadata for Int by chasing through N layers of metadata
307307
// just because that path happens to be in the cache.
308308
if (!type->hasArchetype() &&
309-
getTypeMetadataAccessStrategy(IGF.IGM, type, /*preferDirect*/ true)
310-
== MetadataAccessStrategy::Direct) {
309+
isTypeMetadataAccessTrivial(IGF.IGM, type)) {
311310
continue;
312311
}
313312

0 commit comments

Comments
 (0)