@@ -672,14 +672,10 @@ PropertyMap::lookUpProperties(const MutableTerm &key) const {
672
672
// /
673
673
// / This must be called in monotonically non-decreasing key order.
674
674
PropertyBag *
675
- PropertyMap::getOrCreateProperties (const MutableTerm &key) {
676
- assert (!key.empty ());
677
-
678
- if (!Entries.empty ()) {
679
- const auto &lastEntry = Entries.back ();
680
- if (lastEntry->getKey () == key)
681
- return lastEntry;
682
- }
675
+ PropertyMap::getOrCreateProperties (Term key) {
676
+ auto next = Trie.find (key.rbegin (), key.rend ());
677
+ if (next && (*next)->getKey () == key)
678
+ return *next;
683
679
684
680
auto *props = new PropertyBag (key);
685
681
@@ -704,12 +700,9 @@ PropertyMap::getOrCreateProperties(const MutableTerm &key) {
704
700
//
705
701
// Since 'A' has no proper suffix with additional properties, the next
706
702
// property bag of 'A' is nullptr.
707
- if (auto * next = lookUpProperties (key) )
708
- props->copyPropertiesFrom (next, Context);
703
+ if (next)
704
+ props->copyPropertiesFrom (* next, Context);
709
705
710
- // Here is where we make the assumption that if the new key is not equal to
711
- // the key of the last entry, then it is larger than any key already in the
712
- // map.
713
706
Entries.push_back (props);
714
707
auto oldProps = Trie.insert (key.rbegin (), key.rend (), props);
715
708
if (oldProps) {
@@ -738,7 +731,7 @@ void PropertyMap::clear() {
738
731
// / Record a protocol conformance, layout or superclass constraint on the given
739
732
// / key. Must be called in monotonically non-decreasing key order.
740
733
void PropertyMap::addProperty (
741
- const MutableTerm & key, Symbol property,
734
+ Term key, Symbol property,
742
735
SmallVectorImpl<std::pair<MutableTerm, MutableTerm>> &inducedRules) {
743
736
assert (property.isProperty ());
744
737
auto *props = getOrCreateProperties (key);
@@ -763,12 +756,8 @@ void PropertyMap::computeConcreteTypeInDomainMap() {
763
756
auto concreteTypeKey = std::make_pair (concreteType, domain);
764
757
765
758
auto found = ConcreteTypeInDomainMap.find (concreteTypeKey);
766
- if (found != ConcreteTypeInDomainMap.end ()) {
767
- const auto &otherTerm = found->second ;
768
- assert (props->Key .compare (otherTerm, Protos) > 0 &&
769
- " Out-of-order keys?" );
759
+ if (found != ConcreteTypeInDomainMap.end ())
770
760
continue ;
771
- }
772
761
773
762
auto inserted = ConcreteTypeInDomainMap.insert (
774
763
std::make_pair (concreteTypeKey, props->Key ));
@@ -857,7 +846,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParents(
857
846
// / T.[P:B] => U.V
858
847
// /
859
848
void PropertyMap::concretizeNestedTypesFromConcreteParent (
860
- const MutableTerm & key, RequirementKind requirementKind,
849
+ Term key, RequirementKind requirementKind,
861
850
CanType concreteType, ArrayRef<Term> substitutions,
862
851
ArrayRef<const ProtocolDecl *> conformsTo,
863
852
llvm::TinyPtrVector<ProtocolConformance *> &conformances,
@@ -920,7 +909,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
920
909
<< " of " << concreteType << " is " << typeWitness << " \n " ;
921
910
}
922
911
923
- MutableTerm subjectType = key;
912
+ MutableTerm subjectType ( key) ;
924
913
subjectType.add (Symbol::forAssociatedType (proto, assocType->getName (),
925
914
Context));
926
915
@@ -936,7 +925,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
936
925
}
937
926
938
927
// Add a rule T.[P:A] => T.
939
- constraintType = key;
928
+ constraintType = MutableTerm ( key) ;
940
929
} else {
941
930
constraintType = computeConstraintTermForTypeWitness (
942
931
key, concreteType, typeWitness, subjectType,
@@ -977,7 +966,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
977
966
// /
978
967
// / T.[P:A] => V
979
968
MutableTerm PropertyMap::computeConstraintTermForTypeWitness (
980
- const MutableTerm & key, CanType concreteType, CanType typeWitness,
969
+ Term key, CanType concreteType, CanType typeWitness,
981
970
const MutableTerm &subjectType, ArrayRef<Term> substitutions) const {
982
971
if (!typeWitness->hasTypeParameter ()) {
983
972
// Check if we have a shorter representative we can use.
@@ -986,12 +975,13 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
986
975
987
976
auto found = ConcreteTypeInDomainMap.find (concreteTypeKey);
988
977
if (found != ConcreteTypeInDomainMap.end ()) {
989
- if (found->second != subjectType) {
978
+ MutableTerm result (found->second );
979
+ if (result != subjectType) {
990
980
if (DebugConcretizeNestedTypes) {
991
981
llvm::dbgs () << " ^^ Type witness can re-use property bag of "
992
982
<< found->second << " \n " ;
993
983
}
994
- return found-> second ;
984
+ return result ;
995
985
}
996
986
}
997
987
}
@@ -1048,7 +1038,11 @@ RewriteSystem::buildPropertyMap(PropertyMap &map,
1048
1038
unsigned maxDepth) {
1049
1039
map.clear ();
1050
1040
1051
- std::vector<std::pair<MutableTerm, Symbol>> properties;
1041
+ // PropertyMap::addRule() requires that shorter rules are added
1042
+ // before longer rules, so that it can perform lookups on suffixes and call
1043
+ // PropertyBag::copyPropertiesFrom(). However, we don't have to perform a
1044
+ // full sort by term order here; a bucket sort by term length suffices.
1045
+ SmallVector<std::vector<std::pair<Term, Symbol>>, 4 > properties;
1052
1046
1053
1047
for (const auto &rule : Rules) {
1054
1048
if (rule.isDeleted ())
@@ -1068,31 +1062,19 @@ RewriteSystem::buildPropertyMap(PropertyMap &map,
1068
1062
if (!std::equal (rhs.begin (), rhs.end (), lhs.begin ()))
1069
1063
continue ;
1070
1064
1071
- MutableTerm key (rhs);
1072
-
1073
- #ifndef NDEBUG
1074
- assert (!simplify (key) &&
1075
- " Right hand side of a property rule should already be reduced" );
1076
- #endif
1077
-
1078
- properties.emplace_back (key, property);
1065
+ if (rhs.size () >= properties.size ())
1066
+ properties.resize (rhs.size () + 1 );
1067
+ properties[rhs.size ()].emplace_back (rhs, property);
1079
1068
}
1080
1069
1081
- // PropertyMap::addRule() requires that shorter rules are added
1082
- // before longer rules, so that it can perform lookups on suffixes and call
1083
- // PropertyBag::copyPropertiesFrom().
1084
- std::sort (properties.begin (), properties.end (),
1085
- [&](const std::pair<MutableTerm, Symbol> &lhs,
1086
- const std::pair<MutableTerm, Symbol> &rhs) -> bool {
1087
- return lhs.first .compare (rhs.first , Protos) < 0 ;
1088
- });
1089
-
1090
1070
// Merging multiple superclass or concrete type rules can induce new rules
1091
1071
// to unify concrete type constructor arguments.
1092
1072
SmallVector<std::pair<MutableTerm, MutableTerm>, 3 > inducedRules;
1093
1073
1094
- for (auto pair : properties) {
1095
- map.addProperty (pair.first , pair.second , inducedRules);
1074
+ for (const auto &bucket : properties) {
1075
+ for (auto pair : bucket) {
1076
+ map.addProperty (pair.first , pair.second , inducedRules);
1077
+ }
1096
1078
}
1097
1079
1098
1080
// We collect terms with fully concrete types so that we can re-use them
0 commit comments