Skip to content

Commit 059f1de

Browse files
authored
Merge pull request #30036 from jckarter/trivial-vs-static-metadata
IRGen: Separate the concept of "metadata should be cached" from "statically referenced"
2 parents 853c0f5 + 7ec52e6 commit 059f1de

File tree

4 files changed

+28
-35
lines changed

4 files changed

+28
-35
lines changed

lib/IRGen/LocalTypeData.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ addAbstractForFulfillments(IRGenFunction &IGF, FulfillmentMap &&fulfillments,
560560
// the type metadata for Int by chasing through N layers of metadata
561561
// just because that path happens to be in the cache.
562562
if (!type->hasArchetype() &&
563-
isTypeMetadataAccessTrivial(IGF.IGM, type)) {
563+
!shouldCacheTypeMetadataAccess(IGF.IGM, type)) {
564564
continue;
565565
}
566566

lib/IRGen/MetadataRequest.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ irgen::tryEmitConstantTypeMetadataRef(IRGenModule &IGM, CanType type,
556556
SymbolReferenceKind refKind) {
557557
if (IGM.isStandardLibrary())
558558
return ConstantReference();
559-
if (!isTypeMetadataAccessTrivial(IGM, type))
559+
if (isCompleteTypeMetadataStaticallyAddressable(IGM, type))
560560
return ConstantReference();
561561
return IGM.getAddrOfTypeMetadata(type, refKind);
562562
}
@@ -722,7 +722,7 @@ bool irgen::isNominalGenericContextTypeMetadataAccessTrivial(
722722
};
723723
auto isExistential = [&]() { return argument->isExistentialType(); };
724724
auto metadataAccessIsTrivial = [&]() {
725-
return irgen::isTypeMetadataAccessTrivial(IGM,
725+
return irgen::isCompleteTypeMetadataStaticallyAddressable(IGM,
726726
argument->getCanonicalType());
727727
};
728728
return !isGenericWithoutPrespecializedConformance() && !isExistential() &&
@@ -732,9 +732,9 @@ bool irgen::isNominalGenericContextTypeMetadataAccessTrivial(
732732
&& IGM.getTypeInfoForUnlowered(type).isFixedSize(ResilienceExpansion::Maximal);
733733
}
734734

735-
/// Is it basically trivial to access the given metadata? If so, we don't
736-
/// need a cache variable in its accessor.
737-
bool irgen::isTypeMetadataAccessTrivial(IRGenModule &IGM, CanType type) {
735+
/// Is complete metadata for the given type available at a fixed address?
736+
bool irgen::isCompleteTypeMetadataStaticallyAddressable(IRGenModule &IGM,
737+
CanType type) {
738738
assert(!type->hasArchetype());
739739

740740
// Value type metadata only requires dynamic initialization on first
@@ -775,10 +775,6 @@ bool irgen::isTypeMetadataAccessTrivial(IRGenModule &IGM, CanType type) {
775775
if (isa<SILBoxType>(type))
776776
return true;
777777

778-
// DynamicSelfType is actually local.
779-
if (type->hasDynamicSelfType())
780-
return true;
781-
782778
if (isa<BoundGenericStructType>(type) || isa<BoundGenericEnumType>(type)) {
783779
auto nominalType = cast<BoundGenericType>(type);
784780
auto *nominalDecl = nominalType->getDecl();
@@ -794,6 +790,19 @@ bool irgen::isTypeMetadataAccessTrivial(IRGenModule &IGM, CanType type) {
794790
return false;
795791
}
796792

793+
/// Should requests for the given type's metadata be cached?
794+
bool irgen::shouldCacheTypeMetadataAccess(IRGenModule &IGM, CanType type) {
795+
// DynamicSelfType is actually local.
796+
if (type->hasDynamicSelfType())
797+
return false;
798+
799+
// Statically addressable metadata does not need a cache.
800+
if (isCompleteTypeMetadataStaticallyAddressable(IGM, type))
801+
return false;
802+
803+
return true;
804+
}
805+
797806
/// Return the standard access strategy for getting a non-dependent
798807
/// type metadata object.
799808
MetadataAccessStrategy irgen::getTypeMetadataAccessStrategy(CanType type) {
@@ -2016,7 +2025,7 @@ emitDirectTypeMetadataAccessFunctionBody(IRGenFunction &IGF,
20162025
}
20172026

20182027
// We should not be doing more serious work along this path.
2019-
assert(isTypeMetadataAccessTrivial(IGF.IGM, type));
2028+
assert(isCompleteTypeMetadataStaticallyAddressable(IGF.IGM, type));
20202029

20212030
// Okay, everything else is built from a Swift metadata object.
20222031
llvm::Constant *metadata = IGF.IGM.getAddrOfTypeMetadata(type);
@@ -2064,7 +2073,7 @@ irgen::createTypeMetadataAccessFunction(IRGenModule &IGM, CanType type,
20642073

20652074
// If our preferred access method is to go via an accessor, it means
20662075
// there is some non-trivial computation that needs to be cached.
2067-
if (isTypeMetadataAccessTrivial(IGM, type)) {
2076+
if (!shouldCacheTypeMetadataAccess(IGM, type)) {
20682077
cacheStrategy = CacheStrategy::None;
20692078
} else {
20702079
switch (cacheStrategy) {
@@ -2194,7 +2203,7 @@ static bool shouldAccessByMangledName(IRGenModule &IGM, CanType type) {
21942203
// others may require accessors to trigger instantiation.
21952204
//
21962205
// TODO: Also need to count the parent type's generic arguments.
2197-
if (isTypeMetadataAccessTrivial(IGM, nom)) {
2206+
if (!shouldCacheTypeMetadataAccess(IGM, nom)) {
21982207
NumAddresses += 1;
21992208
} else {
22002209
NumCalls += 1;
@@ -2545,8 +2554,7 @@ IRGenFunction::emitTypeMetadataRef(CanType type,
25452554
}
25462555

25472556
if (type->hasArchetype() ||
2548-
isTypeMetadataAccessTrivial(IGM, type)) {
2549-
// FIXME: propagate metadata request!
2557+
!shouldCacheTypeMetadataAccess(IGM, type)) {
25502558
return emitDirectTypeMetadataRef(*this, type, request);
25512559
}
25522560

lib/IRGen/MetadataRequest.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -500,9 +500,10 @@ static inline bool isAccessorLazilyGenerated(MetadataAccessStrategy strategy) {
500500
llvm_unreachable("bad kind");
501501
}
502502

503-
/// Is it basically trivial to access the given metadata? If so, we don't
504-
/// need a cache variable in its accessor.
505-
bool isTypeMetadataAccessTrivial(IRGenModule &IGM, CanType type);
503+
/// Is complete metadata for the given type available at a fixed address?
504+
bool isCompleteTypeMetadataStaticallyAddressable(IRGenModule &IGM, CanType type);
505+
/// Should requests for the given type's metadata be cached?
506+
bool shouldCacheTypeMetadataAccess(IRGenModule &IGM, CanType type);
506507

507508
bool isNominalGenericContextTypeMetadataAccessTrivial(IRGenModule &IGM,
508509
NominalTypeDecl &nominal,

test/IRGen/dynamic_self_metadata_future.swift

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,7 @@ class C {
5757
// CHECK-SAME: {{.*}} @"$s28dynamic_self_metadata_future1GVyxGAA1PAAMc"
5858
// CHECK-SAME: to %swift.protocol_conformance_descriptor*
5959
// CHECK-SAME: ),
60-
// CHECK-SAME: %swift.type* getelementptr inbounds (
61-
// CHECK-SAME: %swift.full_type,
62-
// CHECK-SAME: %swift.full_type* bitcast (
63-
// CHECK-SAME: <{
64-
// CHECK-SAME: i8**,
65-
// CHECK-SAME: [[INT]],
66-
// CHECK-SAME: %swift.type_descriptor*,
67-
// CHECK-SAME: %swift.type*,
68-
// CHECK-SAME: i32,
69-
// CHECK-SAME: {{(\[4 x i8\])?}},
70-
// CHECK-SAME: i64
71-
// CHECK-SAME: }>* @"$s28dynamic_self_metadata_future1GVyAA1CCXDGMf"
72-
// CHECK-SAME: to %swift.full_type*
73-
// CHECK-SAME: ),
74-
// CHECK-SAME: i32 0,
75-
// CHECK-SAME: i32 1
76-
// CHECK-SAME: ),
60+
// CHECK-SAME: %swift.type* %{{[0-9]+}},
7761
// CHECK-SAME: i8*** undef
7862
// CHECK-SAME: )
7963
}

0 commit comments

Comments
 (0)