Skip to content

Commit 4cc27c9

Browse files
committed
Sema: Factor out SolverTrail from ConstraintGraph
1 parent c126bab commit 4cc27c9

File tree

8 files changed

+425
-297
lines changed

8 files changed

+425
-297
lines changed

Diff for: include/swift/Sema/CSTrail.h

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//===--- CSTrail.h - Constraint Solver Trail --------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines the \c SolverTrail class, which records the decisions taken
14+
// while attempting to find a solution.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
#ifndef SWIFT_SEMA_CSTRAIL_H
18+
#define SWIFT_SEMA_CSTRAIL_H
19+
20+
#include <vector>
21+
22+
namespace llvm {
23+
class raw_ostream;
24+
}
25+
26+
namespace swift {
27+
28+
class TypeBase;
29+
class TypeVariableType;
30+
31+
namespace constraints {
32+
33+
class Constraint;
34+
class ConstraintGraphScope;
35+
36+
class SolverTrail {
37+
public:
38+
39+
/// The kind of change made to the graph.
40+
enum class ChangeKind {
41+
/// Added a type variable to the constraint graph.
42+
AddedTypeVariable,
43+
/// Added a new constraint to the constraint graph.
44+
AddedConstraint,
45+
/// Removed an existing constraint from the constraint graph.
46+
RemovedConstraint,
47+
/// Extended the equivalence class of a type variable in the constraint graph.
48+
ExtendedEquivalenceClass,
49+
/// Added a fixed binding for a type variable in the constraint graph.
50+
BoundTypeVariable,
51+
};
52+
53+
/// A change made to the constraint system.
54+
///
55+
/// Each change can be undone (once, and in reverse order) by calling the
56+
/// undo() method.
57+
class Change {
58+
public:
59+
/// The kind of change.
60+
ChangeKind Kind;
61+
62+
union {
63+
TypeVariableType *TypeVar;
64+
Constraint *TheConstraint;
65+
66+
struct {
67+
/// The type variable whose equivalence class was extended.
68+
TypeVariableType *TypeVar;
69+
70+
/// The previous size of the equivalence class.
71+
unsigned PrevSize;
72+
} EquivClass;
73+
74+
struct {
75+
/// The type variable being bound to a fixed type.
76+
TypeVariableType *TypeVar;
77+
78+
/// The fixed type to which the type variable was bound.
79+
TypeBase *FixedType;
80+
} Binding;
81+
};
82+
83+
Change() : Kind(ChangeKind::AddedTypeVariable), TypeVar(nullptr) { }
84+
85+
/// Create a change that added a type variable.
86+
static Change addedTypeVariable(TypeVariableType *typeVar);
87+
88+
/// Create a change that added a constraint.
89+
static Change addedConstraint(Constraint *constraint);
90+
91+
/// Create a change that removed a constraint.
92+
static Change removedConstraint(Constraint *constraint);
93+
94+
/// Create a change that extended an equivalence class.
95+
static Change extendedEquivalenceClass(TypeVariableType *typeVar,
96+
unsigned prevSize);
97+
98+
/// Create a change that bound a type variable to a fixed type.
99+
static Change boundTypeVariable(TypeVariableType *typeVar, Type fixed);
100+
101+
/// Undo this change, reverting the constraint graph to the state it
102+
/// had prior to this change.
103+
///
104+
/// Changes must be undone in stack order.
105+
void undo(ConstraintSystem &cs);
106+
};
107+
108+
SolverTrail(ConstraintSystem &cs) : CS(cs) {}
109+
110+
~SolverTrail();
111+
112+
SolverTrail(const SolverTrail &) = delete;
113+
SolverTrail &operator=(const SolverTrail &) = delete;
114+
115+
void recordChange(Change change);
116+
117+
void dumpActiveScopeChanges(llvm::raw_ostream &out,
118+
unsigned indent = 0);
119+
120+
unsigned size() const {
121+
return Changes.size();
122+
}
123+
124+
void undo(unsigned toIndex);
125+
126+
private:
127+
ConstraintSystem &CS;
128+
129+
/// The list of changes made to this constraint system.
130+
std::vector<Change> Changes;
131+
132+
friend class ConstraintGraphScope;
133+
};
134+
135+
} // namespace constraints
136+
} // namespace swift
137+
138+
#endif // SWIFT_SEMA_CSTRAIL_H

Diff for: include/swift/Sema/ConstraintGraph.h

+2-76
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ class ConstraintGraphNode {
216216
friend class ConstraintGraph;
217217
friend class ConstraintSystem;
218218
friend class TypeVariableBinding;
219+
friend class SolverTrail;
219220
};
220221

