33
33
#include " llvm/ADT/SetVector.h"
34
34
#include " llvm/ADT/SmallPtrSet.h"
35
35
#include " llvm/ADT/SmallString.h"
36
+ #include " llvm/ADT/Statistic.h"
36
37
#include " llvm/ADT/STLExtras.h"
37
38
#include " llvm/Support/raw_ostream.h"
38
39
#include < algorithm>
39
40
40
41
using namespace swift ;
41
42
using llvm::DenseMap;
42
43
44
+ // / Define this to 1 to enable expensive assertions.
45
+ #define SWIFT_GSB_EXPENSIVE_ASSERTIONS 0
46
+
43
47
namespace {
44
48
typedef GenericSignatureBuilder::RequirementSource RequirementSource;
45
49
typedef GenericSignatureBuilder::FloatingRequirementSource
@@ -54,6 +58,18 @@ namespace {
54
58
55
59
} // end anonymous namespace
56
60
61
+ #define DEBUG_TYPE " Generic signature builder"
62
+ STATISTIC (NumPotentialArchetypes, " # of potential archetypes" );
63
+ STATISTIC (NumConformances, " # of conformances tracked" );
64
+ STATISTIC (NumConformanceConstraints, " # of conformance constraints tracked" );
65
+ STATISTIC (NumSameTypeConstraints, " # of same-type constraints tracked" );
66
+ STATISTIC (NumConcreteTypeConstraints,
67
+ " # of same-type-to-concrete constraints tracked" );
68
+ STATISTIC (NumSuperclassConstraints, " # of superclass constraints tracked" );
69
+ STATISTIC (NumLayoutConstraints, " # of layout constraints tracked" );
70
+ STATISTIC (NumSelfDerived, " # of self-derived constraints removed" );
71
+ STATISTIC (NumRecursive, " # of recursive types we bail out on" );
72
+
57
73
struct GenericSignatureBuilder ::Implementation {
58
74
// / Function used to look up conformances.
59
75
std::function<GenericFunction> LookupConformance;
@@ -988,10 +1004,12 @@ bool FloatingRequirementSource::isRecursive(
988
1004
->getAffectedPotentialArchetype ();
989
1005
while (auto parent = pa->getParent ()) {
990
1006
if (pa->getNestedName () == nestedName) {
991
- if (++grossCount > 4 ) return true ;
1007
+ if (++grossCount > 4 ) {
1008
+ ++NumRecursive;
1009
+ return true ;
1010
+ }
992
1011
}
993
1012
994
-
995
1013
pa = parent;
996
1014
}
997
1015
}
@@ -1000,6 +1018,8 @@ bool FloatingRequirementSource::isRecursive(
1000
1018
}
1001
1019
1002
1020
GenericSignatureBuilder::PotentialArchetype::~PotentialArchetype () {
1021
+ ++NumPotentialArchetypes;
1022
+
1003
1023
for (const auto &nested : NestedTypes) {
1004
1024
for (auto pa : nested.second ) {
1005
1025
if (pa != this )
@@ -1218,6 +1238,7 @@ const RequirementSource *GenericSignatureBuilder::resolveSuperConformance(
1218
1238
superclassSource =
1219
1239
superclassSource->viaSuperclass (*this , conformance->getConcrete ());
1220
1240
paEquivClass->conformsTo [proto].push_back ({pa, proto, superclassSource});
1241
+ ++NumConformanceConstraints;
1221
1242
return superclassSource;
1222
1243
}
1223
1244
@@ -1295,11 +1316,14 @@ bool PotentialArchetype::addConformance(ProtocolDecl *proto,
1295
1316
if (known != equivClass->conformsTo .end ()) {
1296
1317
// We already knew about this conformance; record this specific constraint.
1297
1318
known->second .push_back ({this , proto, source});
1319
+ ++NumConformanceConstraints;
1298
1320
return false ;
1299
1321
}
1300
1322
1301
1323
// Add the conformance along with this constraint.
1302
1324
equivClass->conformsTo [proto].push_back ({this , proto, source});
1325
+ ++NumConformanceConstraints;
1326
+ ++NumConformances;
1303
1327
1304
1328
// Determine whether there is a superclass constraint where the
1305
1329
// superclass conforms to this protocol.
@@ -1505,7 +1529,7 @@ PotentialArchetype *PotentialArchetype::getArchetypeAnchor(
1505
1529
anchor = pa;
1506
1530
}
1507
1531
1508
- #ifndef NDEBUG
1532
+ #if SWIFT_GSB_EXPENSIVE_ASSERTIONS
1509
1533
// Make sure that we did, in fact, get one that is better than all others.
1510
1534
for (auto pa : anchor->getEquivalenceClassMembers ()) {
1511
1535
assert ((pa == anchor || compareDependentTypes (&anchor, &pa) < 0 ) &&
@@ -2716,6 +2740,7 @@ ConstraintResult GenericSignatureBuilder::addLayoutRequirementDirect(
2716
2740
2717
2741
// Record this layout constraint.
2718
2742
equivClass->layoutConstraints .push_back ({PAT, Layout, Source});
2743
+ ++NumLayoutConstraints;
2719
2744
2720
2745
// Update the layout in the equivalence class, if we didn't have one already.
2721
2746
if (!equivClass->layout )
@@ -2840,6 +2865,7 @@ ConstraintResult GenericSignatureBuilder::addSuperclassRequirementDirect(
2840
2865
// Record the constraint.
2841
2866
T->getOrCreateEquivalenceClass ()->superclassConstraints
2842
2867
.push_back (ConcreteConstraint{T, superclass, source});
2868
+ ++NumSuperclassConstraints;
2843
2869
2844
2870
// Update the equivalence class with the constraint.
2845
2871
updateSuperclass (T, superclass, source);
@@ -2976,11 +3002,13 @@ void GenericSignatureBuilder::PotentialArchetype::addSameTypeConstraint(
2976
3002
// Update the same-type constraints of this PA to reference the other PA.
2977
3003
getOrCreateEquivalenceClass ()->sameTypeConstraints [this ]
2978
3004
.push_back ({this , otherPA, source});
3005
+ ++NumSameTypeConstraints;
2979
3006
2980
3007
if (this != otherPA) {
2981
3008
// Update the same-type constraints of the other PA to reference this PA.
2982
3009
otherPA->getOrCreateEquivalenceClass ()->sameTypeConstraints [otherPA]
2983
3010
.push_back ({otherPA, this , source});
3011
+ ++NumSameTypeConstraints;
2984
3012
}
2985
3013
}
2986
3014
@@ -3108,6 +3136,7 @@ ConstraintResult GenericSignatureBuilder::addSameTypeRequirementToConcrete(
3108
3136
// Record the concrete type and its source.
3109
3137
equivClass->concreteTypeConstraints .push_back (
3110
3138
ConcreteConstraint{T, Concrete, Source});
3139
+ ++NumConcreteTypeConstraints;
3111
3140
3112
3141
// If we've already been bound to a type, match that type.
3113
3142
if (equivClass->concreteType ) {
@@ -3151,6 +3180,7 @@ ConstraintResult GenericSignatureBuilder::addSameTypeRequirementToConcrete(
3151
3180
? conformance->getConcrete ()
3152
3181
: nullptr );
3153
3182
equivClass->conformsTo [protocol].push_back ({T, protocol, concreteSource});
3183
+ ++NumConformanceConstraints;
3154
3184
}
3155
3185
3156
3186
// Eagerly resolve any existing nested types to their concrete forms (others
@@ -4107,8 +4137,10 @@ namespace {
4107
4137
[&](const Constraint<T> &constraint) {
4108
4138
bool derivedViaConcrete;
4109
4139
if (constraint.source ->isSelfDerivedSource (
4110
- constraint.archetype , derivedViaConcrete))
4140
+ constraint.archetype , derivedViaConcrete)) {
4141
+ ++NumSelfDerived;
4111
4142
return true ;
4143
+ }
4112
4144
4113
4145
if (!derivedViaConcrete)
4114
4146
return false ;
@@ -4122,6 +4154,7 @@ namespace {
4122
4154
if (!remainingConcrete)
4123
4155
remainingConcrete = constraint;
4124
4156
4157
+ ++NumSelfDerived;
4125
4158
return true ;
4126
4159
}),
4127
4160
constraints.end ());
@@ -4274,15 +4307,19 @@ void GenericSignatureBuilder::checkConformanceConstraints(
4274
4307
bool derivedViaConcrete;
4275
4308
if (constraint.source ->isSelfDerivedConformance (
4276
4309
constraint.archetype , entry.first ,
4277
- derivedViaConcrete))
4310
+ derivedViaConcrete)) {
4311
+ ++NumSelfDerived;
4278
4312
return true ;
4313
+ }
4279
4314
4280
4315
if (!derivedViaConcrete)
4281
4316
return false ;
4282
4317
4283
4318
// Drop derived-via-concrete requirements.
4284
4319
if (!remainingConcrete)
4285
4320
remainingConcrete = constraint;
4321
+
4322
+ ++NumSelfDerived;
4286
4323
return true ;
4287
4324
}),
4288
4325
entry.second .end ());
0 commit comments