Skip to content

Commit e604261

Browse files
committed
[ConstraintSystem] Track AST depth information directly
Instead of storing information about expression depths in the solver state (which gets recomputed for salvage) let's track it directly in constraint system, which also gives solver access to it when needed e.g. for fixes.
1 parent 49c40d9 commit e604261

File tree

6 files changed

+28
-38
lines changed

6 files changed

+28
-38
lines changed

lib/Sema/CSRanking.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,10 +1210,9 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
12101210
: SolutionCompareResult::Incomparable;
12111211
}
12121212

1213-
Optional<unsigned> ConstraintSystem::findBestSolution(
1214-
SmallVectorImpl<Solution> &viable,
1215-
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> &weights,
1216-
bool minimize) {
1213+
Optional<unsigned>
1214+
ConstraintSystem::findBestSolution(SmallVectorImpl<Solution> &viable,
1215+
bool minimize) {
12171216
if (viable.empty())
12181217
return None;
12191218
if (viable.size() == 1)
@@ -1236,7 +1235,7 @@ Optional<unsigned> ConstraintSystem::findBestSolution(
12361235
SmallVector<bool, 16> losers(viable.size(), false);
12371236
unsigned bestIdx = 0;
12381237
for (unsigned i = 1, n = viable.size(); i != n; ++i) {
1239-
switch (compareSolutions(*this, viable, diff, i, bestIdx, weights)) {
1238+
switch (compareSolutions(*this, viable, diff, i, bestIdx, ExprWeights)) {
12401239
case SolutionCompareResult::Identical:
12411240
// FIXME: Might want to warn about this in debug builds, so we can
12421241
// find a way to eliminate the redundancy in the search space.
@@ -1260,7 +1259,7 @@ Optional<unsigned> ConstraintSystem::findBestSolution(
12601259
if (i == bestIdx)
12611260
continue;
12621261

1263-
switch (compareSolutions(*this, viable, diff, bestIdx, i, weights)) {
1262+
switch (compareSolutions(*this, viable, diff, bestIdx, i, ExprWeights)) {
12641263
case SolutionCompareResult::Identical:
12651264
// FIXME: Might want to warn about this in debug builds, so we can
12661265
// find a way to eliminate the redundancy in the search space.
@@ -1312,7 +1311,7 @@ Optional<unsigned> ConstraintSystem::findBestSolution(
13121311
if (losers[j])
13131312
continue;
13141313

1315-
switch (compareSolutions(*this, viable, diff, i, j, weights)) {
1314+
switch (compareSolutions(*this, viable, diff, i, j, ExprWeights)) {
13161315
case SolutionCompareResult::Identical:
13171316
// FIXME: Dub one of these the loser arbitrarily?
13181317
break;

lib/Sema/CSSolver.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -327,16 +327,12 @@ void truncate(llvm::SmallSetVector<T, N> &vec, unsigned newSize) {
327327
} // end anonymous namespace
328328

329329
ConstraintSystem::SolverState::SolverState(
330-
Expr *const expr, ConstraintSystem &cs,
331-
FreeTypeVariableBinding allowFreeTypeVariables)
330+
ConstraintSystem &cs, FreeTypeVariableBinding allowFreeTypeVariables)
332331
: CS(cs), AllowFreeTypeVariables(allowFreeTypeVariables) {
333332
assert(!CS.solverState &&
334333
"Constraint system should not already have solver state!");
335334
CS.solverState = this;
336335

337-
if (expr)
338-
ExprWeights = expr->getDepthMap();
339-
340336
++NumSolutionAttempts;
341337
SolutionAttempt = NumSolutionAttempts;
342338

@@ -498,12 +494,12 @@ Optional<Solution>
498494
ConstraintSystem::solveSingle(FreeTypeVariableBinding allowFreeTypeVariables,
499495
bool allowFixes) {
500496

501-
SolverState state(nullptr, *this, allowFreeTypeVariables);
497+
SolverState state(*this, allowFreeTypeVariables);
502498
state.recordFixes = allowFixes;
503499

504500
SmallVector<Solution, 4> solutions;
505501
solve(solutions);
506-
filterSolutions(solutions, state.ExprWeights);
502+
filterSolutions(solutions);
507503

508504
if (solutions.size() != 1)
509505
return Optional<Solution>();
@@ -538,7 +534,7 @@ bool ConstraintSystem::Candidate::solve(
538534
};
539535

540536
// Allocate new constraint system for sub-expression.
541-
ConstraintSystem cs(TC, DC, None);
537+
ConstraintSystem cs(TC, DC, None, E);
542538
cs.baseCS = &BaseCS;
543539

544540
// Set up expression type checker timer for the candidate.
@@ -589,7 +585,7 @@ bool ConstraintSystem::Candidate::solve(
589585
// Try to solve the system and record all available solutions.
590586
llvm::SmallVector<Solution, 2> solutions;
591587
{
592-
SolverState state(E, cs, FreeTypeVariableBinding::Allow);
588+
SolverState state(cs, FreeTypeVariableBinding::Allow);
593589

594590
// Use solve which doesn't try to filter solution list.
595591
// Because we want the whole set of possible domain choices.
@@ -1179,7 +1175,7 @@ bool ConstraintSystem::solve(Expr *const expr,
11791175
SmallVectorImpl<Solution> &solutions,
11801176
FreeTypeVariableBinding allowFreeTypeVariables) {
11811177
// Set up solver state.
1182-
SolverState state(expr, *this, allowFreeTypeVariables);
1178+
SolverState state(*this, allowFreeTypeVariables);
11831179

11841180
// Solve the system.
11851181
solve(solutions);
@@ -1200,7 +1196,7 @@ bool ConstraintSystem::solve(Expr *const expr,
12001196
// a single best solution to use, if not explicitly disabled
12011197
// by constraint system options.
12021198
if (!retainAllSolutions())
1203-
filterSolutions(solutions, state.ExprWeights);
1199+
filterSolutions(solutions);
12041200

12051201
// We fail if there is no solution or the expression was too complex.
12061202
return solutions.empty() || getExpressionTooComplex(solutions);

lib/Sema/CSStep.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ class SolverStep {
227227

228228
void filterSolutions(SmallVectorImpl<Solution> &solutions, bool minimize) {
229229
if (!CS.retainAllSolutions())
230-
CS.filterSolutions(solutions, CS.solverState->ExprWeights, minimize);
230+
CS.filterSolutions(solutions, minimize);
231231
}
232232

233233
/// Check whether constraint solver is running in "debug" mode,

lib/Sema/ConstraintSystem.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,15 @@ ExpressionTimer::~ExpressionTimer() {
7070
}
7171

7272
ConstraintSystem::ConstraintSystem(TypeChecker &tc, DeclContext *dc,
73-
ConstraintSystemOptions options)
73+
ConstraintSystemOptions options,
74+
Expr *expr)
7475
: TC(tc), DC(dc), Options(options),
7576
Arena(tc.Context, Allocator),
7677
CG(*new ConstraintGraph(*this))
7778
{
79+
if (expr)
80+
ExprWeights = expr->getDepthMap();
81+
7882
assert(DC && "context required");
7983
}
8084

@@ -2063,16 +2067,15 @@ bool ConstraintSystem::salvage(SmallVectorImpl<Solution> &viable, Expr *expr) {
20632067

20642068
{
20652069
// Set up solver state.
2066-
SolverState state(expr, *this, FreeTypeVariableBinding::Disallow);
2070+
SolverState state(*this, FreeTypeVariableBinding::Disallow);
20672071
state.recordFixes = true;
20682072

20692073
// Solve the system.
20702074
solve(viable);
20712075

20722076
// Check whether we have a best solution; this can happen if we found
20732077
// a series of fixes that worked.
2074-
if (auto best = findBestSolution(viable, state.ExprWeights,
2075-
/*minimize=*/true)) {
2078+
if (auto best = findBestSolution(viable, /*minimize=*/true)) {
20762079
if (*best != 0)
20772080
viable[0] = std::move(viable[*best]);
20782081
viable.erase(viable.begin() + 1, viable.end());

lib/Sema/ConstraintSystem.h

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,8 @@ class ConstraintSystem {
962962

963963
private:
964964

965+
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> ExprWeights;
966+
965967
/// Allocator used for all of the related constraint systems.
966968
llvm::BumpPtrAllocator Allocator;
967969

@@ -1163,12 +1165,10 @@ class ConstraintSystem {
11631165

11641166
/// Describes the current solver state.
11651167
struct SolverState {
1166-
SolverState(Expr *const expr, ConstraintSystem &cs,
1168+
SolverState(ConstraintSystem &cs,
11671169
FreeTypeVariableBinding allowFreeTypeVariables);
11681170
~SolverState();
11691171

1170-
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> ExprWeights;
1171-
11721172
/// The constraint system.
11731173
ConstraintSystem &CS;
11741174

@@ -1315,11 +1315,6 @@ class ConstraintSystem {
13151315
return AllowFreeTypeVariables != FreeTypeVariableBinding::Disallow;
13161316
}
13171317

1318-
Expr *getParentExpr(Expr *expr) {
1319-
const auto &e = ExprWeights.find(expr);
1320-
return (e != ExprWeights.end()) ? e->second.second : nullptr;
1321-
}
1322-
13231318
private:
13241319
/// The list of constraints that have been retired along the
13251320
/// current path, this list is used in LIFO fashion when constraints
@@ -1518,7 +1513,8 @@ class ConstraintSystem {
15181513
};
15191514

15201515
ConstraintSystem(TypeChecker &tc, DeclContext *dc,
1521-
ConstraintSystemOptions options);
1516+
ConstraintSystemOptions options,
1517+
Expr *expr = nullptr);
15221518
~ConstraintSystem();
15231519

15241520
/// Retrieve the type checker associated with this constraint system.
@@ -1570,12 +1566,11 @@ class ConstraintSystem {
15701566
/// more details.
15711567
void
15721568
filterSolutions(SmallVectorImpl<Solution> &solutions,
1573-
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> &weights,
15741569
bool minimize = false) {
15751570
if (solutions.size() < 2)
15761571
return;
15771572

1578-
if (auto best = findBestSolution(solutions, weights, minimize)) {
1573+
if (auto best = findBestSolution(solutions, minimize)) {
15791574
if (*best != 0)
15801575
solutions[0] = std::move(solutions[*best]);
15811576
solutions.erase(solutions.begin() + 1, solutions.end());
@@ -3150,7 +3145,6 @@ class ConstraintSystem {
31503145
/// \param diff The differences among the solutions.
31513146
/// \param idx1 The index of the first solution.
31523147
/// \param idx2 The index of the second solution.
3153-
/// \param weights The weights of the sub-expressions used for ranking.
31543148
static SolutionCompareResult
31553149
compareSolutions(ConstraintSystem &cs, ArrayRef<Solution> solutions,
31563150
const SolutionDiff &diff, unsigned idx1, unsigned idx2,
@@ -3169,7 +3163,6 @@ class ConstraintSystem {
31693163
/// solution.
31703164
///
31713165
/// \param solutions The set of viable solutions to consider.
3172-
/// \param weights The weights of the sub-expressions used for ranking.
31733166
///
31743167
/// \param minimize If true, then in the case where there is no single
31753168
/// best solution, minimize the set of solutions by removing any solutions
@@ -3180,7 +3173,6 @@ class ConstraintSystem {
31803173
/// best solution.
31813174
Optional<unsigned>
31823175
findBestSolution(SmallVectorImpl<Solution> &solutions,
3183-
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> &weights,
31843176
bool minimize);
31853177

31863178
/// Apply a given solution to the expression, producing a fully

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2066,7 +2066,7 @@ Type TypeChecker::typeCheckExpressionImpl(Expr *&expr, DeclContext *dc,
20662066
if (options.contains(TypeCheckExprFlags::AllowUnresolvedTypeVariables))
20672067
csOptions |= ConstraintSystemFlags::AllowUnresolvedTypeVariables;
20682068

2069-
ConstraintSystem cs(*this, dc, csOptions);
2069+
ConstraintSystem cs(*this, dc, csOptions, expr);
20702070
cs.baseCS = baseCS;
20712071

20722072
// Verify that a purpose was specified if a convertType was. Note that it is

0 commit comments

Comments
 (0)