Skip to content

Commit b716235

Browse files
committed
[metadata prespecialization] Standardize checks to ref tables.
Previously, some ad hoc checks were done in order to determine whether the metadata access for a generic type was trivial. Now, standard predicates are used, specifically IRGenModule's member functions isDependentConformance and isResilientConformance.
1 parent dac39b1 commit b716235

File tree

1 file changed

+26
-29
lines changed

1 file changed

+26
-29
lines changed

lib/IRGen/MetadataRequest.cpp

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -696,36 +696,33 @@ bool irgen::isNominalGenericContextTypeMetadataAccessTrivial(
696696
auto substitutions =
697697
type->getContextSubstitutionMap(IGM.getSwiftModule(), &nominal);
698698

699-
return llvm::all_of(environment->getGenericParams(), [&](auto parameter) {
700-
auto conformances =
701-
environment->getGenericSignature()->getConformsTo(parameter);
702-
auto witnessTablesAreReferenceable =
703-
llvm::all_of(conformances, [&](ProtocolDecl *conformance) {
704-
return conformance->getModuleContext() == IGM.getSwiftModule() &&
705-
!conformance->isResilient(IGM.getSwiftModule(),
706-
ResilienceExpansion::Minimal);
707-
});
699+
auto allWitnessTablesAreReferenceable = llvm::all_of(environment->getGenericParams(), [&](auto parameter) {
700+
auto signature = environment->getGenericSignature();
701+
auto protocols = signature->getConformsTo(parameter);
708702
auto argument = ((Type *)parameter)->subst(substitutions);
709-
auto genericArgument = argument->getAnyGeneric();
710-
// For now, to avoid statically specializing generic protocol witness
711-
// tables, don't statically specialize metadata for types any of whose
712-
// arguments are generic.
713-
//
714-
// TODO: This is more pessimistic than necessary. Specialize even in
715-
// the face of generic arguments so long as those arguments
716-
// aren't required to conform to any protocols.
717-
//
718-
// TODO: Once witness tables are statically specialized, check whether the
719-
// ConformanceInfo returns nullptr from tryGetConstantTable.
720-
// early return.
721-
auto isGeneric = genericArgument && genericArgument->isGenericContext();
722-
auto isNominal = argument->getNominalOrBoundGenericNominal();
723-
auto isExistential = argument->isExistentialType();
724-
return isNominal && !isGeneric && !isExistential &&
725-
witnessTablesAreReferenceable &&
726-
irgen::isTypeMetadataAccessTrivial(IGM,
727-
argument->getCanonicalType());
728-
}) && IGM.getTypeInfoForUnlowered(type).isFixedSize(ResilienceExpansion::Maximal);
703+
auto canonicalType = argument->getCanonicalType();
704+
auto witnessTablesAreReferenceable = [&]() {
705+
return llvm::all_of(protocols, [&](ProtocolDecl *protocol) {
706+
auto conformance =
707+
signature->lookupConformance(canonicalType, protocol);
708+
if (!conformance.isConcrete()) {
709+
return false;
710+
}
711+
auto rootConformance = conformance.getConcrete()->getRootConformance();
712+
return !IGM.isDependentConformance(rootConformance) &&
713+
!IGM.isResilientConformance(rootConformance);
714+
});
715+
};
716+
auto isExistential = [&]() { return argument->isExistentialType(); };
717+
auto metadataAccessIsTrivial = [&]() {
718+
return irgen::isTypeMetadataAccessTrivial(IGM,
719+
argument->getCanonicalType());
720+
};
721+
return !isExistential() && metadataAccessIsTrivial() &&
722+
witnessTablesAreReferenceable();
723+
});
724+
return allWitnessTablesAreReferenceable
725+
&& IGM.getTypeInfoForUnlowered(type).isFixedSize(ResilienceExpansion::Maximal);
729726
}
730727

731728
/// Is it basically trivial to access the given metadata? If so, we don't

0 commit comments

Comments
 (0)