Skip to content

Commit fd253da

Browse files
authored
Merge pull request #11078 from xedin/shrink-memory-leak
[ConstraintSolver] NFC: refactor candidate solver to use constraint system arena
2 parents 70b836b + 7a1bae8 commit fd253da

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)