Skip to content

Commit e1d7986

Browse files
committed
AST: Nuke GenericSignature::getCanonicalManglingSignature()
Now that the previous patches have shaken out implicit assumptions about the order of generic requirements and substitutions, we can make a more radical change, dropping redundant protocol requirements when building the original generic signature. This means that the canonical ordering and minimization that we used to only perform when building the mangling signature is done all of the time, and hence getCanonicalManglingSignature() can go away. Usages now either call getCanonicalSignature(), or operate on the original signature directly.
1 parent 9c3758c commit e1d7986

21 files changed

+53
-151
lines changed

include/swift/AST/ASTContext.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,6 @@ class ASTContext {
230230

231231
/// Cache of remapped types (useful for diagnostics).
232232
llvm::StringMap<Type> RemappedTypes;
233-
234-
/// Cache for generic mangling signatures.
235-
llvm::DenseMap<std::pair<GenericSignature*, ModuleDecl*>,
236-
CanGenericSignature> ManglingSignatures;
237233

238234
private:
239235
/// \brief The current generation number, which reflects the number of
@@ -838,12 +834,6 @@ class ASTContext {
838834
ArchetypeBuilder *getOrCreateArchetypeBuilder(CanGenericSignature sig,
839835
ModuleDecl *mod);
840836

841-
/// Set the stored archetype builder for the given canonical generic
842-
/// signature and module.
843-
void setArchetypeBuilder(CanGenericSignature sig,
844-
ModuleDecl *mod,
845-
std::unique_ptr<ArchetypeBuilder> builder);
846-
847837
/// Retrieve the inherited name set for the given class.
848838
const InheritedNameSet *getAllPropertyNames(ClassDecl *classDecl,
849839
bool forInstance);

include/swift/AST/ArchetypeBuilder.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class RequirementSource {
7070
/// The requirement was part of a protocol requirement on an
7171
/// associated type.
7272
///
73-
/// These are dropped by getCanonicalManglingSignature().
73+
/// These are dropped when building the GenericSignature.
7474
Protocol,
7575

7676
/// The requirement is redundant with some other requirement.
@@ -257,15 +257,10 @@ class ArchetypeBuilder {
257257
/// \brief Get a generic signature based on the provided complete list
258258
/// of generic parameter types.
259259
///
260-
/// \param buildingCanonicalManglingSignature If true, requirements
261-
/// on associated types are dropped, and types in requirements
262-
/// are canonicalized.
263-
///
264260
/// \returns a generic signature built from the provided list of
265261
/// generic parameter types.
266262
GenericSignature *
267-
getGenericSignature(ArrayRef<GenericTypeParamType *> genericParamsTypes,
268-
bool buildingCanonicalManglingSignature=false);
263+
getGenericSignature(ArrayRef<GenericTypeParamType *> genericParamsTypes);
269264

270265
/// \brief Get a generic context based on the complete list of generic
271266
/// parameter types.

include/swift/AST/GenericSignature.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,16 +210,6 @@ class GenericSignature final : public llvm::FoldingSetNode,
210210

211211
/// Canonicalize the components of a generic signature.
212212
CanGenericSignature getCanonicalSignature() const;
213-
214-
/// Canonicalize a generic signature down to its essential requirements,
215-
/// for mangling purposes.
216-
///
217-
/// TODO: This is what getCanonicalSignature() ought to do, but currently
218-
/// does not due to former implementation dependencies on
219-
/// 'getAllDependentTypes' order matching 'getAllArchetypes' order of a
220-
/// generic param list. Now that 'getAllArchetypes' is gone, we might
221-
/// be able to move forward here.
222-
CanGenericSignature getCanonicalManglingSignature(ModuleDecl &M) const;
223213

224214
/// Uniquing for the ASTContext.
225215
void Profile(llvm::FoldingSetNodeID &ID) {

lib/AST/ASTContext.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,15 +1459,6 @@ ArchetypeBuilder *ASTContext::getOrCreateArchetypeBuilder(
14591459
return builder;
14601460
}
14611461

1462-
void ASTContext::setArchetypeBuilder(CanGenericSignature sig,
1463-
ModuleDecl *mod,
1464-
std::unique_ptr<ArchetypeBuilder> builder) {
1465-
if (Impl.ArchetypeBuilders.find({sig, mod})
1466-
== Impl.ArchetypeBuilders.end()) {
1467-
Impl.ArchetypeBuilders[{sig, mod}] = move(builder);
1468-
}
1469-
}
1470-
14711462
Module *
14721463
ASTContext::getModule(ArrayRef<std::pair<Identifier, SourceLoc>> ModulePath) {
14731464
assert(!ModulePath.empty());

lib/AST/ArchetypeBuilder.cpp

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,8 +2020,7 @@ Type ArchetypeBuilder::substDependentType(Type type) {
20202020
/// their associated types.
20212021
static void collectRequirements(ArchetypeBuilder &builder,
20222022
ArrayRef<GenericTypeParamType *> params,
2023-
SmallVectorImpl<Requirement> &requirements,
2024-
bool buildingCanonicalManglingSignature) {
2023+
SmallVectorImpl<Requirement> &requirements) {
20252024
builder.enumerateRequirements([&](RequirementKind kind,
20262025
ArchetypeBuilder::PotentialArchetype *archetype,
20272026
llvm::PointerUnion<Type, ArchetypeBuilder::PotentialArchetype *> type,
@@ -2030,23 +2029,14 @@ static void collectRequirements(ArchetypeBuilder &builder,
20302029
switch (source.getKind()) {
20312030
case RequirementSource::Explicit:
20322031
case RequirementSource::Inferred:
2032+
case RequirementSource::OuterScope:
20332033
// The requirement was explicit and required, keep it.
20342034
break;
20352035

20362036
case RequirementSource::Protocol:
2037-
// We drop these requirements in canonical mangling signatures.
2038-
if (buildingCanonicalManglingSignature)
2039-
return;
2040-
break;
2041-
20422037
case RequirementSource::Redundant:
20432038
// The requirement was redundant, drop it.
20442039
return;
2045-
2046-
case RequirementSource::OuterScope:
2047-
assert(!buildingCanonicalManglingSignature &&
2048-
"mangling signature shouldn't have an outer scope");
2049-
break;
20502040
}
20512041

20522042
auto depTy = archetype->getDependentType(builder, false);
@@ -2072,22 +2062,15 @@ static void collectRequirements(ArchetypeBuilder &builder,
20722062
if (repTy->is<ErrorType>())
20732063
return;
20742064

2075-
if (buildingCanonicalManglingSignature) {
2076-
depTy = depTy->getCanonicalType();
2077-
repTy = repTy->getCanonicalType();
2078-
}
2079-
20802065
requirements.push_back(Requirement(kind, depTy, repTy));
20812066
});
20822067
}
20832068

20842069
GenericSignature *ArchetypeBuilder::getGenericSignature(
2085-
ArrayRef<GenericTypeParamType *> genericParamTypes,
2086-
bool buildingCanonicalManglingSignature) {
2070+
ArrayRef<GenericTypeParamType *> genericParamTypes) {
20872071
// Collect the requirements placed on the generic parameter types.
20882072
SmallVector<Requirement, 4> requirements;
2089-
collectRequirements(*this, genericParamTypes, requirements,
2090-
buildingCanonicalManglingSignature);
2073+
collectRequirements(*this, genericParamTypes, requirements);
20912074

20922075
auto sig = GenericSignature::get(genericParamTypes, requirements);
20932076
return sig;

lib/AST/GenericSignature.cpp

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -136,42 +136,6 @@ GenericSignature::getCanonicalSignature() const {
136136
CanonicalSignatureOrASTContext.get<GenericSignature*>());
137137
}
138138

139-
CanGenericSignature
140-
GenericSignature::getCanonicalManglingSignature(ModuleDecl &M) const {
141-
// Start from the elementwise-canonical signature.
142-
auto canonical = getCanonicalSignature();
143-
auto &Context = canonical->getASTContext();
144-
145-
// See if we cached the mangling signature.
146-
auto cached = Context.ManglingSignatures.find({canonical, &M});
147-
if (cached != Context.ManglingSignatures.end()) {
148-
return cached->second;
149-
}
150-
151-
// Otherwise, we need to compute it.
152-
// Dump the generic signature into an ArchetypeBuilder that will figure out
153-
// the minimal set of requirements.
154-
std::unique_ptr<ArchetypeBuilder> builder(new ArchetypeBuilder(M,
155-
Context.Diags));
156-
157-
builder->addGenericSignature(canonical,
158-
/*adoptArchetypes*/ false,
159-
/*treatRequirementsAsExplicit*/ true);
160-
161-
// Build the minimized signature.
162-
auto manglingSig =
163-
builder->getGenericSignature(canonical->getGenericParams(),
164-
/*buildingCanonicalManglingSignature*/ true);
165-
166-
CanGenericSignature canSig(manglingSig);
167-
168-
// Cache the result.
169-
Context.ManglingSignatures.insert({{canonical, &M}, canSig});
170-
Context.setArchetypeBuilder(canSig, &M, std::move(builder));
171-
172-
return canSig;
173-
}
174-
175139
ASTContext &GenericSignature::getASTContext() const {
176140
// Canonical signatures store the ASTContext directly.
177141
if (auto ctx = CanonicalSignatureOrASTContext.dyn_cast<ASTContext *>())

lib/AST/Mangle.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,8 @@ void Mangler::bindGenericParameters(CanGenericSignature sig) {
361361

362362
/// Bind the generic parameters from the given context and its parents.
363363
void Mangler::bindGenericParameters(const DeclContext *DC) {
364-
if (auto sig = DC->getGenericSignatureOfContext()) {
365-
Mod = DC->getParentModule();
366-
bindGenericParameters(sig->getCanonicalManglingSignature(*Mod));
367-
}
364+
if (auto sig = DC->getGenericSignatureOfContext())
365+
bindGenericParameters(sig->getCanonicalSignature());
368366
}
369367

370368
static OperatorFixity getDeclFixity(const ValueDecl *decl) {
@@ -496,8 +494,7 @@ Type Mangler::getDeclTypeForMangling(const ValueDecl *decl,
496494
initialParamDepth = 0;
497495
CanGenericSignature sig;
498496
if (auto gft = type->getAs<GenericFunctionType>()) {
499-
assert(Mod);
500-
sig = gft->getGenericSignature()->getCanonicalManglingSignature(*Mod);
497+
sig = gft->getGenericSignature()->getCanonicalSignature();
501498
CurGenericSignature = sig;
502499
genericParams = sig->getGenericParams();
503500
requirements = sig->getRequirements();
@@ -682,8 +679,7 @@ void Mangler::mangleGenericSignatureParts(
682679
}
683680

684681
void Mangler::mangleGenericSignature(const GenericSignature *sig) {
685-
assert(Mod);
686-
auto canSig = sig->getCanonicalManglingSignature(*Mod);
682+
auto canSig = sig->getCanonicalSignature();
687683
CurGenericSignature = canSig;
688684
mangleGenericSignatureParts(canSig->getGenericParams(), 0,
689685
canSig->getRequirements());

lib/IRGen/GenProto.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,8 @@ void PolymorphicConvention::addPseudogenericFulfillments() {
195195
void PolymorphicConvention::enumerateRequirements(const RequirementCallback &callback) {
196196
if (!Generics) return;
197197

198-
// Note that the canonical mangling signature will sometimes use
199-
// different dependent type from Generics, apparently for no good
200-
// reason.
201-
auto minimized = Generics->getCanonicalManglingSignature(M);
202-
203198
// Make a first pass to get all the type metadata.
204-
for (auto &reqt : minimized->getRequirements()) {
199+
for (auto &reqt : Generics->getRequirements()) {
205200
switch (reqt.getKind()) {
206201
// Ignore these; they don't introduce extra requirements.
207202
case RequirementKind::Superclass:
@@ -220,7 +215,7 @@ void PolymorphicConvention::enumerateRequirements(const RequirementCallback &cal
220215
}
221216

222217
// Make a second pass for all the protocol conformances.
223-
for (auto &reqt : minimized->getRequirements()) {
218+
for (auto &reqt : Generics->getRequirements()) {
224219
switch (reqt.getKind()) {
225220
// Ignore these; they don't introduce extra requirements.
226221
case RequirementKind::Superclass:
@@ -258,9 +253,6 @@ void PolymorphicConvention::enumerateUnfulfilledRequirements(const RequirementCa
258253
}
259254

260255
void PolymorphicConvention::initGenerics() {
261-
// The canonical mangling signature removes dependent types that are
262-
// equal to concrete types, but isn't necessarily parallel with
263-
// substitutions.
264256
Generics = FnType->getGenericSignature();
265257
}
266258

@@ -669,10 +661,23 @@ static unsigned getDependentTypeIndex(CanGenericSignature generics,
669661
static unsigned
670662
getProtocolConformanceIndex(CanGenericSignature generics, ModuleDecl &M,
671663
CanType type, ProtocolDecl *protocol) {
672-
auto conformsTo = generics->getConformsTo(type, M);
673-
auto it = std::find(conformsTo.begin(), conformsTo.end(), protocol);
674-
assert(it != conformsTo.end() && "didn't find protocol in conformances");
675-
return (it - conformsTo.begin());
664+
assert(type->isTypeParameter());
665+
666+
// Make a pass over all the dependent types.
667+
unsigned index = 0;
668+
for (auto reqt : generics->getRequirements()) {
669+
// Unfortunately, we can't rely on either depTy or type actually
670+
// being the marked witness type in the generic signature, so we have
671+
// to ask the generic signature whether the types are equal.
672+
if (reqt.getKind() == RequirementKind::Conformance &&
673+
generics->areSameTypeParameterInContext(reqt.getFirstType(), type, M)) {
674+
if (reqt.getSecondType()->getAnyNominal() == protocol)
675+
return index;
676+
index++;
677+
}
678+
}
679+
680+
llvm_unreachable("didn't find dependent type in all-dependent-types list");
676681
}
677682

678683
namespace {

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -957,15 +957,10 @@ void ConstraintSystem::openGeneric(
957957
bool skipProtocolSelfConstraint,
958958
ConstraintLocatorBuilder locator,
959959
llvm::DenseMap<CanType, TypeVariableType *> &replacements) {
960-
// Use the minimized constraints; we can re-derive solutions for all the
961-
// implied constraints.
962-
auto minimized =
963-
signature->getCanonicalManglingSignature(*DC->getParentModule());
964-
965960
openGeneric(innerDC,
966961
outerDC,
967-
minimized->getGenericParams(),
968-
minimized->getRequirements(),
962+
signature->getGenericParams(),
963+
signature->getRequirements(),
969964
skipProtocolSelfConstraint,
970965
locator,
971966
replacements);

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -555,10 +555,6 @@ bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
555555
llvm::errs() << "Canonical generic signature: ";
556556
sig->getCanonicalSignature()->print(llvm::errs());
557557
llvm::errs() << "\n";
558-
llvm::errs() << "Canonical generic signature for mangling: ";
559-
sig->getCanonicalManglingSignature(*func->getParentModule())
560-
->print(llvm::errs());
561-
llvm::errs() << "\n";
562558
}
563559

564560
func->setGenericSignature(sig);
@@ -767,10 +763,6 @@ GenericSignature *TypeChecker::validateGenericSignature(
767763
llvm::errs() << "Canonical generic signature: ";
768764
sig->getCanonicalSignature()->print(llvm::errs());
769765
llvm::errs() << "\n";
770-
llvm::errs() << "Canonical generic signature for mangling: ";
771-
sig->getCanonicalManglingSignature(*dc->getParentModule())
772-
->print(llvm::errs());
773-
llvm::errs() << "\n";
774766
}
775767

776768
return sig;

test/Generics/requirement_inference.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ protocol P7 : P6 {
160160
}
161161

162162
// CHECK-LABEL: P7.nestedSameType1()@
163-
// CHECK: Canonical generic signature for mangling: <τ_0_0 where τ_0_0 : P7, τ_0_0.AssocP6.Element : P6, τ_0_0.AssocP6.Element == τ_0_0.AssocP7.AssocP6.Element>
163+
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P7, τ_0_0.AssocP6.Element : P6, τ_0_0.AssocP6.Element == τ_0_0.AssocP7.AssocP6.Element>
164164
extension P7 where AssocP6.Element : P6,
165165
AssocP7.AssocP6.Element : P6,
166166
AssocP6.Element == AssocP7.AssocP6.Element {

test/Generics/superclass_constraint.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ extension P2 where Self.T : C {
6868
// CHECK-NEXT: T : C [explicit @
6969
// CHECK-NEXT: T : P3 [redundant @
7070
// CHECK-NEXT: T[.P3].T == C.T [redundant]
71-
// CHECK: Canonical generic signature for mangling: <τ_0_0 where τ_0_0 : C>
71+
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : C>
7272
func superclassConformance1<T>(t: T) where T : C, T : P3 {}
7373

7474
// CHECK: superclassConformance2
@@ -77,7 +77,7 @@ func superclassConformance1<T>(t: T) where T : C, T : P3 {}
7777
// CHECK-NEXT: T : C [explicit @
7878
// CHECK-NEXT: T : P3 [redundant @
7979
// CHECK-NEXT: T[.P3].T == C.T [redundant]
80-
// CHECK: Canonical generic signature for mangling: <τ_0_0 where τ_0_0 : C>
80+
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : C>
8181
func superclassConformance2<T>(t: T) where T : C, T : P3 {}
8282

8383
protocol P4 { }
@@ -89,5 +89,5 @@ class C2 : C, P4 { }
8989
// CHECK-NEXT: T witness marker
9090
// CHECK-NEXT: T : C2 [explicit @
9191
// CHECK-NEXT: T : P4 [redundant @
92-
// CHECK: Canonical generic signature for mangling: <τ_0_0 where τ_0_0 : C2>
92+
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : C2>
9393
func superclassConformance3<T>(t: T) where T : C, T : P4, T : C2 {}

test/SIL/Parser/default_witness_tables.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ public protocol ResilientProtocol {
1414
func defaultE()
1515
}
1616

17-
// CHECK-LABEL: sil @defaultC : $@convention(witness_method) <`Self` where `Self` : ResilientProtocol, `Self`.T : Proto> (@in_guaranteed `Self`) -> ()
17+
// CHECK-LABEL: sil @defaultC : $@convention(witness_method) <`Self` where `Self` : ResilientProtocol> (@in_guaranteed `Self`) -> ()
1818
sil @defaultC : $@convention(witness_method) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> () {
1919
bb0(%0 : $*Self):
2020
%result = tuple ()
2121
return %result : $()
2222
}
2323

2424

25-
// CHECK-LABEL: sil @defaultD : $@convention(witness_method) <`Self` where `Self` : ResilientProtocol, `Self`.T : Proto> (@in_guaranteed `Self`) -> ()
25+
// CHECK-LABEL: sil @defaultD : $@convention(witness_method) <`Self` where `Self` : ResilientProtocol> (@in_guaranteed `Self`) -> ()
2626
sil @defaultD : $@convention(witness_method) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> () {
2727
bb0(%0 : $*Self):
2828
%result = tuple ()

test/SIL/Parser/generic_signature_with_depth.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ protocol mmExt : mmCollectionType {
1818
> (_ seq: S)
1919
}
2020

21-
// CHECK-LABEL: @_TF28generic_signature_with_depth4testu0_RxS_5mmExt_S0_Wx9Generator7Element_zW_S1_S2__rFTxq__x : $@convention(thin) <EC1, EC2 where EC1 : mmExt, EC2 : mmExt, EC1.Generator : mmGeneratorType, EC2.Generator : mmGeneratorType, EC1.Generator.Element == EC2.Generator.Element> (@in EC1, @in EC2) -> @out EC1 {
22-
// CHECK: witness_method $EC1, #mmExt.extend!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : mmExt, τ_0_0.Generator : mmGeneratorType><τ_1_0 where τ_1_0 : mmSequenceType, τ_1_0.Generator : mmGeneratorType, τ_0_0.Generator.Element == τ_1_0.Generator.Element> (@in τ_1_0, @inout τ_0_0) -> ()
23-
// CHECK: apply {{%[0-9]+}}<EC1, EC2, EC1.Generator, EC2.Generator, EC1.Generator.Element>({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(witness_method) <τ_0_0 where τ_0_0 : mmExt, τ_0_0.Generator : mmGeneratorType><τ_1_0 where τ_1_0 : mmSequenceType, τ_1_0.Generator : mmGeneratorType, τ_0_0.Generator.Element == τ_1_0.Generator.Element> (@in τ_1_0, @inout τ_0_0) -> ()
21+
// CHECK-LABEL: @_TF28generic_signature_with_depth4testu0_RxS_5mmExt_S0_Wx9Generator7Element_zW_S1_S2__rFTxq__x : $@convention(thin) <EC1, EC2 where EC1 : mmExt, EC2 : mmExt, EC1.Generator.Element == EC2.Generator.Element> (@in EC1, @in EC2) -> @out EC1 {
22+
// CHECK: witness_method $EC1, #mmExt.extend!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : mmExt><τ_1_0 where τ_1_0 : mmSequenceType, τ_0_0.Generator.Element == τ_1_0.Generator.Element> (@in τ_1_0, @inout τ_0_0) -> ()
23+
// CHECK: apply {{%[0-9]+}}<EC1, EC2, EC1.Generator, EC2.Generator, EC1.Generator.Element>({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(witness_method) <τ_0_0 where τ_0_0 : mmExt><τ_1_0 where τ_1_0 : mmSequenceType, τ_0_0.Generator.Element == τ_1_0.Generator.Element> (@in τ_1_0, @inout τ_0_0) -> ()
2424

2525
func test<
2626
EC1 : mmExt,

0 commit comments

Comments
 (0)