Skip to content

Commit b2d2b01

Browse files
authored
Merge pull request #24561 from DougGregor/opaque-generic-sig-arena-5.1
[5.1] [AST] Allocate GenericSignature(Builders) in the arena
2 parents 215db7e + 13824e9 commit b2d2b01

File tree

5 files changed

+106
-26
lines changed

5 files changed

+106
-26
lines changed

include/swift/AST/GenericSignature.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,12 @@ class alignas(1 << TypeAlignInBits) GenericSignature final
312312
/// generic parameters to themselves.
313313
SubstitutionMap getIdentitySubstitutionMap() const;
314314

315+
/// Whether this generic signature involves a type variable.
316+
bool hasTypeVariable() const;
317+
318+
/// Whether the given set of requirements involves a type variable.
319+
static bool hasTypeVariable(ArrayRef<Requirement> requirements);
320+
315321
static void Profile(llvm::FoldingSetNodeID &ID,
316322
TypeArrayView<GenericTypeParamType> genericParams,
317323
ArrayRef<Requirement> requirements);

lib/AST/ASTContext.cpp

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -259,16 +259,6 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
259259
/// Stores information about lazy deserialization of various declarations.
260260
llvm::DenseMap<const DeclContext *, LazyContextData *> LazyContexts;
261261

262-
/// Stored generic signature builders for canonical generic signatures.
263-
llvm::DenseMap<GenericSignature *, std::unique_ptr<GenericSignatureBuilder>>
264-
GenericSignatureBuilders;
265-
266-
/// Canonical generic environments for canonical generic signatures.
267-
///
268-
/// The keys are the generic signature builders in \c GenericSignatureBuilders.
269-
llvm::DenseMap<GenericSignatureBuilder *, GenericEnvironment *>
270-
CanonicalGenericEnvironments;
271-
272262
/// The single-parameter generic signature with no constraints, <T>.
273263
CanGenericSignature SingleGenericParameterSignature;
274264

@@ -334,6 +324,19 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
334324
llvm::FoldingSet<LayoutConstraintInfo> LayoutConstraints;
335325
llvm::FoldingSet<OpaqueTypeArchetypeType> OpaqueArchetypes;
336326

327+
llvm::FoldingSet<GenericSignature> GenericSignatures;
328+
329+
/// Stored generic signature builders for canonical generic signatures.
330+
llvm::DenseMap<GenericSignature *, std::unique_ptr<GenericSignatureBuilder>>
331+
GenericSignatureBuilders;
332+
333+
/// Canonical generic environments for canonical generic signatures.
334+
///
335+
/// The keys are the generic signature builders in
336+
/// \c GenericSignatureBuilders.
337+
llvm::DenseMap<GenericSignatureBuilder *, GenericEnvironment *>
338+
CanonicalGenericEnvironments;
339+
337340
/// The set of function types.
338341
llvm::FoldingSet<FunctionType> FunctionTypes;
339342

@@ -384,7 +387,6 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
384387
llvm::FoldingSet<SILBoxType> SILBoxTypes;
385388
llvm::DenseMap<BuiltinIntegerWidth, BuiltinIntegerType*> IntegerTypes;
386389
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
387-
llvm::FoldingSet<GenericSignature> GenericSignatures;
388390
llvm::FoldingSet<DeclName::CompoundDeclName> CompoundNames;
389391
llvm::DenseMap<UUID, OpenedArchetypeType *> OpenedExistentialArchetypes;
390392

@@ -1506,34 +1508,50 @@ void ASTContext::getVisibleTopLevelClangModules(
15061508
collectAllModules(Modules);
15071509
}
15081510

