Skip to content

Commit b3dda2c

Browse files
committed
[Constraint graph] Handle orphaned constraints within connected components
Move the logic for creating connected components of orphaned constraints into the connected-components algorithm code, rather than making it a special part of SplitterStep. (cherry picked from commit ab38be1)
1 parent 0ae3b30 commit b3dda2c

File tree

4 files changed

+32
-35
lines changed

4 files changed

+32
-35
lines changed

lib/Sema/CSStep.cpp

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -97,32 +97,13 @@ void SplitterStep::computeFollowupSteps(
9797

9898
// Compute the connected components of the constraint graph.
9999
auto components = CG.computeConnectedComponents(CS.TypeVariables);
100-
unsigned numComponents =
101-
components.size() + CG.getOrphanedConstraints().size();
100+
unsigned numComponents = components.size();
102101
if (numComponents < 2) {
103102
componentSteps.push_back(llvm::make_unique<ComponentStep>(
104103
CS, 0, &CS.InactiveConstraints, Solutions));
105104
return;
106105
}
107106

108-
Components.resize(numComponents);
109-
PartialSolutions = std::unique_ptr<SmallVector<Solution, 4>[]>(
110-
new SmallVector<Solution, 4>[numComponents]);
111-
112-
// Add components.
113-
for (unsigned i : indices(components)) {
114-
componentSteps.push_back(llvm::make_unique<ComponentStep>(
115-
CS, i, &Components[i], std::move(components[i]), PartialSolutions[i]));
116-
}
117-
118-
// Add components for the orphaned constraints.
119-
OrphanedConstraints = CG.takeOrphanedConstraints();
120-
for (unsigned i : range(components.size(), numComponents)) {
121-
auto orphaned = OrphanedConstraints[i - components.size()];
122-
componentSteps.push_back(llvm::make_unique<ComponentStep>(
123-
CS, i, &Components[i], orphaned, PartialSolutions[i]));
124-
}
125-
126107
if (isDebugMode()) {
127108
auto &log = getDebugLogger();
128109
// Verify that the constraint graph is valid.
@@ -135,6 +116,19 @@ void SplitterStep::computeFollowupSteps(
135116
CG.printConnectedComponents(CS.TypeVariables, log);
136117
}
137118

119+
// Take the orphaned constraints, because they'll go into a component now.
120+
OrphanedConstraints = CG.takeOrphanedConstraints();
121+
122+
Components.resize(numComponents);
123+
PartialSolutions = std::unique_ptr<SmallVector<Solution, 4>[]>(
124+
new SmallVector<Solution, 4>[numComponents]);
125+
126+
// Add components.
127+
for (unsigned i : indices(components)) {
128+
componentSteps.push_back(llvm::make_unique<ComponentStep>(
129+
CS, i, &Components[i], std::move(components[i]), PartialSolutions[i]));
130+
}
131+
138132
// Create component ordering based on the information associated
139133
// with constraints in each step - e.g. number of disjunctions,
140134
// since components are going to be executed in LIFO order, we'd

lib/Sema/CSStep.h

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,13 @@ class ComponentStep final : public SolverStep {
366366
: SolverStep(cs, solutions), Index(index), IsSingle(false),
367367
OriginalScore(getCurrentScore()), OriginalBestScore(getBestScore()),
368368
Constraints(constraints) {
369+
if (component.isOrphaned()) {
370+
assert(component.constraints.size() == 1);
371+
OrphanedConstraint = component.constraints.front();
372+
} else {
373+
assert(component.typeVars.size() > 0);
374+
}
375+
369376
TypeVars = std::move(component.typeVars);
370377

371378
for (auto constraint : component.constraints) {
@@ -374,18 +381,6 @@ class ComponentStep final : public SolverStep {
374381
}
375382
}
376383

377-
/// Create a component step for an orphaned constraint.
378-
ComponentStep(ConstraintSystem &cs, unsigned index,
379-
ConstraintList *constraints,
380-
Constraint *orphaned,
381-
SmallVectorImpl<Solution> &solutions)
382-
: SolverStep(cs, solutions), Index(index), IsSingle(false),
383-
OriginalScore(getCurrentScore()), OriginalBestScore(getBestScore()),
384-
Constraints(constraints), OrphanedConstraint(orphaned) {
385-
constraints->erase(orphaned);
386-
record(orphaned);
387-
}
388-
389384
private:
390385
/// Record a constraint as associated with this step.
391386
void record(Constraint *constraint) {
@@ -417,7 +412,8 @@ class ComponentStep final : public SolverStep {
417412
getDebugLogger() << "(solving component #" << Index << '\n';
418413

419414
ComponentScope = llvm::make_unique<Scope>(*this);
420-
// If this component has oprhaned constraint attached,
415+
416+
// If this component has orphaned constraint attached,
421417
// let's return it to the graph.
422418
CS.CG.setOrphanedConstraint(OrphanedConstraint);
423419
}

lib/Sema/ConstraintGraph.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,8 @@ namespace {
540540

541541
// Assign each type variable to its appropriate component.
542542
SmallVector<Component, 1> components;
543+
components.reserve(
544+
validComponents.size() + cg.getOrphanedConstraints().size());
543545
llvm::SmallDenseMap<TypeVariableType *, unsigned> componentIdxMap;
544546
for (auto typeVar : typeVars) {
545547
// Find the representative. If we aren't creating a type variable
@@ -577,6 +579,12 @@ namespace {
577579
components[componentIdxMap[rep]].constraints.push_back(&constraint);
578580
}
579581

582+
// Gather orphaned constraints; each gets its own component.
583+
for (auto orphaned : cg.getOrphanedConstraints()) {
584+
components.push_back({ });
585+
components.back().constraints.push_back(orphaned);
586+
}
587+
580588
return components;
581589
}
582590

@@ -635,7 +643,6 @@ ConstraintGraph::computeConnectedComponents(
635643
// Perform connected components via a union-find algorithm on all of the
636644
// constraints adjacent to these type variables.
637645
ConnectedComponents cc(*this, typeVars);
638-
639646
return cc.getComponents();
640647
}
641648

lib/Sema/ConstraintGraph.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ class ConstraintGraph {
213213
TinyPtrVector<Constraint *> constraints;
214214

215215
/// Whether this component represents an orphaned constraint.
216-
bool isOrphanedConstraint() const {
216+
bool isOrphaned() const {
217217
return typeVars.empty();
218218
}
219219
};

0 commit comments

Comments
 (0)