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>
@@ -54,6 +55,18 @@ namespace {
54
55
55
56
} // end anonymous namespace
56
57
58
+ #define DEBUG_TYPE " Generic signature builder"
59
+ STATISTIC (NumPotentialArchetypes, " # of potential archetypes" );
60
+ STATISTIC (NumConformances, " # of conformances tracked" );
61
+ STATISTIC (NumConformanceConstraints, " # of conformance constraints tracked" );
62
+ STATISTIC (NumSameTypeConstraints, " # of same-type constraints tracked" );
63
+ STATISTIC (NumConcreteTypeConstraints,
64
+ " # of same-type-to-concrete constraints tracked" );
65
+ STATISTIC (NumSuperclassConstraints, " # of superclass constraints tracked" );
66
+ STATISTIC (NumLayoutConstraints, " # of layout constraints tracked" );
67
+ STATISTIC (NumSelfDerived, " # of self-derived constraints removed" );
68
+ STATISTIC (NumRecursive, " # of recursive types we bail out on" );
69
+
57
70
struct GenericSignatureBuilder ::Implementation {
58
71
// / Function used to look up conformances.
59
72
std::function<GenericFunction> LookupConformance;
@@ -988,10 +1001,12 @@ bool FloatingRequirementSource::isRecursive(
988
1001
->getAffectedPotentialArchetype ();
989
1002
while (auto parent = pa->getParent ()) {
990
1003
if (pa->getNestedName () == nestedName) {
991
- if (++grossCount > 4 ) return true ;
1004
+ if (++grossCount > 4 ) {
1005
+ ++NumRecursive;
1006
+ return true ;
1007
+ }
992
1008
}
993
1009
994
-
995
1010
pa = parent;
996
1011
}
997
1012
}
@@ -1000,6 +1015,8 @@ bool FloatingRequirementSource::isRecursive(
1000
1015
}
1001
1016
1002
1017
GenericSignatureBuilder::PotentialArchetype::~PotentialArchetype () {
1018
+ ++NumPotentialArchetypes;
1019
+
1003
1020
for (const auto &nested : NestedTypes) {
1004
1021
for (auto pa : nested.second ) {
1005
1022
if (pa != this )
@@ -1218,6 +1235,7 @@ const RequirementSource *GenericSignatureBuilder::resolveSuperConformance(
1218
1235
superclassSource =
1219
1236
superclassSource->viaSuperclass (*this , conformance->getConcrete ());
1220
1237
paEquivClass->conformsTo [proto].push_back ({pa, proto, superclassSource});
1238
+ ++NumConformanceConstraints;
1221
1239
return superclassSource;
1222
1240
}
1223
1241
@@ -1295,11 +1313,14 @@ bool PotentialArchetype::addConformance(ProtocolDecl *proto,
1295
1313
if (known != equivClass->conformsTo .end ()) {
1296
1314
// We already knew about this conformance; record this specific constraint.
1297
1315
known->second .push_back ({this , proto, source});
1316
+ ++NumConformanceConstraints;
1298
1317
return false ;
1299
1318
}
1300
1319
1301
1320
// Add the conformance along with this constraint.
1302
1321
equivClass->conformsTo [proto].push_back ({this , proto, source});
1322
+ ++NumConformanceConstraints;
1323
+ ++NumConformances;
1303
1324
1304
1325
// Determine whether there is a superclass constraint where the
1305
1326
// superclass conforms to this protocol.
@@ -2716,6 +2737,7 @@ ConstraintResult GenericSignatureBuilder::addLayoutRequirementDirect(
2716
2737
2717
2738
// Record this layout constraint.
2718
2739
equivClass->layoutConstraints .push_back ({PAT, Layout, Source});
2740
+ ++NumLayoutConstraints;
2719
2741
2720
2742
// Update the layout in the equivalence class, if we didn't have one already.
2721
2743
if (!equivClass->layout )
@@ -2840,6 +2862,7 @@ ConstraintResult GenericSignatureBuilder::addSuperclassRequirementDirect(
2840
2862
// Record the constraint.
2841
2863
T->getOrCreateEquivalenceClass ()->superclassConstraints
2842
2864
.push_back (ConcreteConstraint{T, superclass, source});
2865
+ ++NumSuperclassConstraints;
2843
2866
2844
2867
// Update the equivalence class with the constraint.
2845
2868
updateSuperclass (T, superclass, source);
@@ -2976,11 +2999,13 @@ void GenericSignatureBuilder::PotentialArchetype::addSameTypeConstraint(
2976
2999
// Update the same-type constraints of this PA to reference the other PA.
2977
3000
getOrCreateEquivalenceClass ()->sameTypeConstraints [this ]
2978
3001
.push_back ({this , otherPA, source});
3002
+ ++NumSameTypeConstraints;
2979
3003
2980
3004
if (this != otherPA) {
2981
3005
// Update the same-type constraints of the other PA to reference this PA.
2982
3006
otherPA->getOrCreateEquivalenceClass ()->sameTypeConstraints [otherPA]
2983
3007
.push_back ({otherPA, this , source});
3008
+ ++NumSameTypeConstraints;
2984
3009
}
2985
3010
}
2986
3011
@@ -3108,6 +3133,7 @@ ConstraintResult GenericSignatureBuilder::addSameTypeRequirementToConcrete(
3108
3133
// Record the concrete type and its source.
3109
3134
equivClass->concreteTypeConstraints .push_back (
3110
3135
ConcreteConstraint{T, Concrete, Source});
3136
+ ++NumConcreteTypeConstraints;
3111
3137
3112
3138
// If we've already been bound to a type, match that type.
3113
3139
if (equivClass->concreteType ) {
@@ -3151,6 +3177,7 @@ ConstraintResult GenericSignatureBuilder::addSameTypeRequirementToConcrete(
3151
3177
? conformance->getConcrete ()
3152
3178
: nullptr );
3153
3179
equivClass->conformsTo [protocol].push_back ({T, protocol, concreteSource});
3180
+ ++NumConformanceConstraints;
3154
3181
}
3155
3182
3156
3183
// Eagerly resolve any existing nested types to their concrete forms (others
@@ -4107,8 +4134,10 @@ namespace {
4107
4134
[&](const Constraint<T> &constraint) {
4108
4135
bool derivedViaConcrete;
4109
4136
if (constraint.source ->isSelfDerivedSource (
4110
- constraint.archetype , derivedViaConcrete))
4137
+ constraint.archetype , derivedViaConcrete)) {
4138
+ ++NumSelfDerived;
4111
4139
return true ;
4140
+ }
4112
4141
4113
4142
if (!derivedViaConcrete)
4114
4143
return false ;
@@ -4122,6 +4151,7 @@ namespace {
4122
4151
if (!remainingConcrete)
4123
4152
remainingConcrete = constraint;
4124
4153
4154
+ ++NumSelfDerived;
4125
4155
return true ;
4126
4156
}),
4127
4157
constraints.end ());
@@ -4274,15 +4304,19 @@ void GenericSignatureBuilder::checkConformanceConstraints(
4274
4304
bool derivedViaConcrete;
4275
4305
if (constraint.source ->isSelfDerivedConformance (
4276
4306
constraint.archetype , entry.first ,
4277
- derivedViaConcrete))
4307
+ derivedViaConcrete)) {
4308
+ ++NumSelfDerived;
4278
4309
return true ;
4310
+ }
4279
4311
4280
4312
if (!derivedViaConcrete)
4281
4313
return false ;
4282
4314
4283
4315
// Drop derived-via-concrete requirements.
4284
4316
if (!remainingConcrete)
4285
4317
remainingConcrete = constraint;
4318
+
4319
+ ++NumSelfDerived;
4286
4320
return true ;
4287
4321
}),
4288
4322
entry.second .end ());
0 commit comments