Skip to content

Commit 7a1bae8

Browse files
committed
[ConstraintSolver] NFC: refactor candidate solver to use constraint system arena
While shrinking we have to allocate containers for the reduced domains for some of the candidates, it's currently done using permanent arena of the `ASTContext` allocator. This patch changes candidate solver to use arena associated with the parent constraint system, which significantly limits lifetime of domain containers.
1 parent bb4fd09 commit 7a1bae8

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ ConstraintSystem::solveSingle(FreeTypeVariableBinding allowFreeTypeVariables) {
765765
}
766766

767767
bool ConstraintSystem::Candidate::solve(
768-
llvm::SmallDenseSet<Expr *> &shrunkExprs) {
768+
llvm::SmallDenseSet<OverloadSetRefExpr *> &shrunkExprs) {
769769
// Don't attempt to solve candidate if there is closure
770770
// expression involved, because it's handled specially
771771
// by parent constraint system (e.g. parameter lists).
@@ -879,7 +879,7 @@ bool ConstraintSystem::Candidate::solve(
879879

880880
void ConstraintSystem::Candidate::applySolutions(
881881
llvm::SmallVectorImpl<Solution> &solutions,
882-
llvm::SmallDenseSet<Expr *> &shrunkExprs) const {
882+
llvm::SmallDenseSet<OverloadSetRefExpr *> &shrunkExprs) const {
883883
// A collection of OSRs with their newly reduced domains,
884884
// it's domains are sets because multiple solutions can have the same
885885
// choice for one of the type variables, and we want no duplication.
@@ -922,8 +922,10 @@ void ConstraintSystem::Candidate::applySolutions(
922922
if (OSR->getDecls().size() == choices.size()) continue;
923923

924924
// Update the expression with the reduced domain.
925-
MutableArrayRef<ValueDecl *> decls
926-
= TC.Context.AllocateUninitialized<ValueDecl *>(choices.size());
925+
MutableArrayRef<ValueDecl *> decls(
926+
Allocator.Allocate<ValueDecl *>(choices.size()),
927+
choices.size());
928+
927929
std::uninitialized_copy(choices.begin(), choices.end(), decls.begin());
928930
OSR->setDecls(decls);
929931

@@ -1238,7 +1240,7 @@ void ConstraintSystem::shrink(Expr *expr) {
12381240
// so we can start solving them separately.
12391241
expr->walk(collector);
12401242

1241-
llvm::SmallDenseSet<Expr *> shrunkExprs;
1243+
llvm::SmallDenseSet<OverloadSetRefExpr *> shrunkExprs;
12421244
for (auto &candidate : collector.Candidates) {
12431245
// If there are no results, let's forget everything we know about the
12441246
// system so far. This actually is ok, because some of the expressions
@@ -1261,6 +1263,17 @@ void ConstraintSystem::shrink(Expr *expr) {
12611263
});
12621264
}
12631265
}
1266+
1267+
// Once "shrinking" is done let's re-allocate final version of
1268+
// the candidate list to the permanent arena, so it could
1269+
// survive even after primary constraint system is destroyed.
1270+
for (auto &OSR : shrunkExprs) {
1271+
auto choices = OSR->getDecls();
1272+
auto decls = TC.Context.AllocateUninitialized<ValueDecl *>(choices.size());
1273+
1274+
std::uninitialized_copy(choices.begin(), choices.end(), decls.begin());
1275+
OSR->setDecls(decls);
1276+
}
12641277
}
12651278

12661279
ConstraintSystem::SolutionKind

lib/Sema/ConstraintSystem.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,7 @@ class ConstraintSystem {
10181018
Expr *E;
10191019
TypeChecker &TC;
10201020
DeclContext *DC;
1021+
llvm::BumpPtrAllocator &Allocator;
10211022

10221023
// Contextual Information.
10231024
Type CT;
@@ -1026,7 +1027,8 @@ class ConstraintSystem {
10261027
public:
10271028
Candidate(ConstraintSystem &cs, Expr *expr, Type ct = Type(),
10281029
ContextualTypePurpose ctp = ContextualTypePurpose::CTP_Unused)
1029-
: E(expr), TC(cs.TC), DC(cs.DC), CT(ct), CTP(ctp) {}
1030+
: E(expr), TC(cs.TC), DC(cs.DC), Allocator(cs.Allocator), CT(ct),
1031+
CTP(ctp) {}
10301032

10311033
/// \brief Return underlying expression.
10321034
Expr *getExpr() const { return E; }
@@ -1038,7 +1040,7 @@ class ConstraintSystem {
10381040
/// domains have been successfully shrunk so far.
10391041
///
10401042
/// \returns true on solver failure, false otherwise.
1041-
bool solve(llvm::SmallDenseSet<Expr *> &shrunkExprs);
1043+
bool solve(llvm::SmallDenseSet<OverloadSetRefExpr *> &shrunkExprs);
10421044

10431045
/// \brief Apply solutions found by solver as reduced OSR sets for
10441046
/// for current and all of it's sub-expressions.
@@ -1048,14 +1050,16 @@ class ConstraintSystem {
10481050
///
10491051
/// \param shrunkExprs The set of expressions which
10501052
/// domains have been successfully shrunk so far.
1051-
void applySolutions(llvm::SmallVectorImpl<Solution> &solutions,
1052-
llvm::SmallDenseSet<Expr *> &shrunkExprs) const;
1053+
void applySolutions(
1054+
llvm::SmallVectorImpl<Solution> &solutions,
1055+
llvm::SmallDenseSet<OverloadSetRefExpr *> &shrunkExprs) const;
10531056

10541057
/// Check if attempt at solving of the candidate makes sense given
10551058
/// the current conditions - number of shrunk domains which is related
10561059
/// to the given candidate over the total number of disjunctions present.
1057-
static bool isTooComplexGiven(ConstraintSystem *const cs,
1058-
llvm::SmallDenseSet<Expr *> &shrunkExprs) {
1060+
static bool
1061+
isTooComplexGiven(ConstraintSystem *const cs,
1062+
llvm::SmallDenseSet<OverloadSetRefExpr *> &shrunkExprs) {
10591063
SmallVector<Constraint *, 8> disjunctions;
10601064
cs->collectDisjunctions(disjunctions);
10611065

@@ -1066,7 +1070,11 @@ class ConstraintSystem {
10661070
continue;
10671071

10681072
if (auto *anchor = locator->getAnchor()) {
1069-
if (shrunkExprs.count(anchor) > 0)
1073+
auto *OSR = dyn_cast<OverloadSetRefExpr>(anchor);
1074+
if (!OSR)
1075+
continue;
1076+
1077+
if (shrunkExprs.count(OSR) > 0)
10701078
--unsolvedDisjunctions;
10711079
}
10721080
}

0 commit comments

Comments
 (0)