Skip to content

Commit 983fe46

Browse files
authored
Merge pull request swiftlang#39859 from xedin/dedupe-constraint-system-storage
[ConstraintSystem] De-duplicate storage of constraint system elements
2 parents e779790 + f765390 commit 983fe46

File tree

6 files changed

+85
-93
lines changed

6 files changed

+85
-93
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,10 +2184,6 @@ class SolutionApplicationTarget {
21842184
using RewriteTargetFn = std::function<
21852185
Optional<SolutionApplicationTarget> (SolutionApplicationTarget)>;
21862186

2187-
/// Represents a conversion restriction between two types.
2188-
using ConversionRestriction =
2189-
std::tuple<TypeBase *, TypeBase *, ConversionRestrictionKind>;
2190-
21912187
enum class ConstraintSystemPhase {
21922188
ConstraintGeneration,
21932189
Solving,
@@ -2377,15 +2373,15 @@ class ConstraintSystem {
23772373
/// there are multiple ways in which one type could convert to another, e.g.,
23782374
/// given class types A and B, the solver might choose either a superclass
23792375
/// conversion or a user-defined conversion.
2380-
std::vector<ConversionRestriction> ConstraintRestrictions;
2376+
llvm::MapVector<std::pair<TypeBase *, TypeBase *>, ConversionRestrictionKind>
2377+
ConstraintRestrictions;
23812378

23822379
/// The set of fixes applied to make the solution work.
2383-
llvm::SmallVector<ConstraintFix *, 4> Fixes;
2380+
llvm::SmallSetVector<ConstraintFix *, 4> Fixes;
23842381

23852382
/// The set of remembered disjunction choices used to reach
23862383
/// the current constraint system.
2387-
std::vector<std::pair<ConstraintLocator*, unsigned>>
2388-
DisjunctionChoices;
2384+
llvm::MapVector<ConstraintLocator *, unsigned> DisjunctionChoices;
23892385

23902386
/// A map from applied disjunction constraints to the corresponding
23912387
/// argument function type.
@@ -2394,12 +2390,12 @@ class ConstraintSystem {
23942390

23952391
/// For locators associated with call expressions, the trailing closure
23962392
/// matching rule and parameter bindings that were applied.
2397-
std::vector<std::pair<ConstraintLocator *, MatchCallArgumentResult>>
2393+
llvm::MapVector<ConstraintLocator *, MatchCallArgumentResult>
23982394
argumentMatchingChoices;
23992395

24002396
/// The set of implicit value conversions performed by the solver on
24012397
/// a current path to reach a solution.
2402-
SmallVector<std::pair<ConstraintLocator *, ConversionRestrictionKind>, 2>
2398+
llvm::SmallMapVector<ConstraintLocator *, ConversionRestrictionKind, 2>
24032399
ImplicitValueConversions;
24042400

24052401
/// The worklist of "active" constraints that should be revisited
@@ -2415,8 +2411,8 @@ class ConstraintSystem {
24152411

24162412
/// A mapping from constraint locators to the set of opened types associated
24172413
/// with that locator.
2418-
SmallVector<std::pair<ConstraintLocator *, ArrayRef<OpenedType>>, 4>
2419-
OpenedTypes;
2414+
llvm::SmallMapVector<ConstraintLocator *, ArrayRef<OpenedType>, 4>
2415+
OpenedTypes;
24202416

24212417
/// The list of all generic requirements fixed along the current
24222418
/// solver path.
@@ -2430,11 +2426,11 @@ class ConstraintSystem {
24302426

24312427
/// A mapping from constraint locators to the opened existential archetype
24322428
/// used for the 'self' of an existential type.
2433-
SmallVector<std::pair<ConstraintLocator *, OpenedArchetypeType *>, 4>
2434-
OpenedExistentialTypes;
2429+
llvm::SmallMapVector<ConstraintLocator *, OpenedArchetypeType *, 4>
2430+
OpenedExistentialTypes;
24352431

24362432
/// The set of functions that have been transformed by a result builder.
2437-
std::vector<std::pair<AnyFunctionRef, AppliedBuilderTransform>>
2433+
llvm::MapVector<AnyFunctionRef, AppliedBuilderTransform>
24382434
resultBuilderTransformed;
24392435

24402436
/// Cache of the effects any closures visited.
@@ -2450,7 +2446,7 @@ class ConstraintSystem {
24502446
llvm::SmallMapVector<ASTNode, SmallVector<AppliedPropertyWrapper, 2>, 4> appliedPropertyWrappers;
24512447

24522448
/// The locators of \c Defaultable constraints whose defaults were used.
2453-
std::vector<ConstraintLocator *> DefaultedConstraints;
2449+
llvm::SetVector<ConstraintLocator *> DefaultedConstraints;
24542450

24552451
/// A cache that stores the @dynamicCallable required methods implemented by
24562452
/// types.
@@ -3424,7 +3420,7 @@ class ConstraintSystem {
34243420
return !solverState || solverState->recordFixes;
34253421
}
34263422

3427-
ArrayRef<ConstraintFix *> getFixes() const { return Fixes; }
3423+
ArrayRef<ConstraintFix *> getFixes() const { return Fixes.getArrayRef(); }
34283424

34293425
bool shouldSuppressDiagnostics() const {
34303426
return Options.contains(ConstraintSystemFlags::SuppressDiagnostics);
@@ -3473,6 +3469,16 @@ class ConstraintSystem {
34733469
});
34743470
}
34753471

3472+
bool
3473+
hasConversionRestriction(Type type1, Type type2,
3474+
ConversionRestrictionKind restrictionKind) const {
3475+
auto restriction =
3476+
ConstraintRestrictions.find({type1.getPointer(), type2.getPointer()});
3477+
return restriction == ConstraintRestrictions.end()
3478+
? false
3479+
: restriction->second == restrictionKind;
3480+
}
3481+
34763482
/// If an UnresolvedDotExpr, SubscriptMember, etc has been resolved by the
34773483
/// constraint system, return the decl that it references.
34783484
ValueDecl *findResolvedMemberRef(ConstraintLocator *locator);
@@ -4172,10 +4178,12 @@ class ConstraintSystem {
41724178
OpenedTypeMap *replacements = nullptr);
41734179

41744180
/// Retrieve a list of generic parameter types solver has "opened" (replaced
4175-
/// with a type variable) along the current path.
4176-
ArrayRef<std::pair<ConstraintLocator *, ArrayRef<OpenedType>>>
4177-
getOpenedTypes() const {
4178-
return OpenedTypes;
4181+
/// with a type variable) at the given location.
4182+
ArrayRef<OpenedType> getOpenedTypes(ConstraintLocator *locator) const {
4183+
auto substitutions = OpenedTypes.find(locator);
4184+
if (substitutions == OpenedTypes.end())
4185+
return {};
4186+
return substitutions->second;
41794187
}
41804188

41814189
private:
@@ -4901,7 +4909,10 @@ class ConstraintSystem {
49014909
/// Record a particular disjunction choice of
49024910
void recordDisjunctionChoice(ConstraintLocator *disjunctionLocator,
49034911
unsigned index) {
4904-
DisjunctionChoices.push_back({disjunctionLocator, index});
4912+
// We shouldn't ever register disjunction choices multiple times.
4913+
assert(!DisjunctionChoices.count(disjunctionLocator) ||
4914+
DisjunctionChoices[disjunctionLocator] == index);
4915+
DisjunctionChoices.insert({disjunctionLocator, index});
49054916
}
49064917

49074918
/// Filter the set of disjunction terms, keeping only those where the

lib/Sema/BuilderTransform.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,8 +1859,7 @@ ConstraintSystem::matchResultBuilder(AnyFunctionRef fn, Type builderType,
18591859
return elt.first == fn;
18601860
}) == resultBuilderTransformed.end() &&
18611861
"already transformed this body along this path!?!");
1862-
resultBuilderTransformed.push_back(
1863-
std::make_pair(fn, std::move(*applied)));
1862+
resultBuilderTransformed.insert(std::make_pair(fn, std::move(*applied)));
18641863

18651864
// If builder is applied to the closure expression then
18661865
// `closure body` to `closure result` matching should

lib/Sema/CSBindings.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1983,7 +1983,7 @@ bool TypeVariableBinding::attempt(ConstraintSystem &cs) const {
19831983

19841984
// If this was from a defaultable binding note that.
19851985
if (Binding.isDefaultableBinding()) {
1986-
cs.DefaultedConstraints.push_back(srcLocator);
1986+
cs.DefaultedConstraints.insert(srcLocator);
19871987

19881988
if (type->isPlaceholder() && reportHole())
19891989
return true;

lib/Sema/CSSimplify.cpp

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3973,10 +3973,10 @@ bool ConstraintSystem::repairFailures(
39733973
// we can instead suggest the conditional downcast as it is safer in
39743974
// situations like conditional binding.
39753975
auto useConditionalCast =
3976-
llvm::any_of(ConstraintRestrictions, [&](auto &restriction) {
3977-
ConversionRestrictionKind restrictionKind;
3976+
llvm::any_of(ConstraintRestrictions, [&](const auto &restriction) {
39783977
Type type1, type2;
3979-
std::tie(type1, type2, restrictionKind) = restriction;
3978+
std::tie(type1, type2) = restriction.first;
3979+
auto restrictionKind = restriction.second;
39803980

39813981
if (restrictionKind != ConversionRestrictionKind::ValueToOptional)
39823982
return false;
@@ -6770,7 +6770,6 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
67706770
ConstraintSystem &cs, Type origFromType, Type origToType, Type fromType,
67716771
Type toType, SmallVector<Type, 4> fromOptionals,
67726772
SmallVector<Type, 4> toOptionals,
6773-
const std::vector<ConversionRestriction> &constraintRestrictions,
67746773
ConstraintSystem::TypeMatchOptions flags,
67756774
ConstraintLocatorBuilder locator) {
67766775

@@ -6797,10 +6796,8 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
67976796
// "from" expression could be a type variable with value-to-optional
67986797
// restrictions that we have to account for optionality mismatch.
67996798
const auto subExprType = cs.getType(castExpr->getSubExpr());
6800-
if (llvm::is_contained(
6801-
constraintRestrictions,
6802-
std::make_tuple(fromType.getPointer(), subExprType.getPointer(),
6803-
ConversionRestrictionKind::ValueToOptional))) {
6799+
if (cs.hasConversionRestriction(fromType, subExprType,
6800+
ConversionRestrictionKind::ValueToOptional)) {
68046801
extraOptionals++;
68056802
origFromType = OptionalType::get(origFromType);
68066803
}
@@ -6960,7 +6957,7 @@ ConstraintSystem::simplifyCheckedCastConstraint(
69606957

69616958
if (auto *fix = maybeWarnAboutExtraneousCast(
69626959
*this, origFromType, origToType, fromType, toType, fromOptionals,
6963-
toOptionals, ConstraintRestrictions, flags, locator)) {
6960+
toOptionals, flags, locator)) {
69646961
(void)recordFix(fix);
69656962
}
69666963
};
@@ -7028,7 +7025,7 @@ ConstraintSystem::simplifyCheckedCastConstraint(
70287025
// succeed or fail.
70297026
if (auto *fix = maybeWarnAboutExtraneousCast(
70307027
*this, origFromType, origToType, fromType, toType, fromOptionals,
7031-
toOptionals, ConstraintRestrictions, flags, locator)) {
7028+
toOptionals, flags, locator)) {
70327029
(void)recordFix(fix);
70337030
}
70347031

@@ -8893,13 +8890,10 @@ static Type getOpenedResultBuilderTypeFor(ConstraintSystem &cs,
88938890
if (builderType->hasTypeParameter()) {
88948891
// Find the opened type for this callee and substitute in the type
88958892
// parametes.
8896-
// FIXME: We should consider changing OpenedTypes to a MapVector.
8897-
for (const auto &opened : cs.getOpenedTypes()) {
8898-
if (opened.first == calleeLocator) {
8899-
OpenedTypeMap replacements(opened.second.begin(), opened.second.end());
8900-
builderType = cs.openType(builderType, replacements);
8901-
break;
8902-
}
8893+
auto substitutions = cs.getOpenedTypes(calleeLocator);
8894+
if (!substitutions.empty()) {
8895+
OpenedTypeMap replacements(substitutions.begin(), substitutions.end());
8896+
builderType = cs.openType(builderType, replacements);
89038897
}
89048898
assert(!builderType->hasTypeParameter());
89058899
}
@@ -11325,7 +11319,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
1132511319
FunctionType::get({FunctionType::Param(type1)}, type2),
1132611320
memberTy, applicationLoc);
1132711321

11328-
ImplicitValueConversions.push_back(
11322+
ImplicitValueConversions.insert(
1132911323
{getConstraintLocator(locator), restriction});
1133011324
return SolutionKind::Solved;
1133111325
}
@@ -11361,8 +11355,8 @@ ConstraintSystem::simplifyRestrictedConstraint(
1136111355
addFixConstraint(fix, matchKind, type1, type2, locator);
1136211356
}
1136311357

11364-
ConstraintRestrictions.push_back(
11365-
std::make_tuple(type1.getPointer(), type2.getPointer(), restriction));
11358+
ConstraintRestrictions.insert({
11359+
std::make_pair(type1.getPointer(), type2.getPointer()), restriction});
1136611360
return SolutionKind::Solved;
1136711361
}
1136811362
case SolutionKind::Unsolved:
@@ -11522,7 +11516,7 @@ bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact) {
1152211516
return true;
1152311517

1152411518
if (isAugmentingFix(fix)) {
11525-
Fixes.push_back(fix);
11519+
Fixes.insert(fix);
1152611520
return false;
1152711521
}
1152811522

@@ -11547,7 +11541,7 @@ bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact) {
1154711541
}
1154811542

1154911543
if (!found)
11550-
Fixes.push_back(fix);
11544+
Fixes.insert(fix);
1155111545

1155211546
return false;
1155311547
}
@@ -11569,7 +11563,7 @@ void ConstraintSystem::recordAnyTypeVarAsPotentialHole(Type type) {
1156911563
void ConstraintSystem::recordMatchCallArgumentResult(
1157011564
ConstraintLocator *locator, MatchCallArgumentResult result) {
1157111565
assert(locator->isLastElement<LocatorPathElt::ApplyArgument>());
11572-
argumentMatchingChoices.push_back({locator, result});
11566+
argumentMatchingChoices.insert({locator, result});
1157311567
}
1157411568

1157511569
ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(

0 commit comments

Comments
 (0)