Merge pull request #19392 from xedin/use-unique_ptr-for-worklist
[CSStep] Switch to use `std::unique_ptr` for work list
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 564da3e..5b1f047 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -19,6 +19,7 @@
#include "TypeCheckType.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/TypeWalker.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Compiler.h"
@@ -1226,15 +1227,9 @@
void ConstraintSystem::solve(SmallVectorImpl<Solution> &solutions) {
assert(solverState);
- SmallVector<SolverStep *, 16> workList;
+ SmallVector<std::unique_ptr<SolverStep>, 16> workList;
// First step is always wraps whole constraint system.
- workList.push_back(SplitterStep::create(*this, solutions));
-
- SWIFT_DEFER {
- // Delete all of the leftover steps from the work list.
- while (!workList.empty())
- delete workList.pop_back_val();
- };
+ workList.push_back(llvm::make_unique<SplitterStep>(*this, solutions));
// Indicate whether previous step in the stack has failed
// (returned StepResult::Kind = Error), this is useful to
@@ -1264,7 +1259,7 @@
// a solution, or producing another set of mergeable
// steps to take before arriving to solution.
while (!workList.empty()) {
- auto *step = workList.back();
+ auto &step = workList.back();
// Now let's try to advance to the next step or re-take previous,
// which should produce another steps to follow,
@@ -1274,7 +1269,7 @@
step->getState() == StepState::Done) &&
"Cannot re-take already running/done step.");
- auto result = advance(step, prevFailed);
+ auto result = advance(step.get(), prevFailed);
switch (result.getKind()) {
// It was impossible to solve this step, let's note that
// for followup steps, to propogate the error.
@@ -1286,7 +1281,6 @@
// toward that solution.
case SolutionKind::Solved: {
workList.pop_back();
- delete step;
break;
}
diff --git a/lib/Sema/CSStep.cpp b/lib/Sema/CSStep.cpp
index a2c0512..6af164c 100644
--- a/lib/Sema/CSStep.cpp
+++ b/lib/Sema/CSStep.cpp
@@ -49,7 +49,7 @@
if (prevFailed || CS.failedConstraint || CS.simplify())
return done(/*isSuccess=*/false);
- SmallVector<ComponentStep *, 4> components;
+ SmallVector<std::unique_ptr<ComponentStep>, 4> components;
// Try to run "connected components" algorithm and split
// type variables and their constraints into independent
// sub-systems to solve.
@@ -59,10 +59,14 @@
// try to merge solutions, "split" step should be considered
// done and replaced by a single component step.
if (components.size() < 2)
- return replaceWith(components.front());
+ return replaceWith(std::move(components.front()));
+
+ SmallVector<std::unique_ptr<SolverStep>, 4> followup;
+ for (auto &step : components)
+ followup.push_back(std::move(step));
/// Wait until all of the component steps are done.
- return suspend<ComponentStep>(components);
+ return suspend(followup);
}
StepResult SplitterStep::resume(bool prevFailed) {
@@ -83,7 +87,7 @@
}
void SplitterStep::computeFollowupSteps(
- SmallVectorImpl<ComponentStep *> &componentSteps) {
+ SmallVectorImpl<std::unique_ptr<ComponentStep>> &componentSteps) {
// Compute next steps based on that connected components
// algorithm tells us is splittable.
@@ -99,7 +103,7 @@
SmallVector<unsigned, 16> components;
unsigned numComponents = CG.computeConnectedComponents(typeVars, components);
if (numComponents < 2) {
- componentSteps.push_back(ComponentStep::create(
+ componentSteps.push_back(llvm::make_unique<ComponentStep>(
CS, 0, /*single=*/true, &CS.InactiveConstraints, Solutions));
return;
}
@@ -109,7 +113,7 @@
new SmallVector<Solution, 4>[numComponents]);
for (unsigned i = 0, n = numComponents; i != n; ++i) {
- componentSteps.push_back(ComponentStep::create(
+ componentSteps.push_back(llvm::make_unique<ComponentStep>(
CS, i, /*single=*/false, &Components[i], PartialSolutions[i]));
}
@@ -186,7 +190,8 @@
// since components are going to be executed in LIFO order, we'd
// want to have smaller/faster components at the back of the list.
std::sort(componentSteps.begin(), componentSteps.end(),
- [](const ComponentStep *lhs, const ComponentStep *rhs) {
+ [](const std::unique_ptr<ComponentStep> &lhs,
+ const std::unique_ptr<ComponentStep> &rhs) {
return lhs->disjunctionCount() > rhs->disjunctionCount();
});
}
@@ -256,10 +261,12 @@
if (bestBindings && (!disjunction || (!bestBindings->InvolvesTypeVariables &&
!bestBindings->FullyBound))) {
// Produce a type variable step.
- return suspend(TypeVariableStep::create(CS, *bestBindings, Solutions));
+ return suspend(
+ llvm::make_unique<TypeVariableStep>(CS, *bestBindings, Solutions));
} else if (disjunction) {
// Produce a disjunction step.
- return suspend(DisjunctionStep::create(CS, disjunction, Solutions));
+ return suspend(
+ llvm::make_unique<DisjunctionStep>(CS, disjunction, Solutions));
}
// If there are no disjunctions or type variables to bind
diff --git a/lib/Sema/CSStep.h b/lib/Sema/CSStep.h
index 3fd6495..f7bb00c 100644
--- a/lib/Sema/CSStep.h
+++ b/lib/Sema/CSStep.h
@@ -49,15 +49,15 @@
private:
Kind ResultKind;
- SmallVector<SolverStep *, 4> NextSteps;
+ SmallVector<std::unique_ptr<SolverStep>, 4> NextSteps;
StepResult(Kind kind) : ResultKind(kind) {}
- StepResult(Kind kind, SolverStep *step) : ResultKind(kind) {
- NextSteps.push_back(step);
+ StepResult(Kind kind, std::unique_ptr<SolverStep> step) : ResultKind(kind) {
+ NextSteps.push_back(std::move(step));
}
- StepResult(Kind kind, SmallVectorImpl<SolverStep *> &followup)
+ StepResult(Kind kind, SmallVectorImpl<std::unique_ptr<SolverStep>> &followup)
: ResultKind(kind), NextSteps(std::move(followup)) {}
public:
@@ -65,29 +65,24 @@
Kind getKind() const { return ResultKind; }
- void transfer(SmallVectorImpl<SolverStep *> &workList) {
+ void transfer(SmallVectorImpl<std::unique_ptr<SolverStep>> &workList) {
workList.reserve(NextSteps.size());
- workList.append(NextSteps.begin(), NextSteps.end());
+ for (auto &step : NextSteps)
+ workList.push_back(std::move(step));
}
private:
static StepResult success() { return StepResult(Kind::Solved); }
static StepResult failure() { return StepResult(Kind::Error); }
- static StepResult unsolved(SolverStep *singleStep) {
- return StepResult(Kind::Unsolved, singleStep);
+ static StepResult unsolved(std::unique_ptr<SolverStep> singleStep) {
+ return StepResult(Kind::Unsolved, std::move(singleStep));
}
- static StepResult unsolved(SmallVectorImpl<SolverStep *> &followup) {
+ static StepResult
+ unsolved(SmallVectorImpl<std::unique_ptr<SolverStep>> &followup) {
return StepResult(Kind::Unsolved, followup);
}
-
- template <typename T> static StepResult unsolved(ArrayRef<T *> followup) {
- auto result = StepResult(Kind::Unsolved);
- for (auto *step : followup)
- result.NextSteps.push_back(static_cast<SolverStep *>(step));
- return result;
- }
};
/// Represents a single independently solvable part of
@@ -167,22 +162,17 @@
return isSuccess ? StepResult::success() : StepResult::failure();
}
- StepResult replaceWith(SolverStep *replacement) {
+ StepResult replaceWith(std::unique_ptr<SolverStep> replacement) {
transitionTo(StepState::Done);
- return StepResult(StepResult::Kind::Solved, replacement);
+ return StepResult(StepResult::Kind::Solved, std::move(replacement));
}
- StepResult suspend(SolverStep *followup) {
+ StepResult suspend(std::unique_ptr<SolverStep> followup) {
transitionTo(StepState::Suspended);
- return StepResult::unsolved(followup);
+ return StepResult::unsolved(std::move(followup));
}
- StepResult suspend(SmallVectorImpl<SolverStep *> &followup) {
- transitionTo(StepState::Suspended);
- return StepResult::unsolved(followup);
- }
-
- template <typename T> StepResult suspend(ArrayRef<T *> followup) {
+ StepResult suspend(SmallVectorImpl<std::unique_ptr<SolverStep>> &followup) {
transitionTo(StepState::Suspended);
return StepResult::unsolved(followup);
}
@@ -244,10 +234,10 @@
SmallVector<Constraint *, 4> OrphanedConstraints;
+public:
SplitterStep(ConstraintSystem &cs, SmallVectorImpl<Solution> &solutions)
: SolverStep(cs, solutions) {}
-public:
StepResult take(bool prevFailed) override;
StepResult resume(bool prevFailed) override;
@@ -255,15 +245,11 @@
Out << "SplitterStep with #" << Components.size() << " components\n";
}
- static SplitterStep *create(ConstraintSystem &cs,
- SmallVectorImpl<Solution> &solutions) {
- return new SplitterStep(cs, solutions);
- }
-
private:
/// If current step needs follow-up steps to get completely solved,
/// let's compute them using connected components algorithm.
- void computeFollowupSteps(SmallVectorImpl<ComponentStep *> &componentSteps);
+ void computeFollowupSteps(
+ SmallVectorImpl<std::unique_ptr<ComponentStep>> &componentSteps);
/// Once all of the follow-up steps are complete, let's try
/// to merge resulting solutions together, to form final solution(s)
@@ -339,6 +325,7 @@
/// with it, which makes it disconnected in the graph.
Constraint *OrphanedConstraint = nullptr;
+public:
ComponentStep(ConstraintSystem &cs, unsigned index, bool single,
ConstraintList *constraints,
SmallVectorImpl<Solution> &solutions)
@@ -346,7 +333,6 @@
OriginalScore(getCurrentScore()), OriginalBestScore(getBestScore()),
Constraints(constraints) {}
-public:
/// Record a type variable as associated with this step.
void record(TypeVariableType *typeVar) { TypeVars.push_back(typeVar); }
@@ -388,12 +374,6 @@
void print(llvm::raw_ostream &Out) override {
Out << "ComponentStep with at #" << Index << '\n';
}
-
- static ComponentStep *create(ConstraintSystem &cs, unsigned index,
- bool single, ConstraintList *constraints,
- SmallVectorImpl<Solution> &solutions) {
- return new ComponentStep(cs, index, single, constraints, solutions);
- }
};
template <typename P> class BindingStep : public SolverStep {
@@ -429,7 +409,7 @@
auto scope = llvm::make_unique<Scope>(CS);
if (attempt(*choice)) {
ActiveChoice.emplace(std::move(scope), *choice);
- return suspend(SplitterStep::create(CS, Solutions));
+ return suspend(llvm::make_unique<SplitterStep>(CS, Solutions));
}
}
@@ -490,12 +470,12 @@
/// attempting other bindings in certain conditions.
bool SawFirstLiteralConstraint = false;
+public:
TypeVariableStep(ConstraintSystem &cs, BindingContainer &bindings,
SmallVectorImpl<Solution> &solutions)
: BindingStep(cs, {cs, bindings}, solutions), TypeVar(bindings.TypeVar),
InitialBindings(bindings.Bindings.begin(), bindings.Bindings.end()) {}
-public:
void setup() override;
StepResult resume(bool prevFailed) override;
@@ -505,12 +485,6 @@
<< InitialBindings.size() << " initial bindings\n";
}
- static TypeVariableStep *create(ConstraintSystem &cs,
- BindingContainer &bindings,
- SmallVectorImpl<Solution> &solutions) {
- return new TypeVariableStep(cs, bindings, solutions);
- }
-
protected:
bool attempt(const TypeVariableBinding &choice) override;
@@ -574,11 +548,6 @@
Out << '\n';
}
- static DisjunctionStep *create(ConstraintSystem &cs, Constraint *disjunction,
- SmallVectorImpl<Solution> &solutions) {
- return new DisjunctionStep(cs, disjunction, solutions);
- }
-
private:
bool shouldSkip(const DisjunctionChoice &choice) const override;