@@ -408,13 +408,17 @@ class Sema;
408408 }
409409
410410 bool isPerfect (const ASTContext &C) const {
411- if (!isIdentityConversion ())
411+ if (!isIdentityConversion ())
412412 return false ;
413- if (!ReferenceBinding)
413+ // If we are not performing a reference binding, we can skip comparing
414+ // the types, which has a noticeable performance impact.
415+ if (!ReferenceBinding) {
416+ assert (C.hasSameType (getFromType (), getToType (2 )));
414417 return true ;
415- if (!C.hasSameType (getFromType (), getToType (2 )))
418+ }
419+ if (!C.hasSameType (getFromType (), getToType (2 )))
416420 return false ;
417- if (BindsToRvalue && IsLvalueReference)
421+ if (BindsToRvalue && IsLvalueReference)
418422 return false ;
419423 return true ;
420424 }
@@ -755,6 +759,9 @@ class Sema;
755759 Standard.setAllToTypes (T);
756760 }
757761
762+ // / A conversion sequence is perfect if
763+ // / it is an identity conversion and
764+ // / the type of the source is the same as the type of the target.
758765 bool isPerfect (const ASTContext &C) const {
759766 return isStandard () && Standard.isPerfect (C);
760767 }
@@ -995,6 +1002,8 @@ class Sema;
9951002 return false ;
9961003 }
9971004
1005+ // An overload is a perfect match if the conversion
1006+ // sequences for each argument are perfect.
9981007 bool isPerfectMatch (const ASTContext &Ctx) const {
9991008 if (!Viable)
10001009 return false ;
@@ -1046,7 +1055,10 @@ class Sema;
10461055 };
10471056
10481057 struct DeferredTemplateOverloadCandidate {
1058+
1059+ // intrusive linked list support for allocateDeferredCandidate
10491060 DeferredTemplateOverloadCandidate *Next = nullptr ;
1061+
10501062 enum Kind { Function, Method, Conversion };
10511063
10521064 LLVM_PREFERRED_TYPE (Kind)
@@ -1256,6 +1268,11 @@ class Sema;
12561268 return reinterpret_cast <T *>(FreeSpaceStart);
12571269 }
12581270
1271+ // Because the size of OverloadCandidateSet has a noticeable impact on
1272+ // performance, we store each deferred template candidate in the slab
1273+ // allocator such that deferred candidates are ultimately a singly-linked
1274+ // intrusive linked list. This ends up being much more efficient than a
1275+ // SmallVector that is empty in the common case.
12591276 template <typename T> T *allocateDeferredCandidate () {
12601277 T *C = slabAllocate<T>(1 );
12611278 if (!FirstDeferredCandidate)
0 commit comments