@@ -107,8 +107,6 @@ STATISTIC(NumDelayedRequirementUnresolved,
107
107
" Delayed requirements left unresolved" );
108
108
STATISTIC (NumConditionalRequirementsAdded,
109
109
" # of conditional requirements added" );
110
- STATISTIC (NumComponentsCollapsedViaRewriting,
111
- " # of same-type components collapsed via term rewriting" );
112
110
113
111
namespace {
114
112
@@ -412,10 +410,6 @@ namespace {
412
410
BaseIterator base;
413
411
BaseIterator baseEnd;
414
412
415
- void advance () {
416
- ++base;
417
- }
418
-
419
413
public:
420
414
using difference_type = ptrdiff_t ;
421
415
using value_type = EquivalenceClassVizNode;
@@ -426,7 +420,6 @@ namespace {
426
420
EquivalenceClassVizIterator (EquivalenceClassVizNode node,
427
421
BaseIterator base, BaseIterator baseEnd)
428
422
: node(node), base(base), baseEnd(baseEnd) {
429
- advance ();
430
423
}
431
424
432
425
BaseIterator &getBase () { return base; }
@@ -438,7 +431,6 @@ namespace {
438
431
439
432
EquivalenceClassVizIterator& operator ++() {
440
433
++getBase ();
441
- advance ();
442
434
return *this ;
443
435
}
444
436
@@ -2157,19 +2149,42 @@ Type EquivalenceClass::getAnchor(
2157
2149
}
2158
2150
2159
2151
// Form the anchor.
2152
+ bool updatedAnchor = false ;
2160
2153
for (auto member : members) {
2161
2154
auto anchorType =
2162
2155
builder.getCanonicalTypeParameter (member->getDependentType (genericParams));
2163
2156
if (!anchorType) continue ;
2164
2157
2158
+ #ifndef NDEBUG
2159
+ // Check that we get consistent results from all of the anchors.
2160
+ if (updatedAnchor) {
2161
+ assert (anchorType->isEqual (archetypeAnchorCache.anchor ) &&
2162
+ " Inconsistent anchor computation" );
2163
+ continue ;
2164
+ }
2165
+ #endif
2166
+
2165
2167
// Record the cache miss and update the cache.
2166
2168
++NumArchetypeAnchorCacheMisses;
2167
2169
archetypeAnchorCache.anchor = anchorType;
2168
2170
archetypeAnchorCache.lastGeneration = builder.Impl ->Generation ;
2169
- return substAnchor ();
2171
+ updatedAnchor = true ;
2172
+
2173
+ #if NDEBUG
2174
+ break ;
2175
+ #endif
2170
2176
}
2171
2177
2172
- llvm_unreachable (" Unable to compute anchor" );
2178
+ // FIXME: Once we are no longer constructing potential archetypes with
2179
+ // concrete nested types, we can turn this into assert(updatedAnchor);
2180
+ if (!updatedAnchor) {
2181
+ ++NumArchetypeAnchorCacheMisses;
2182
+ archetypeAnchorCache.anchor =
2183
+ builder.getCanonicalTypeParameter (members.front ()->getDependentType ({ }));
2184
+ archetypeAnchorCache.lastGeneration = builder.Impl ->Generation ;
2185
+ }
2186
+
2187
+ return substAnchor ();
2173
2188
}
2174
2189
2175
2190
Type EquivalenceClass::getTypeInContext (GenericSignatureBuilder &builder,
@@ -3299,17 +3314,19 @@ RewriteTreeNode::bestMatch(GenericParamKey base, RelativeRewritePath path,
3299
3314
[&](unsigned length, RewritePath path) {
3300
3315
// Determine how much of the original path will be replaced by the rewrite.
3301
3316
unsigned adjustedLength = length;
3317
+ bool changesBase = false ;
3302
3318
if (auto newBase = path.getBase ()) {
3303
3319
adjustedLength += prefixLength;
3304
3320
3305
3321
// If the base is unchanged, make sure we're reducing the length.
3306
- if (*newBase == base && adjustedLength <= path.getPath ().size ())
3322
+ changesBase = *newBase != base;
3323
+ if (!changesBase && adjustedLength <= path.getPath ().size ())
3307
3324
return ;
3308
3325
}
3309
3326
3310
- if (adjustedLength == 0 ) return ;
3327
+ if (adjustedLength == 0 && !changesBase ) return ;
3311
3328
3312
- if (adjustedLength > bestAdjustedLength ||
3329
+ if (adjustedLength > bestAdjustedLength || !best ||
3313
3330
(adjustedLength == bestAdjustedLength &&
3314
3331
path.compare (best->second ) < 0 )) {
3315
3332
best = { length, path };
@@ -3407,39 +3424,29 @@ GenericSignatureBuilder::Implementation::getOrCreateRewriteTreeRoot(
3407
3424
return root;
3408
3425
}
3409
3426
3410
- void GenericSignatureBuilder::addSameTypeRewriteRule (PotentialArchetype *pa1,
3411
- PotentialArchetype *pa2){
3412
- auto pathOpt1 = RewritePath::createPath (pa1);
3413
- if (!pathOpt1) return ;
3414
-
3415
- auto pathOpt2 = RewritePath::createPath (pa2);
3416
- if (!pathOpt2) return ;
3417
-
3418
- auto path1 = std::move (pathOpt1).getValue ();
3419
- auto path2 = std::move (pathOpt2).getValue ();
3427
+ void GenericSignatureBuilder::addSameTypeRewriteRule (
3428
+ EquivalenceClass *equivClass,
3429
+ PotentialArchetype *otherPA){
3430
+ // Simplify both sides in the hope of uncovering a common path.
3431
+ Type simplifiedType1 = equivClass->getAnchor (*this , { });
3432
+ if (!simplifiedType1) return ;
3420
3433
3421
- // Look for a common path.
3422
- auto prefix = path1.commonPath (path2);
3423
-
3424
- // If we didn't find a common path, try harder.
3425
- Type simplifiedType1;
3426
3434
Type simplifiedType2;
3427
- if (!prefix) {
3428
- // Simplify both sides in the hope of uncovering a common path.
3429
- simplifiedType1 = getCanonicalTypeParameter (pa1-> getDependentType ({ }));
3430
- simplifiedType2 = getCanonicalTypeParameter (pa2 ->getDependentType ({ }));
3431
- if (simplifiedType1-> isEqual ( simplifiedType2) ) return ;
3435
+ if (auto otherEquivClass = otherPA-> getEquivalenceClassIfPresent ())
3436
+ simplifiedType2 = otherEquivClass-> getAnchor (* this , { });
3437
+ else
3438
+ simplifiedType2 = getCanonicalTypeParameter (otherPA ->getDependentType ({ }));
3439
+ if (! simplifiedType2) return ;
3432
3440
3433
- // Create new paths from the simplified types.
3434
- path1 = *RewritePath::createPath (simplifiedType1);
3435
- path2 = *RewritePath::createPath (simplifiedType2);
3441
+ // We already effectively have this rewrite rule.
3442
+ if (simplifiedType1->isEqual (simplifiedType2)) return ;
3436
3443
3437
- // Find a common path.
3438
- prefix = path1.commonPath (path2);
3439
- }
3444
+ auto path1 = *RewritePath::createPath (simplifiedType1);
3445
+ auto path2 = *RewritePath::createPath (simplifiedType2);
3440
3446
3441
- // When we have a common prefix, form a rewrite rule using relative paths.
3442
- if (prefix) {
3447
+ // Look for a common prefix. When we have one, form a rewrite rule using
3448
+ // relative paths.
3449
+ if (auto prefix = path1.commonPath (path2)) {
3443
3450
// Find the better relative rewrite path.
3444
3451
RelativeRewritePath relPath1
3445
3452
= path1.getPath ().slice (prefix->getPath ().size ());
@@ -3475,11 +3482,11 @@ void GenericSignatureBuilder::addSameTypeRewriteRule(PotentialArchetype *pa1,
3475
3482
Type firstBase =
3476
3483
GenericTypeParamType::get (path1.getBase ()->Depth , path1.getBase ()->Index ,
3477
3484
getASTContext ());
3478
- auto equivClass =
3485
+ auto baseEquivClass =
3479
3486
resolveEquivalenceClass (firstBase, ArchetypeResolutionKind::WellFormed);
3480
- assert (equivClass && " Base cannot be resolved?" );
3487
+ assert (baseEquivClass && " Base cannot be resolved?" );
3481
3488
3482
- auto root = Impl->getOrCreateRewriteTreeRoot (equivClass );
3489
+ auto root = Impl->getOrCreateRewriteTreeRoot (baseEquivClass );
3483
3490
root->addRewriteRule (path1.getPath (), path2);
3484
3491
}
3485
3492
@@ -3842,6 +3849,7 @@ bool GenericSignatureBuilder::addGenericParameterRequirements(
3842
3849
void GenericSignatureBuilder::addGenericParameter (GenericTypeParamType *GenericParam) {
3843
3850
GenericParamKey Key (GenericParam);
3844
3851
auto params = getGenericParams ();
3852
+ (void )params;
3845
3853
assert (params.empty () ||
3846
3854
((Key.Depth == params.back ()->getDepth () &&
3847
3855
Key.Index == params.back ()->getIndex () + 1 ) ||
@@ -4544,9 +4552,6 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
4544
4552
PotentialArchetype *OrigT2,
4545
4553
const RequirementSource *Source)
4546
4554
{
4547
- // Add a rewrite rule based on the given same-type constraint.
4548
- addSameTypeRewriteRule (OrigT1, OrigT2);
4549
-
4550
4555
// Record the same-type constraint, and bail out if it was already known.
4551
4556
if (!OrigT1->getOrCreateEquivalenceClass (*this )
4552
4557
->recordSameTypeConstraint (OrigT1, OrigT2, Source))
@@ -4566,10 +4571,12 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
4566
4571
std::swap (OrigT1, OrigT2);
4567
4572
}
4568
4573
4569
- // Merge the equivalence classes .
4574
+ // Add a rewrite rule to map T2 down to the anchor .
4570
4575
auto equivClass = T1->getOrCreateEquivalenceClass (*this );
4571
- equivClass-> modified (* this );
4576
+ addSameTypeRewriteRule (equivClass, T2 );
4572
4577
4578
+ // Merge the equivalence classes.
4579
+ equivClass->modified (*this );
4573
4580
auto equivClass1Members = equivClass->members ;
4574
4581
auto equivClass2Members = T2->getEquivalenceClassMembers ();
4575
4582
for (auto equiv : equivClass2Members)
0 commit comments