Skip to content

Commit fe9376d

Browse files
authored
Merge pull request #22082 from xedin/move-weights-to-cs
[ConstraintSystem] Track AST depth information directly
2 parents 2408b3d + e604261 commit fe9376d

File tree

8 files changed

+49
-50
lines changed

8 files changed

+49
-50
lines changed

include/swift/AST/Expr.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -524,10 +524,10 @@ class alignas(8) Expr {
524524
/// the parent map.
525525
llvm::DenseMap<Expr *, Expr *> getParentMap();
526526

527-
/// Produce a mapping from each subexpression to its depth in the root
528-
/// expression. The root expression has depth 0, its children have depth
529-
/// 1, etc.
530-
llvm::DenseMap<Expr *, unsigned> getDepthMap();
527+
/// Produce a mapping from each subexpression to its depth and parent,
528+
/// in the root expression. The root expression has depth 0, its children have
529+
/// depth 1, etc.
530+
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> getDepthMap();
531531

532532
/// Produce a mapping from each expression to its index according to a
533533
/// preorder traversal of the expressions. The parent has index 0, its first

lib/AST/Expr.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -698,17 +698,18 @@ llvm::DenseMap<Expr *, Expr *> Expr::getParentMap() {
698698
return parentMap;
699699
}
700700

701-
llvm::DenseMap<Expr *, unsigned> Expr::getDepthMap() {
701+
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> Expr::getDepthMap() {
702702
class RecordingTraversal : public ASTWalker {
703703
public:
704-
llvm::DenseMap<Expr *, unsigned> &DepthMap;
704+
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> &DepthMap;
705705
unsigned Depth = 0;
706706

707-
explicit RecordingTraversal(llvm::DenseMap<Expr *, unsigned> &depthMap)
708-
: DepthMap(depthMap) { }
707+
explicit RecordingTraversal(
708+
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> &depthMap)
709+
: DepthMap(depthMap) {}
709710

710711
std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
711-
DepthMap[E] = Depth;
712+
DepthMap[E] = {Depth, Parent.getAsExpr()};
712713
Depth++;
713714
return { true, E };
714715
}
@@ -719,7 +720,7 @@ llvm::DenseMap<Expr *, unsigned> Expr::getDepthMap() {
719720
}
720721
};
721722

722-
llvm::DenseMap<Expr *, unsigned> depthMap;
723+
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> depthMap;
723724
RecordingTraversal traversal(depthMap);
724725
walk(traversal);
725726
return depthMap;

lib/Sema/CSRanking.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ static Type getUnlabeledType(Type type, ASTContext &ctx) {
772772
SolutionCompareResult ConstraintSystem::compareSolutions(
773773
ConstraintSystem &cs, ArrayRef<Solution> solutions,
774774
const SolutionDiff &diff, unsigned idx1, unsigned idx2,
775-
llvm::DenseMap<Expr *, unsigned> &weights) {
775+
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> &weights) {
776776
if (cs.TC.getLangOpts().DebugConstraintSolver) {
777777
auto &log = cs.getASTContext().TypeCheckerDebug->getStream();
778778
log.indent(cs.solverState->depth * 2)
@@ -806,7 +806,7 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
806806
if (auto *anchor = locator->getAnchor()) {
807807
auto weight = weights.find(anchor);
808808
if (weight != weights.end())
809-
return weight->getSecond() + 1;
809+
return weight->getSecond().first + 1;
810810
}
811811

812812
return 1;
@@ -1212,7 +1212,6 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
12121212

12131213
Optional<unsigned>
12141214
ConstraintSystem::findBestSolution(SmallVectorImpl<Solution> &viable,
1215-
llvm::DenseMap<Expr *, unsigned> &weights,
12161215
bool minimize) {
12171216
if (viable.empty())
12181217
return None;
@@ -1236,7 +1235,7 @@ ConstraintSystem::findBestSolution(SmallVectorImpl<Solution> &viable,
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 @@ ConstraintSystem::findBestSolution(SmallVectorImpl<Solution> &viable,
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 @@ ConstraintSystem::findBestSolution(SmallVectorImpl<Solution> &viable,
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: 11 additions & 7 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());
@@ -2289,10 +2292,11 @@ bool ConstraintSystem::diagnoseAmbiguity(Expr *expr,
22892292
if (it == indexMap.end())
22902293
continue;
22912294
unsigned index = it->second;
2292-
it = depthMap.find(anchor);
2293-
if (it == depthMap.end())
2295+
2296+
auto e = depthMap.find(anchor);
2297+
if (e == depthMap.end())
22942298
continue;
2295-
unsigned depth = it->second;
2299+
unsigned depth = e->second.first;
22962300

22972301
// If we don't have a name to hang on to, it'll be hard to diagnose this
22982302
// overload.

lib/Sema/ConstraintSystem.h

Lines changed: 13 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 *, unsigned> ExprWeights;
1171-
11721172
/// The constraint system.
11731173
ConstraintSystem &CS;
11741174

@@ -1513,7 +1513,8 @@ class ConstraintSystem {
15131513
};
15141514

15151515
ConstraintSystem(TypeChecker &tc, DeclContext *dc,
1516-
ConstraintSystemOptions options);
1516+
ConstraintSystemOptions options,
1517+
Expr *expr = nullptr);
15171518
~ConstraintSystem();
15181519

15191520
/// Retrieve the type checker associated with this constraint system.
@@ -1563,13 +1564,13 @@ class ConstraintSystem {
15631564
/// set of solutions should be filtered even if there is
15641565
/// no single best solution, see `findBestSolution` for
15651566
/// more details.
1566-
void filterSolutions(SmallVectorImpl<Solution> &solutions,
1567-
llvm::DenseMap<Expr *, unsigned> &weights,
1568-
bool minimize = false) {
1567+
void
1568+
filterSolutions(SmallVectorImpl<Solution> &solutions,
1569+
bool minimize = false) {
15691570
if (solutions.size() < 2)
15701571
return;
15711572

1572-
if (auto best = findBestSolution(solutions, weights, minimize)) {
1573+
if (auto best = findBestSolution(solutions, minimize)) {
15731574
if (*best != 0)
15741575
solutions[0] = std::move(solutions[*best]);
15751576
solutions.erase(solutions.begin() + 1, solutions.end());
@@ -3144,11 +3145,10 @@ class ConstraintSystem {
31443145
/// \param diff The differences among the solutions.
31453146
/// \param idx1 The index of the first solution.
31463147
/// \param idx2 The index of the second solution.
3147-
/// \param weights The weights of the sub-expressions used for ranking.
31483148
static SolutionCompareResult
31493149
compareSolutions(ConstraintSystem &cs, ArrayRef<Solution> solutions,
31503150
const SolutionDiff &diff, unsigned idx1, unsigned idx2,
3151-
llvm::DenseMap<Expr *, unsigned> &weights);
3151+
llvm::DenseMap<Expr *, std::pair<unsigned, Expr *>> &weights);
31523152

31533153
public:
31543154
/// Increase the score of the given kind for the current (partial) solution
@@ -3163,7 +3163,6 @@ class ConstraintSystem {
31633163
/// solution.
31643164
///
31653165
/// \param solutions The set of viable solutions to consider.
3166-
/// \param weights The weights of the sub-expressions used for ranking.
31673166
///
31683167
/// \param minimize If true, then in the case where there is no single
31693168
/// best solution, minimize the set of solutions by removing any solutions
@@ -3172,9 +3171,9 @@ class ConstraintSystem {
31723171
///
31733172
/// \returns The index of the best solution, or nothing if there was no
31743173
/// best solution.
3175-
Optional<unsigned> findBestSolution(SmallVectorImpl<Solution> &solutions,
3176-
llvm::DenseMap<Expr *, unsigned> &weights,
3177-
bool minimize);
3174+
Optional<unsigned>
3175+
findBestSolution(SmallVectorImpl<Solution> &solutions,
3176+
bool minimize);
31783177

31793178
/// Apply a given solution to the expression, producing a fully
31803179
/// type-checked expression.

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)