Skip to content

Commit 60d34a4

Browse files
committed
Sema: Micro-optimize PotentialBindings
PotentialBindings is part of ConstraintGraphNode and there's no need to store the ConstraintSystem and TypeVariableType twice. Also it doesn't need to be optional either, because we no longer need to reset and recompute bindings.
1 parent 1bdf7f0 commit 60d34a4

File tree

5 files changed

+63
-45
lines changed

5 files changed

+63
-45
lines changed

include/swift/Sema/CSBindings.h

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,6 @@ struct LiteralRequirement {
218218
};
219219

220220
struct PotentialBindings {
221-
/// The constraint system this type variable and its bindings belong to.
222-
ConstraintSystem &CS;
223-
224-
TypeVariableType *TypeVar;
225-
226221
/// The set of all constraints that have been added via infer().
227222
llvm::SmallPtrSet<Constraint *, 2> Constraints;
228223

@@ -265,18 +260,13 @@ struct PotentialBindings {
265260
llvm::SmallSetVector<std::pair<TypeVariableType *, Constraint *>, 4> SupertypeOf;
266261
llvm::SmallSetVector<std::pair<TypeVariableType *, Constraint *>, 4> EquivalentTo;
267262

268-
PotentialBindings(ConstraintSystem &cs, TypeVariableType *typeVar)
269-
: CS(cs), TypeVar(typeVar) {}
270-
271263
void addDefault(Constraint *constraint);
272264

273265
void addLiteral(Constraint *constraint);
274266

275267
/// Add a potential binding to the list of bindings,
276268
/// coalescing supertype bounds when we are able to compute the meet.
277-
void addPotentialBinding(PotentialBinding binding);
278-
279-
bool isGenericParameter() const;
269+
void addPotentialBinding(TypeVariableType *typeVar, PotentialBinding binding);
280270

281271
bool isSubtypeOf(TypeVariableType *typeVar) const {
282272
return llvm::any_of(
@@ -291,17 +281,26 @@ struct PotentialBindings {
291281
/// Attempt to infer a new binding and other useful information
292282
/// (i.e. whether bindings should be delayed) from the given
293283
/// relational constraint.
294-
std::optional<PotentialBinding> inferFromRelational(Constraint *constraint);
284+
std::optional<PotentialBinding> inferFromRelational(
285+
ConstraintSystem &CS,
286+
TypeVariableType *TypeVar,
287+
Constraint *constraint);
295288

296289
public:
297-
void infer(Constraint *constraint);
290+
void infer(ConstraintSystem &CS,
291+
TypeVariableType *TypeVar,
292+
Constraint *constraint);
298293

299294
/// Retract all bindings and other information related to a given
300295
/// constraint from this binding set.
301296
///
302297
/// This would happen when constraint is simplified or solver backtracks
303298
/// (either from overload choice or (some) type variable binding).
304-
void retract(Constraint *constraint);
299+
void retract(ConstraintSystem &CS,
300+
TypeVariableType *TypeVar,
301+
Constraint *constraint);
302+
303+
void reset();
305304
};
306305

307306

@@ -388,8 +387,9 @@ class BindingSet {
388387
/// subtype/conversion/equivalence relations with other type variables.
389388
std::optional<llvm::SmallPtrSet<Constraint *, 4>> TransitiveProtocols;
390389

391-
BindingSet(const PotentialBindings &info)
392-
: CS(info.CS), TypeVar(info.TypeVar), Info(info) {
390+
BindingSet(ConstraintSystem &CS, TypeVariableType *TypeVar,
391+
const PotentialBindings &info)
392+
: CS(CS), TypeVar(TypeVar), Info(info) {
393393
for (const auto &binding : info.Bindings)
394394
addBinding(binding, /*isTransitive=*/false);
395395

@@ -405,7 +405,7 @@ class BindingSet {
405405

406406
ConstraintSystem &getConstraintSystem() const { return CS; }
407407

408-
TypeVariableType *getTypeVariable() const { return Info.TypeVar; }
408+
TypeVariableType *getTypeVariable() const { return TypeVar; }
409409

410410
/// Check whether this binding set belongs to a type variable
411411
/// that represents a result type of a closure.

include/swift/Sema/ConstraintGraph.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ class ConstraintGraphNode {
8484
/// as this type variable.
8585
ArrayRef<TypeVariableType *> getEquivalenceClass() const;
8686

87-
inference::PotentialBindings &getCurrentBindings();
87+
inference::PotentialBindings &getCurrentBindings() {
88+
assert(forRepresentativeVar());
89+
return Bindings;
90+
}
8891

8992
private:
9093
/// Determines whether the type variable associated with this node
@@ -180,7 +183,7 @@ class ConstraintGraphNode {
180183
TypeVariableType *TypeVar;
181184

182185
/// The set of bindings associated with this type variable.
183-
std::optional<inference::PotentialBindings> Bindings;
186+
inference::PotentialBindings Bindings;
184187

185188
/// The vector of constraints that mention this type variable, in a stable
186189
/// order for iteration.

include/swift/Sema/ConstraintSystem.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include "swift/Basic/Debug.h"
3131
#include "swift/Basic/LLVM.h"
3232
#include "swift/Basic/OptionSet.h"
33-
#include "swift/Sema/CSBindings.h"
3433
#include "swift/Sema/CSFix.h"
3534
#include "swift/Sema/CSTrail.h"
3635
#include "swift/Sema/Constraint.h"

lib/Sema/CSBindings.cpp

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ static std::optional<Type> checkTypeOfBinding(TypeVariableType *typeVar,
3535
Type type);
3636

3737
bool BindingSet::forClosureResult() const {
38-
return Info.TypeVar->getImpl().isClosureResultType();
38+
return TypeVar->getImpl().isClosureResultType();
3939
}
4040

4141
bool BindingSet::forGenericParameter() const {
42-
return bool(Info.TypeVar->getImpl().getGenericParameter());
42+
return bool(TypeVar->getImpl().getGenericParameter());
4343
}
4444

4545
bool BindingSet::canBeNil() const {
@@ -54,10 +54,10 @@ bool BindingSet::isDirectHole() const {
5454
return false;
5555

5656
return Bindings.empty() && getNumViableLiteralBindings() == 0 &&
57-
Defaults.empty() && Info.TypeVar->getImpl().canBindToHole();
57+
Defaults.empty() && TypeVar->getImpl().canBindToHole();
5858
}
5959

60-
bool PotentialBindings::isGenericParameter() const {
60+
static bool isGenericParameter(TypeVariableType *TypeVar) {
6161
auto *locator = TypeVar->getImpl().getLocator();
6262
return locator && locator->isLastElement<LocatorPathElt::GenericParameter>();
6363
}
@@ -178,7 +178,7 @@ bool BindingSet::involvesTypeVariables() const {
178178

179179
bool BindingSet::isPotentiallyIncomplete() const {
180180
// Generic parameters are always potentially incomplete.
181-
if (Info.isGenericParameter())
181+
if (isGenericParameter(TypeVar))
182182
return true;
183183

184184
// Key path literal type is incomplete until there is a
@@ -1168,7 +1168,8 @@ LiteralRequirement::isCoveredBy(const PotentialBinding &binding, bool canBeNil,
11681168
} while (true);
11691169
}
11701170

1171-
void PotentialBindings::addPotentialBinding(PotentialBinding binding) {
1171+
void PotentialBindings::addPotentialBinding(TypeVariableType *TypeVar,
1172+
PotentialBinding binding) {
11721173
assert(!binding.BindingType->is<ErrorType>());
11731174

11741175
// If the type variable can't bind to an lvalue, make sure the
@@ -1418,7 +1419,7 @@ BindingSet ConstraintSystem::getBindingsFor(TypeVariableType *typeVar,
14181419
"not a representative");
14191420
assert(!typeVar->getImpl().getFixedType(nullptr) && "has a fixed type");
14201421

1421-
BindingSet bindings{CG[typeVar].getCurrentBindings()};
1422+
BindingSet bindings(*this, typeVar, CG[typeVar].getCurrentBindings());
14221423

14231424
if (finalize) {
14241425
llvm::SmallDenseMap<TypeVariableType *, BindingSet> cache;
@@ -1461,7 +1462,9 @@ static std::optional<Type> checkTypeOfBinding(TypeVariableType *typeVar,
14611462
}
14621463

14631464
std::optional<PotentialBinding>
1464-
PotentialBindings::inferFromRelational(Constraint *constraint) {
1465+
PotentialBindings::inferFromRelational(ConstraintSystem &CS,
1466+
TypeVariableType *TypeVar,
1467+
Constraint *constraint) {
14651468
assert(constraint->getClassification() ==
14661469
ConstraintClassification::Relational &&
14671470
"only relational constraints handled here");
@@ -1657,7 +1660,7 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
16571660
// Since inference now happens during constraint generation,
16581661
// this hack should be allowed in both `Solving`
16591662
// (during non-diagnostic mode) and `ConstraintGeneration` phases.
1660-
if (isGenericParameter() &&
1663+
if (isGenericParameter(TypeVar) &&
16611664
(!CS.shouldAttemptFixes() ||
16621665
CS.getPhase() == ConstraintSystemPhase::ConstraintGeneration)) {
16631666
type = fnTy->withExtInfo(fnTy->getExtInfo().withNoEscape(false));
@@ -1766,7 +1769,9 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
17661769
/// Retrieve the set of potential type bindings for the given
17671770
/// representative type variable, along with flags indicating whether
17681771
/// those types should be opened.
1769-
void PotentialBindings::infer(Constraint *constraint) {
1772+
void PotentialBindings::infer(ConstraintSystem &CS,
1773+
TypeVariableType *TypeVar,
1774+
Constraint *constraint) {
17701775
if (!Constraints.insert(constraint).second)
17711776
return;
17721777

@@ -1787,11 +1792,11 @@ void PotentialBindings::infer(Constraint *constraint) {
17871792
case ConstraintKind::OptionalObject:
17881793
case ConstraintKind::UnresolvedMemberChainBase:
17891794
case ConstraintKind::LValueObject: {
1790-
auto binding = inferFromRelational(constraint);
1795+
auto binding = inferFromRelational(CS, TypeVar, constraint);
17911796
if (!binding)
17921797
break;
17931798

1794-
addPotentialBinding(*binding);
1799+
addPotentialBinding(TypeVar, *binding);
17951800
break;
17961801
}
17971802
case ConstraintKind::KeyPathApplication: {
@@ -1940,7 +1945,9 @@ void PotentialBindings::infer(Constraint *constraint) {
19401945
}
19411946
}
19421947

1943-
void PotentialBindings::retract(Constraint *constraint) {
1948+
void PotentialBindings::retract(ConstraintSystem &CS,
1949+
TypeVariableType *TypeVar,
1950+
Constraint *constraint) {
19441951
if (!Constraints.erase(constraint))
19451952
return;
19461953

@@ -2011,6 +2018,23 @@ void PotentialBindings::retract(Constraint *constraint) {
20112018
EquivalentTo.remove_if(hasMatchingSource);
20122019
}
20132020

2021+
void PotentialBindings::reset() {
2022+
if (CONDITIONAL_ASSERT_enabled()) {
2023+
ASSERT(Constraints.empty());
2024+
ASSERT(Bindings.empty());
2025+
ASSERT(Protocols.empty());
2026+
ASSERT(Literals.empty());
2027+
ASSERT(Defaults.empty());
2028+
ASSERT(DelayedBy.empty());
2029+
ASSERT(AdjacentVars.empty());
2030+
ASSERT(SubtypeOf.empty());
2031+
ASSERT(SupertypeOf.empty());
2032+
ASSERT(EquivalentTo.empty());
2033+
}
2034+
2035+
AssociatedCodeCompletionToken = ASTNode();
2036+
}
2037+
20142038
void BindingSet::forEachLiteralRequirement(
20152039
llvm::function_ref<void(KnownProtocolKind)> callback) const {
20162040
for (const auto &literal : Literals) {

lib/Sema/ConstraintGraph.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -296,19 +296,11 @@ void ConstraintGraphNode::removeReferencedBy(TypeVariableType *typeVar) {
296296
}
297297
}
298298

299-
inference::PotentialBindings &ConstraintGraphNode::getCurrentBindings() {
300-
assert(forRepresentativeVar());
301-
302-
if (!Bindings)
303-
Bindings.emplace(CG.getConstraintSystem(), TypeVar);
304-
return *Bindings;
305-
}
306-
307299
void ConstraintGraphNode::introduceToInference(Constraint *constraint) {
308300
if (forRepresentativeVar()) {
309301
auto fixedType = TypeVar->getImpl().getFixedType(/*record=*/nullptr);
310302
if (!fixedType)
311-
getCurrentBindings().infer(constraint);
303+
getCurrentBindings().infer(CG.getConstraintSystem(), TypeVar, constraint);
312304
} else {
313305
auto *repr =
314306
getTypeVariable()->getImpl().getRepresentative(/*record=*/nullptr);
@@ -320,7 +312,7 @@ void ConstraintGraphNode::retractFromInference(Constraint *constraint) {
320312
if (forRepresentativeVar()) {
321313
auto fixedType = TypeVar->getImpl().getFixedType(/*record=*/nullptr);
322314
if (!fixedType)
323-
getCurrentBindings().retract(constraint);
315+
getCurrentBindings().retract(CG.getConstraintSystem(), TypeVar,constraint);
324316
} else {
325317
auto *repr =
326318
getTypeVariable()->getImpl().getRepresentative(/*record=*/nullptr);
@@ -584,12 +576,12 @@ void ConstraintGraph::unrelateTypeVariables(TypeVariableType *typeVar,
584576

585577
void ConstraintGraph::inferBindings(TypeVariableType *typeVar,
586578
Constraint *constraint) {
587-
(*this)[typeVar].getCurrentBindings().infer(constraint);
579+
(*this)[typeVar].getCurrentBindings().infer(CS, typeVar, constraint);
588580
}
589581

590582
void ConstraintGraph::retractBindings(TypeVariableType *typeVar,
591583
Constraint *constraint) {
592-
(*this)[typeVar].getCurrentBindings().retract(constraint);
584+
(*this)[typeVar].getCurrentBindings().retract(CS, typeVar, constraint);
593585
}
594586

595587
#pragma mark Algorithms

0 commit comments

Comments
 (0)