1511+
static AllocationArena getArena(GenericSignature *genericSig) {
1512+
if (!genericSig)
1513+
return AllocationArena::Permanent;
1514+
1515+
if (genericSig->hasTypeVariable())
1516+
return AllocationArena::ConstraintSolver;
1517+
1518+
return AllocationArena::Permanent;
1519+
}
1520+
15091521
void ASTContext::registerGenericSignatureBuilder(
15101522
GenericSignature *sig,
15111523
GenericSignatureBuilder &&builder) {
15121524
auto canSig = sig->getCanonicalSignature();
1513-
auto known = getImpl().GenericSignatureBuilders.find(canSig);
1514-
if (known != getImpl().GenericSignatureBuilders.end()) {
1525+
auto arena = getArena(sig);
1526+
auto &genericSignatureBuilders =
1527+
getImpl().getArena(arena).GenericSignatureBuilders;
1528+
auto known = genericSignatureBuilders.find(canSig);
1529+
if (known != genericSignatureBuilders.end()) {
15151530
++NumRegisteredGenericSignatureBuildersAlready;
15161531
return;
15171532
}
15181533

15191534
++NumRegisteredGenericSignatureBuilders;
1520-
getImpl().GenericSignatureBuilders[canSig] =
1535+
genericSignatureBuilders[canSig] =
15211536
llvm::make_unique<GenericSignatureBuilder>(std::move(builder));
15221537
}
15231538

15241539
GenericSignatureBuilder *ASTContext::getOrCreateGenericSignatureBuilder(
15251540
CanGenericSignature sig) {
15261541
// Check whether we already have a generic signature builder for this
15271542
// signature and module.
1528-
auto known = getImpl().GenericSignatureBuilders.find(sig);
1529-
if (known != getImpl().GenericSignatureBuilders.end())
1543+
auto arena = getArena(sig);
1544+
auto &genericSignatureBuilders =
1545+
getImpl().getArena(arena).GenericSignatureBuilders;
1546+
auto known = genericSignatureBuilders.find(sig);
1547+
if (known != genericSignatureBuilders.end())
15301548
return known->second.get();
15311549

15321550
// Create a new generic signature builder with the given signature.
15331551
auto builder = new GenericSignatureBuilder(*this);
15341552

15351553
// Store this generic signature builder (no generic environment yet).
1536-
getImpl().GenericSignatureBuilders[sig] =
1554+
genericSignatureBuilders[sig] =
15371555
std::unique_ptr<GenericSignatureBuilder>(builder);
15381556

15391557
builder->addGenericSignature(sig);
@@ -1604,12 +1622,16 @@ GenericSignatureBuilder *ASTContext::getOrCreateGenericSignatureBuilder(
16041622
GenericEnvironment *ASTContext::getOrCreateCanonicalGenericEnvironment(
16051623
GenericSignatureBuilder *builder,
16061624
GenericSignature *sig) {
1607-
auto known = getImpl().CanonicalGenericEnvironments.find(builder);
1608-
if (known != getImpl().CanonicalGenericEnvironments.end())
1625+
auto arena = getArena(sig);
1626+
auto &canonicalGenericEnvironments =
1627+
getImpl().getArena(arena).CanonicalGenericEnvironments;
1628+
1629+
auto known = canonicalGenericEnvironments.find(builder);
1630+
if (known != canonicalGenericEnvironments.end())
16091631
return known->second;
16101632

16111633
auto env = sig->createGenericEnvironment();
1612-
getImpl().CanonicalGenericEnvironments[builder] = env;
1634+
canonicalGenericEnvironments[builder] = env;
16131635
return env;
16141636
}
16151637

@@ -4608,10 +4630,14 @@ GenericSignature::get(TypeArrayView<GenericTypeParamType> params,
46084630
llvm::FoldingSetNodeID ID;
46094631
GenericSignature::Profile(ID, params, requirements);
46104632

4633+
auto arena = GenericSignature::hasTypeVariable(requirements)
4634+
? AllocationArena::ConstraintSolver
4635+
: AllocationArena::Permanent;
4636+
46114637
auto &ctx = getASTContext(params, requirements);
46124638
void *insertPos;
4613-
if (auto *sig = ctx.getImpl().GenericSignatures.FindNodeOrInsertPos(ID,
4614-
insertPos)) {
4639+
if (auto *sig = ctx.getImpl().getArena(arena).GenericSignatures
4640+
.FindNodeOrInsertPos(ID, insertPos)) {
46154641
if (isKnownCanonical)
46164642
sig->CanonicalSignatureOrASTContext = &ctx;
46174643

@@ -4624,7 +4650,7 @@ GenericSignature::get(TypeArrayView<GenericTypeParamType> params,
46244650
void *mem = ctx.Allocate(bytes, alignof(GenericSignature));
46254651
auto newSig = new (mem) GenericSignature(params, requirements,
46264652
isKnownCanonical);
4627-
ctx.getImpl().GenericSignatures.InsertNode(newSig, insertPos);
4653+
ctx.getImpl().getArena(arena).GenericSignatures.InsertNode(newSig, insertPos);
46284654
return newSig;
46294655
}
46304656

lib/AST/GenericSignature.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,3 +1042,28 @@ unsigned GenericSignature::getGenericParamOrdinal(GenericTypeParamType *param) {
10421042
.findIndexIn(getGenericParams());
10431043
}
10441044

1045+
bool GenericSignature::hasTypeVariable() const {
1046+
return hasTypeVariable(getRequirements());
1047+
}
1048+
1049+
bool GenericSignature::hasTypeVariable(ArrayRef<Requirement> requirements) {
1050+
for (const auto &req : requirements) {
1051+
if (req.getFirstType()->hasTypeVariable())
1052+
return true;
1053+
1054+
switch (req.getKind()) {
1055+
case RequirementKind::Layout:
1056+
break;
1057+
1058+
case RequirementKind::Conformance:
1059+
case RequirementKind::SameType:
1060+
case RequirementKind::Superclass:
1061+
if (req.getSecondType()->hasTypeVariable())
1062+
return true;
1063+
break;
1064+
}
1065+
}
1066+
1067+
return false;
1068+
}
1069+

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5426,9 +5426,15 @@ namespace {
54265426
ArrayRef<Constraint<T>> constraints,
54275427
llvm::function_ref<bool(const Constraint<T> &)>
54285428
isSuitableRepresentative) {
5429+
Optional<Constraint<T>> fallbackConstraint;
5430+
54295431
// Find a representative constraint.
54305432
Optional<Constraint<T>> representativeConstraint;
54315433
for (const auto &constraint : constraints) {
5434+
// Make sure we have a constraint to fall back on.
5435+
if (!fallbackConstraint)
5436+
fallbackConstraint = constraint;
5437+
54325438
// If this isn't a suitable representative constraint, ignore it.
54335439
if (!isSuitableRepresentative(constraint))
54345440
continue;
@@ -5479,7 +5485,8 @@ namespace {
54795485
representativeConstraint = constraint;
54805486
}
54815487

5482-
return representativeConstraint;
5488+
return representativeConstraint ? representativeConstraint
5489+
: fallbackConstraint;
54835490
}
54845491
} // end anonymous namespace
54855492

@@ -7018,9 +7025,11 @@ void GenericSignatureBuilder::checkConcreteTypeConstraints(
70187025
if (concreteType->isEqual(equivClass->concreteType))
70197026
return ConstraintRelation::Redundant;
70207027

7021-
// If either has a type parameter, call them unrelated.
7028+
// If either has a type parameter or type variable, call them unrelated.
70227029
if (concreteType->hasTypeParameter() ||
7023-
equivClass->concreteType->hasTypeParameter())
7030+
equivClass->concreteType->hasTypeParameter() ||
7031+
concreteType->hasTypeVariable() ||
7032+
equivClass->concreteType->hasTypeVariable())
70247033
return ConstraintRelation::Unrelated;
70257034

70267035
return ConstraintRelation::Conflicting;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend -emit-ir -o /dev/null %s
2+
3+
protocol P {
4+
associatedtype AT
5+
func foo() -> AT
6+
}
7+
8+
struct X<C1: Collection, C2: Collection, T>: P
9+
where C1.Element == C2.Element
10+
{
11+
func foo() -> some P {
12+
return self
13+
}
14+
}

0 commit comments

Comments
 (0)