Skip to content

Commit f746685

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 8c60dd0 commit f746685

File tree

5 files changed

+60
-45
lines changed

5 files changed

+60
-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: 34 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
@@ -1430,7 +1431,7 @@ BindingSet ConstraintSystem::getBindingsFor(TypeVariableType *typeVar,
14301431
"not a representative");
14311432
assert(!typeVar->getImpl().getFixedType(nullptr) && "has a fixed type");
14321433

1433-
BindingSet bindings{CG[typeVar].getCurrentBindings()};
1434+
BindingSet bindings(*this, typeVar, CG[typeVar].getCurrentBindings());
14341435

14351436
if (finalize) {
14361437
llvm::SmallDenseMap<TypeVariableType *, BindingSet> cache;
@@ -1473,7 +1474,9 @@ static std::optional<Type> checkTypeOfBinding(TypeVariableType *typeVar,
14731474
}
14741475

14751476
std::optional<PotentialBinding>
1476-
PotentialBindings::inferFromRelational(Constraint *constraint) {
1477+
PotentialBindings::inferFromRelational(ConstraintSystem &CS,
1478+
TypeVariableType *TypeVar,
1479+
Constraint *constraint) {
14771480
assert(constraint->getClassification() ==
14781481
ConstraintClassification::Relational &&
14791482
"only relational constraints handled here");
@@ -1669,7 +1672,7 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
16691672
// Since inference now happens during constraint generation,
16701673
// this hack should be allowed in both `Solving`
16711674
// (during non-diagnostic mode) and `ConstraintGeneration` phases.
1672-
if (isGenericParameter() &&
1675+
if (isGenericParameter(TypeVar) &&
16731676
(!CS.shouldAttemptFixes() ||
16741677
CS.getPhase() == ConstraintSystemPhase::ConstraintGeneration)) {
16751678
type = fnTy->withExtInfo(fnTy->getExtInfo().withNoEscape(false));
@@ -1778,7 +1781,9 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
17781781
/// Retrieve the set of potential type bindings for the given
17791782
/// representative type variable, along with flags indicating whether
17801783
/// those types should be opened.
1781-
void PotentialBindings::infer(Constraint *constraint) {
1784+
void PotentialBindings::infer(ConstraintSystem &CS,
1785+
TypeVariableType *TypeVar,
1786+
Constraint *constraint) {
17821787
if (!Constraints.insert(constraint).second)
17831788
return;
17841789

@@ -1799,11 +1804,11 @@ void PotentialBindings::infer(Constraint *constraint) {
17991804
case ConstraintKind::OptionalObject:
18001805
case ConstraintKind::UnresolvedMemberChainBase:
18011806
case ConstraintKind::LValueObject: {
1802-
auto binding = inferFromRelational(constraint);
1807+
auto binding = inferFromRelational(CS, TypeVar, constraint);
18031808
if (!binding)
18041809
break;
18051810

1806-
addPotentialBinding(*binding);
1811+
addPotentialBinding(TypeVar, *binding);
18071812
break;
18081813
}
18091814
case ConstraintKind::KeyPathApplication: {
@@ -1952,7 +1957,9 @@ void PotentialBindings::infer(Constraint *constraint) {
19521957
}
19531958
}
19541959

1955-
void PotentialBindings::retract(Constraint *constraint) {
1960+
void PotentialBindings::retract(ConstraintSystem &CS,
1961+
TypeVariableType *TypeVar,
1962+
Constraint *constraint) {
19561963
if (!Constraints.erase(constraint))
19571964
return;
19581965

@@ -2023,6 +2030,20 @@ void PotentialBindings::retract(Constraint *constraint) {
20232030
EquivalentTo.remove_if(hasMatchingSource);
20242031
}
20252032

2033+
void PotentialBindings::reset() {
2034+
Constraints.clear();
2035+
Bindings.clear();
2036+
Protocols.clear();
2037+
Literals.clear();
2038+
Defaults.clear();
2039+
DelayedBy.clear();
2040+
AdjacentVars.clear();
2041+
AssociatedCodeCompletionToken = ASTNode();
2042+
SubtypeOf.clear();
2043+
SupertypeOf.clear();
2044+
EquivalentTo.clear();
2045+
}
2046+
20262047
void BindingSet::forEachLiteralRequirement(
20272048
llvm::function_ref<void(KnownProtocolKind)> callback) const {
20282049
for (const auto &literal : Literals) {

lib/Sema/ConstraintGraph.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -289,19 +289,11 @@ void ConstraintGraphNode::removeReferencedBy(TypeVariableType *typeVar) {
289289
}
290290
}
291291

292-
inference::PotentialBindings &ConstraintGraphNode::getCurrentBindings() {
293-
assert(forRepresentativeVar());
294-
295-
if (!Bindings)
296-
Bindings.emplace(CG.getConstraintSystem(), TypeVar);
297-
return *Bindings;
298-
}
299-
300292
void ConstraintGraphNode::introduceToInference(Constraint *constraint) {
301293
if (forRepresentativeVar()) {
302294
auto fixedType = TypeVar->getImpl().getFixedType(/*record=*/nullptr);
303295
if (!fixedType)
304-
getCurrentBindings().infer(constraint);
296+
getCurrentBindings().infer(CG.getConstraintSystem(), TypeVar, constraint);
305297
} else {
306298
auto *repr =
307299
getTypeVariable()->getImpl().getRepresentative(/*record=*/nullptr);
@@ -313,7 +305,7 @@ void ConstraintGraphNode::retractFromInference(Constraint *constraint) {
313305
if (forRepresentativeVar()) {
314306
auto fixedType = TypeVar->getImpl().getFixedType(/*record=*/nullptr);
315307
if (!fixedType)
316-
getCurrentBindings().retract(constraint);
308+
getCurrentBindings().retract(CG.getConstraintSystem(), TypeVar,constraint);
317309
} else {
318310
auto *repr =
319311
getTypeVariable()->getImpl().getRepresentative(/*record=*/nullptr);
@@ -577,12 +569,12 @@ void ConstraintGraph::unrelateTypeVariables(TypeVariableType *typeVar,
577569

578570
void ConstraintGraph::inferBindings(TypeVariableType *typeVar,
579571
Constraint *constraint) {
580-
(*this)[typeVar].getCurrentBindings().infer(constraint);
572+
(*this)[typeVar].getCurrentBindings().infer(CS, typeVar, constraint);
581573
}
582574

583575
void ConstraintGraph::retractBindings(TypeVariableType *typeVar,
584576
Constraint *constraint) {
585-
(*this)[typeVar].getCurrentBindings().retract(constraint);
577+
(*this)[typeVar].getCurrentBindings().retract(CS, typeVar, constraint);
586578
}
587579

588580
#pragma mark Algorithms

0 commit comments

Comments
 (0)