221222
/// A graph that describes the relationships among the various type variables
@@ -387,7 +388,6 @@ class ConstraintGraph {
387388
/// Print the graph.
388389
void print(ArrayRef<TypeVariableType *> typeVars, llvm::raw_ostream &out);
389390
void dump(llvm::raw_ostream &out);
390-
void dumpActiveScopeChanges(llvm::raw_ostream &out, unsigned indent = 0);
391391

392392
// FIXME: Potentially side-effectful.
393393
SWIFT_DEBUG_HELPER(void dump());
@@ -440,86 +440,12 @@ class ConstraintGraph {
440440
/// to contract constraint graph edges.
441441
void incrementConstraintsPerContractionCounter();
442442

443-
/// The kind of change made to the graph.
444-
enum class ChangeKind {
445-
/// Added a type variable.
446-
AddedTypeVariable,
447-
/// Added a new constraint.
448-
AddedConstraint,
449-
/// Removed an existing constraint
450-
RemovedConstraint,
451-
/// Extended the equivalence class of a type variable.
452-
ExtendedEquivalenceClass,
453-
/// Added a fixed binding for a type variable.
454-
BoundTypeVariable,
455-
};
456-
457-
/// A change made to the constraint graph.
458-
///
459-
/// Each change can be undone (once, and in reverse order) by calling the
460-
/// undo() method.
461-
class Change {
462-
public:
463-
/// The kind of change.
464-
ChangeKind Kind;
465-
466-
union {
467-
TypeVariableType *TypeVar;
468-
Constraint *TheConstraint;
469-
470-
struct {
471-
/// The type variable whose equivalence class was extended.
472-
TypeVariableType *TypeVar;
473-
474-
/// The previous size of the equivalence class.
475-
unsigned PrevSize;
476-
} EquivClass;
477-
478-
struct {
479-
/// The type variable being bound to a fixed type.
480-
TypeVariableType *TypeVar;
481-
482-
/// The fixed type to which the type variable was bound.
483-
TypeBase *FixedType;
484-
} Binding;
485-
};
486-
487-
Change() : Kind(ChangeKind::AddedTypeVariable), TypeVar(nullptr) { }
488-
489-
/// Create a change that added a type variable.
490-
static Change addedTypeVariable(TypeVariableType *typeVar);
491-
492-
/// Create a change that added a constraint.
493-
static Change addedConstraint(Constraint *constraint);
494-
495-
/// Create a change that removed a constraint.
496-
static Change removedConstraint(Constraint *constraint);
497-
498-
/// Create a change that extended an equivalence class.
499-
static Change extendedEquivalenceClass(TypeVariableType *typeVar,
500-
unsigned prevSize);
501-
502-
/// Create a change that bound a type variable to a fixed type.
503-
static Change boundTypeVariable(TypeVariableType *typeVar, Type fixed);
504-
505-
/// Undo this change, reverting the constraint graph to the state it
506-
/// had prior to this change.
507-
///
508-
/// Changes must be undone in stack order.
509-
void undo(ConstraintGraph &cg);
510-
};
511-
512443
/// The currently active scope, or null if we aren't tracking changes made
513444
/// to the constraint graph.
514445
ConstraintGraphScope *ActiveScope = nullptr;
515446

516-
/// The set of changes made to this constraint graph.
517-
///
518-
/// As the constraint graph is extended and mutated, additional changes are
519-
/// introduced into this vector. Each scope
520-
llvm::SmallVector<Change, 4> Changes;
521-
522447
friend class ConstraintGraphScope;
448+
friend class SolverTrail;
523449
};
524450

525451
} // end namespace constraints

Diff for: include/swift/Sema/ConstraintSystem.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "swift/Basic/OptionSet.h"
3333
#include "swift/Sema/CSBindings.h"
3434
#include "swift/Sema/CSFix.h"
35+
#include "swift/Sema/CSTrail.h"
3536
#include "swift/Sema/Constraint.h"
3637
#include "swift/Sema/ConstraintGraph.h"
3738
#include "swift/Sema/ConstraintGraphScope.h"
@@ -63,8 +64,6 @@ enum class TypeCheckExprFlags;
6364

6465
namespace constraints {
6566

66-
class ConstraintGraph;
67-
class ConstraintGraphNode;
6867
class ConstraintSystem;
6968
class SyntacticElementTarget;
7069

@@ -2533,6 +2532,10 @@ class ConstraintSystem {
25332532
/// processing this constraint system.
25342533
SavedTypeVariableBindings savedBindings;
25352534

2535+
/// A log of changes to the constraint system, representing the
2536+
/// current path being explored in the solution space.
2537+
SolverTrail Trail;
2538+
25362539
/// The best solution computed so far.
25372540
std::optional<Score> BestScore;
25382541

@@ -2681,6 +2684,10 @@ class ConstraintSystem {
26812684
favoredConstraints.push_back(constraint);
26822685
}
26832686

2687+
void recordChange(SolverTrail::Change change) {
2688+
Trail.recordChange(change);
2689+
}
2690+
26842691
private:
26852692
/// The list of constraints that have been retired along the
26862693
/// current path, this list is used in LIFO fashion when

Diff for: lib/Sema/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_swift_host_library(swiftSema STATIC
1111
CSSimplify.cpp
1212
CSSolver.cpp
1313
CSStep.cpp
14+
CSTrail.cpp
1415
CSFix.cpp
1516
CSDiagnostics.cpp
1617
CodeSynthesis.cpp

Diff for: lib/Sema/CSSolver.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ void truncate(llvm::SetVector<V> &vector, unsigned newSize) {
568568

569569
ConstraintSystem::SolverState::SolverState(
570570
ConstraintSystem &cs, FreeTypeVariableBinding allowFreeTypeVariables)
571-
: CS(cs), AllowFreeTypeVariables(allowFreeTypeVariables) {
571+
: CS(cs), AllowFreeTypeVariables(allowFreeTypeVariables), Trail(cs) {
572572
assert(!CS.solverState &&
573573
"Constraint system should not already have solver state!");
574574
CS.solverState = this;

Diff for: lib/Sema/CSStep.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,8 @@ template <typename P> class BindingStep : public SolverStep {
550550
ActiveChoice.emplace(std::move(scope), *choice);
551551

552552
if (CS.isDebugMode()) {
553-
auto &log = llvm::errs();
554-
auto &CG = CS.getConstraintGraph();
555-
CG.dumpActiveScopeChanges(log, CS.solverState->getCurrentIndent());
553+
CS.solverState->Trail.dumpActiveScopeChanges(
554+
llvm::errs(), CS.solverState->getCurrentIndent());
556555
}
557556

558557
return suspend(std::make_unique<SplitterStep>(CS, Solutions));

0 commit comments

Comments
 (0)