Skip to content

Commit 41ff058

Browse files
committed
[GSB] Collapse structurally-equivalent potential archetypes.
When there are to "structurally" equivalent potential archetypes in different components of an equivalence class, as determined by their nested-name structure, collapse the two components. This addresses the remaining known issues due to the eager explosion of potential archetypes in the generic signature builder.
1 parent 0d53a73 commit 41ff058

File tree

1 file changed

+59
-2
lines changed

1 file changed

+59
-2
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5356,6 +5356,53 @@ static void collapseSameTypeComponentsThroughDelayedRequirements(
53565356
collapsedParents.end());
53575357
}
53585358

5359+
/// Check whether two potential archetypes "structurally" match, e.g.,
5360+
/// the names match up to the root (which must match).
5361+
static bool potentialArchetypesStructurallyMatch(PotentialArchetype *pa1,
5362+
PotentialArchetype *pa2) {
5363+
auto parent1 = pa1->getParent();
5364+
auto parent2 = pa2->getParent();
5365+
if (!parent1 && !parent2)
5366+
return pa1->getGenericParamKey() == pa2->getGenericParamKey();
5367+
5368+
// Check for depth mismatch.
5369+
if (static_cast<bool>(parent1) != static_cast<bool>(parent2))
5370+
return false;
5371+
5372+
// Check names.
5373+
if (pa1->getNestedName() != pa2->getNestedName())
5374+
return false;
5375+
5376+
return potentialArchetypesStructurallyMatch(parent1, parent2);
5377+
}
5378+
5379+
/// Look for structurally-equivalent types within the given equivalence class,
5380+
/// collapsing their components.
5381+
static void collapseStructurallyEquivalentSameTypeComponents(
5382+
EquivalenceClass *equivClass,
5383+
llvm::SmallDenseMap<PotentialArchetype *, unsigned> &componentOf,
5384+
SmallVectorImpl<unsigned> &collapsedParents,
5385+
unsigned &remainingComponents) {
5386+
for (unsigned i : indices(equivClass->members)) {
5387+
auto pa1 = equivClass->members[i];
5388+
auto rep1 = findRepresentative(collapsedParents, componentOf[pa1]);
5389+
for (unsigned j : indices(equivClass->members).slice(i + 1)) {
5390+
auto pa2 = equivClass->members[j];
5391+
auto rep2 = findRepresentative(collapsedParents, componentOf[pa2]);
5392+
if (rep1 == rep2) continue;
5393+
5394+
auto depth = pa1->getNestingDepth();
5395+
if (depth < 2 || depth != pa2->getNestingDepth()) continue;
5396+
5397+
if (potentialArchetypesStructurallyMatch(pa1, pa2) &&
5398+
unionSets(collapsedParents, rep1, rep2)) {
5399+
--remainingComponents;
5400+
rep1 = findRepresentative(collapsedParents, componentOf[pa1]);
5401+
}
5402+
}
5403+
}
5404+
}
5405+
53595406
/// Collapse same-type components within an equivalence class, minimizing the
53605407
/// number of requirements required to express the equivalence class.
53615408
static void collapseSameTypeComponents(
@@ -5410,9 +5457,19 @@ static void collapseSameTypeComponents(
54105457
--remainingComponents;
54115458
}
54125459

5413-
// Collapse same-type components by looking at the delayed requirements.
5414-
collapseSameTypeComponentsThroughDelayedRequirements(
5460+
if (remainingComponents > 1) {
5461+
// Collapse same-type components by looking at the delayed requirements.
5462+
collapseSameTypeComponentsThroughDelayedRequirements(
54155463
builder, equivClass, componentOf, collapsedParents, remainingComponents);
5464+
}
5465+
5466+
if (remainingComponents > 1) {
5467+
// Collapse structurally-equivalent components.
5468+
collapseStructurallyEquivalentSameTypeComponents(equivClass,
5469+
componentOf,
5470+
collapsedParents,
5471+
remainingComponents);
5472+
}
54165473

54175474
// If needed, collapse the same-type components merged by a derived
54185475
// nested-type-name-match edge.

0 commit comments

Comments
 (0)