Skip to content

Commit 8ee4eee

Browse files
committed
Sema: Migrate SavedTypeVariableBindings to SolverTrail
1 parent 4cc27c9 commit 8ee4eee

File tree

7 files changed

+104
-114
lines changed

7 files changed

+104
-114
lines changed

include/swift/Sema/CSTrail.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class SolverTrail {
4848
ExtendedEquivalenceClass,
4949
/// Added a fixed binding for a type variable in the constraint graph.
5050
BoundTypeVariable,
51+
/// Set the fixed type or parent and flags for a type variable.
52+
UpdatedTypeVariable,
5153
};
5254

5355
/// A change made to the constraint system.
@@ -78,6 +80,17 @@ class SolverTrail {
7880
/// The fixed type to which the type variable was bound.
7981
TypeBase *FixedType;
8082
} Binding;
83+
84+
struct {
85+
/// The type variable being updated.
86+
TypeVariableType *TypeVar;
87+
88+
/// The representative of the equivalence class, or the fixed type.
89+
llvm::PointerUnion<TypeVariableType *, TypeBase *> ParentOrFixed;
90+
91+
/// The saved value of TypeVariableType::Implementation::getRawOptions().
92+
unsigned Options;
93+
} Update;
8194
};
8295

8396
Change() : Kind(ChangeKind::AddedTypeVariable), TypeVar(nullptr) { }
@@ -98,6 +111,12 @@ class SolverTrail {
98111
/// Create a change that bound a type variable to a fixed type.
99112
static Change boundTypeVariable(TypeVariableType *typeVar, Type fixed);
100113

114+
/// Create a change that updated a type variable.
115+
static Change updatedTypeVariable(
116+
TypeVariableType *typeVar,
117+
llvm::PointerUnion<TypeVariableType *, TypeBase *> parentOrFixed,
118+
unsigned options);
119+
101120
/// Undo this change, reverting the constraint graph to the state it
102121
/// had prior to this change.
103122
///

include/swift/Sema/ConstraintSystem.h

Lines changed: 45 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -200,28 +200,6 @@ enum class TrailingClosureMatching {
200200
Backward,
201201
};
202202

203-
/// A handle that holds the saved state of a type variable, which
204-
/// can be restored.
205-
class SavedTypeVariableBinding {
206-
/// The type variable that we saved the state of.
207-
TypeVariableType *TypeVar;
208-
209-
/// The saved type variable options.
210-
unsigned Options;
211-
212-
/// The parent or fixed type.
213-
llvm::PointerUnion<TypeVariableType *, TypeBase *> ParentOrFixed;
214-
215-
public:
216-
explicit SavedTypeVariableBinding(TypeVariableType *typeVar);
217-
218-
/// Restore the state of the type variable to the saved state.
219-
void restore();
220-
};
221-
222-
/// A set of saved type variable bindings.
223-
using SavedTypeVariableBindings = SmallVector<SavedTypeVariableBinding, 16>;
224-
225203
class ConstraintLocator;
226204

227205
/// Describes a conversion restriction or a fix.
@@ -369,7 +347,7 @@ class TypeVariableType::Implementation {
369347
/// constraint graph.
370348
unsigned GraphIndex;
371349

372-
friend class constraints::SavedTypeVariableBinding;
350+
friend class constraints::SolverTrail;
373351

374352
public:
375353
/// Retrieve the type variable associated with this implementation.
@@ -457,8 +435,9 @@ class TypeVariableType::Implementation {
457435
}
458436

459437
/// Record the current type-variable binding.
460-
void recordBinding(constraints::SavedTypeVariableBindings &record) {
461-
record.push_back(constraints::SavedTypeVariableBinding(getTypeVariable()));
438+
void recordBinding(constraints::SolverTrail &trail) {
439+
trail.recordChange(constraints::SolverTrail::Change::updatedTypeVariable(
440+
getTypeVariable(), ParentOrFixed, getRawOptions()));
462441
}
463442

464443
/// Retrieve the locator describing where this type variable was
@@ -525,11 +504,11 @@ class TypeVariableType::Implementation {
525504
/// Retrieve the representative of the equivalence class to which this
526505
/// type variable belongs.
527506
///
528-
/// \param record The record of changes made by retrieving the representative,
507+
/// \param trail The record of changes made by retrieving the representative,
529508
/// which can happen due to path compression. If null, path compression is
530509
/// not performed.
531510
TypeVariableType *
532-
getRepresentative(constraints::SavedTypeVariableBindings *record) {
511+
getRepresentative(constraints::SolverTrail *trail) {
533512
// Find the representative type variable.
534513
auto result = getTypeVariable();
535514
Implementation *impl = this;
@@ -543,7 +522,7 @@ class TypeVariableType::Implementation {
543522
impl = &nextTV->getImpl();
544523
}
545524

546-
if (impl == this || !record)
525+
if (impl == this || !trail)
547526
return result;
548527

549528
// Perform path compression.
@@ -555,7 +534,7 @@ class TypeVariableType::Implementation {
555534
break;
556535

557536
// Record the state change.
558-
impl->recordBinding(*record);
537+
impl->recordBinding(*trail);
559538

560539
impl->ParentOrFixed = result;
561540
impl = &nextTV->getImpl();
@@ -569,36 +548,36 @@ class TypeVariableType::Implementation {
569548
///
570549
/// \param other The type variable to merge with.
571550
///
572-
/// \param record The record of state changes.
551+
/// \param trail The record of state changes.
573552
void mergeEquivalenceClasses(TypeVariableType *other,
574-
constraints::SavedTypeVariableBindings *record) {
553+
constraints::SolverTrail *trail) {
575554
// Merge the equivalence classes corresponding to these two type
576555
// variables. Always merge 'up' the constraint stack, because it is simpler.
577556
if (getID() > other->getImpl().getID()) {
578-
other->getImpl().mergeEquivalenceClasses(getTypeVariable(), record);
557+
other->getImpl().mergeEquivalenceClasses(getTypeVariable(), trail);
579558
return;
580559
}
581560

582-
auto otherRep = other->getImpl().getRepresentative(record);
583-
if (record)
584-
otherRep->getImpl().recordBinding(*record);
561+
auto otherRep = other->getImpl().getRepresentative(trail);
562+
if (trail)
563+
otherRep->getImpl().recordBinding(*trail);
585564
otherRep->getImpl().ParentOrFixed = getTypeVariable();
586565

587566
if (canBindToLValue() && !otherRep->getImpl().canBindToLValue()) {
588-
if (record)
589-
recordBinding(*record);
567+
if (trail)
568+
recordBinding(*trail);
590569
getTypeVariable()->Bits.TypeVariableType.Options &= ~TVO_CanBindToLValue;
591570
}
592571

593572
if (canBindToInOut() && !otherRep->getImpl().canBindToInOut()) {
594-
if (record)
595-
recordBinding(*record);
573+
if (trail)
574+
recordBinding(*trail);
596575
getTypeVariable()->Bits.TypeVariableType.Options &= ~TVO_CanBindToInOut;
597576
}
598577

599578
if (canBindToNoEscape() && !otherRep->getImpl().canBindToNoEscape()) {
600-
if (record)
601-
recordBinding(*record);
579+
if (trail)
580+
recordBinding(*trail);
602581
getTypeVariable()->Bits.TypeVariableType.Options &= ~TVO_CanBindToNoEscape;
603582
}
604583
}
@@ -609,12 +588,12 @@ class TypeVariableType::Implementation {
609588
/// \returns the fixed type associated with this type variable, or a null
610589
/// type if there is no fixed type.
611590
///
612-
/// \param record The record of changes made by retrieving the representative,
591+
/// \param trail The record of changes made by retrieving the representative,
613592
/// which can happen due to path compression. If null, path compression is
614593
/// not performed.
615-
Type getFixedType(constraints::SavedTypeVariableBindings *record) {
594+
Type getFixedType(constraints::SolverTrail *trail) {
616595
// Find the representative type variable.
617-
auto rep = getRepresentative(record);
596+
auto rep = getRepresentative(trail);
618597
Implementation &repImpl = rep->getImpl();
619598

620599
// Return the bound type if there is one, otherwise, null.
@@ -623,20 +602,21 @@ class TypeVariableType::Implementation {
623602

624603
/// Assign a fixed type to this equivalence class.
625604
void assignFixedType(Type type,
626-
constraints::SavedTypeVariableBindings *record) {
627-
assert((!getFixedType(0) || getFixedType(0)->isEqual(type)) &&
605+
constraints::SolverTrail *trail) {
606+
assert((!getFixedType(nullptr) ||
607+
getFixedType(nullptr)->isEqual(type)) &&
628608
"Already has a fixed type!");
629-
auto rep = getRepresentative(record);
630-
if (record)
631-
rep->getImpl().recordBinding(*record);
609+
auto rep = getRepresentative(trail);
610+
if (trail)
611+
rep->getImpl().recordBinding(*trail);
632612
rep->getImpl().ParentOrFixed = type.getPointer();
633613
}
634614

635-
void setCanBindToLValue(constraints::SavedTypeVariableBindings *record,
615+
void setCanBindToLValue(constraints::SolverTrail *trail,
636616
bool enabled) {
637-
auto &impl = getRepresentative(record)->getImpl();
638-
if (record)
639-
impl.recordBinding(*record);
617+
auto &impl = getRepresentative(trail)->getImpl();
618+
if (trail)
619+
impl.recordBinding(*trail);
640620

641621
if (enabled)
642622
impl.getTypeVariable()->Bits.TypeVariableType.Options |=
@@ -646,11 +626,11 @@ class TypeVariableType::Implementation {
646626
~TVO_CanBindToLValue;
647627
}
648628

649-
void setCanBindToNoEscape(constraints::SavedTypeVariableBindings *record,
629+
void setCanBindToNoEscape(constraints::SolverTrail *trail,
650630
bool enabled) {
651-
auto &impl = getRepresentative(record)->getImpl();
652-
if (record)
653-
impl.recordBinding(*record);
631+
auto &impl = getRepresentative(trail)->getImpl();
632+
if (trail)
633+
impl.recordBinding(*trail);
654634

655635
if (enabled)
656636
impl.getTypeVariable()->Bits.TypeVariableType.Options |=
@@ -660,10 +640,10 @@ class TypeVariableType::Implementation {
660640
~TVO_CanBindToNoEscape;
661641
}
662642

663-
void enableCanBindToHole(constraints::SavedTypeVariableBindings *record) {
664-
auto &impl = getRepresentative(record)->getImpl();
665-
if (record)
666-
impl.recordBinding(*record);
643+
void enableCanBindToHole(constraints::SolverTrail *trail) {
644+
auto &impl = getRepresentative(trail)->getImpl();
645+
if (trail)
646+
impl.recordBinding(*trail);
667647

668648
impl.getTypeVariable()->Bits.TypeVariableType.Options |= TVO_CanBindToHole;
669649
}
@@ -2528,10 +2508,6 @@ class ConstraintSystem {
25282508
/// Whether to record failures or not.
25292509
bool recordFixes = false;
25302510

2531-
/// The set of type variable bindings that have changed while
2532-
/// processing this constraint system.
2533-
SavedTypeVariableBindings savedBindings;
2534-
25352511
/// A log of changes to the constraint system, representing the
25362512
/// current path being explored in the solution space.
25372513
SolverTrail Trail;
@@ -3072,18 +3048,11 @@ class ConstraintSystem {
30723048
}
30733049
}
30743050

3075-
/// Restore the type variable bindings to what they were before
3076-
/// we attempted to solve this constraint system.
3077-
///
3078-
/// \param numBindings The number of bindings to restore, from the end of
3079-
/// the saved-binding stack.
3080-
void restoreTypeVariableBindings(unsigned numBindings);
3081-
30823051
/// Retrieve the set of saved type variable bindings, if available.
30833052
///
30843053
/// \returns null when we aren't currently solving the system.
3085-
SavedTypeVariableBindings *getSavedBindings() const {
3086-
return solverState ? &solverState->savedBindings : nullptr;
3054+
SolverTrail *getTrail() const {
3055+
return solverState ? &solverState->Trail : nullptr;
30873056
}
30883057

30893058
/// Add a new type variable that was already created.
@@ -4090,7 +4059,7 @@ class ConstraintSystem {
40904059
/// Retrieve the representative of the equivalence class containing
40914060
/// this type variable.
40924061
TypeVariableType *getRepresentative(TypeVariableType *typeVar) const {
4093-
return typeVar->getImpl().getRepresentative(getSavedBindings());
4062+
return typeVar->getImpl().getRepresentative(getTrail());
40944063
}
40954064

40964065
/// Find if the given type variable is representative for a type
@@ -4153,7 +4122,7 @@ class ConstraintSystem {
41534122
/// Retrieve the fixed type corresponding to the given type variable,
41544123
/// or a null type if there is no fixed type.
41554124
Type getFixedType(TypeVariableType *typeVar) const {
4156-
return typeVar->getImpl().getFixedType(getSavedBindings());
4125+
return typeVar->getImpl().getFixedType(getTrail());
41574126
}
41584127

41594128
/// Retrieve the fixed type corresponding to a given type variable,

lib/Sema/CSSimplify.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4429,11 +4429,11 @@ ConstraintSystem::matchTypesBindTypeVar(
44294429
type.visit([&](Type t) {
44304430
if (auto *tvt = dyn_cast<TypeVariableType>(t.getPointer())) {
44314431
if (!typeVar->getImpl().canBindToLValue()) {
4432-
tvt->getImpl().setCanBindToLValue(getSavedBindings(),
4432+
tvt->getImpl().setCanBindToLValue(getTrail(),
44334433
/*enabled=*/false);
44344434
}
44354435
if (!typeVar->getImpl().canBindToNoEscape()) {
4436-
tvt->getImpl().setCanBindToNoEscape(getSavedBindings(),
4436+
tvt->getImpl().setCanBindToNoEscape(getTrail(),
44374437
/*enabled=*/false);
44384438
}
44394439
}
@@ -14894,7 +14894,7 @@ bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact) {
1489414894
}
1489514895

1489614896
void ConstraintSystem::recordPotentialHole(TypeVariableType *typeVar) {
14897-
typeVar->getImpl().enableCanBindToHole(getSavedBindings());
14897+
typeVar->getImpl().enableCanBindToHole(getTrail());
1489814898
}
1489914899

1490014900
void ConstraintSystem::recordAnyTypeVarAsPotentialHole(Type type) {
@@ -14903,7 +14903,7 @@ void ConstraintSystem::recordAnyTypeVarAsPotentialHole(Type type) {
1490314903

1490414904
type.visit([&](Type type) {
1490514905
if (auto *typeVar = type->getAs<TypeVariableType>()) {
14906-
typeVar->getImpl().enableCanBindToHole(getSavedBindings());
14906+
typeVar->getImpl().enableCanBindToHole(getTrail());
1490714907
}
1490814908
});
1490914909
}

lib/Sema/CSSolver.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -421,19 +421,6 @@ void ConstraintSystem::applySolution(const Solution &solution) {
421421
// Register any fixes produced along this path.
422422
Fixes.insert(solution.Fixes.begin(), solution.Fixes.end());
423423
}
424-
425-
/// Restore the type variable bindings to what they were before
426-
/// we attempted to solve this constraint system.
427-
void ConstraintSystem::restoreTypeVariableBindings(unsigned numBindings) {
428-
auto &savedBindings = *getSavedBindings();
429-
std::for_each(savedBindings.rbegin(), savedBindings.rbegin() + numBindings,
430-
[](SavedTypeVariableBinding &saved) {
431-
saved.restore();
432-
});
433-
savedBindings.erase(savedBindings.end() - numBindings,
434-
savedBindings.end());
435-
}
436-
437424
bool ConstraintSystem::simplify() {
438425
// While we have a constraint in the worklist, process it.
439426
while (!ActiveConstraints.empty()) {
@@ -664,7 +651,6 @@ ConstraintSystem::SolverScope::SolverScope(ConstraintSystem &cs)
664651
: cs(cs), CGScope(cs.CG)
665652
{
666653
numTypeVariables = cs.TypeVariables.size();
667-
numSavedBindings = cs.solverState->savedBindings.size();
668654
numConstraintRestrictions = cs.ConstraintRestrictions.size();
669655
numFixes = cs.Fixes.size();
670656
numFixedRequirements = cs.FixedRequirements.size();
@@ -716,10 +702,6 @@ ConstraintSystem::SolverScope::~SolverScope() {
716702

717703
truncate(cs.ResolvedOverloads, numResolvedOverloads);
718704

719-
// Restore bindings.
720-
cs.restoreTypeVariableBindings(cs.solverState->savedBindings.size() -
721-
numSavedBindings);
722-
723705
// Move any remaining active constraints into the inactive list.
724706
if (!cs.ActiveConstraints.empty()) {
725707
for (auto &constraint : cs.ActiveConstraints) {

0 commit comments

Comments
 (0)