Skip to content

Commit fdcf750

Browse files
committed
[Constraint graph] Move component sorting into connected components.
(cherry picked from commit dec149c)
1 parent b3dda2c commit fdcf750

File tree

4 files changed

+53
-36
lines changed

4 files changed

+53
-36
lines changed

lib/Sema/CSStep.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,11 @@ void SplitterStep::computeFollowupSteps(
125125

126126
// Add components.
127127
for (unsigned i : indices(components)) {
128+
unsigned solutionIndex = components[i].solutionIndex;
128129
componentSteps.push_back(llvm::make_unique<ComponentStep>(
129-
CS, i, &Components[i], std::move(components[i]), PartialSolutions[i]));
130+
CS, solutionIndex, &Components[i], std::move(components[i]),
131+
PartialSolutions[solutionIndex]));
130132
}
131-
132-
// Create component ordering based on the information associated
133-
// with constraints in each step - e.g. number of disjunctions,
134-
// since components are going to be executed in LIFO order, we'd
135-
// want to have smaller/faster components at the back of the list.
136-
std::sort(componentSteps.begin(), componentSteps.end(),
137-
[](const std::unique_ptr<ComponentStep> &lhs,
138-
const std::unique_ptr<ComponentStep> &rhs) {
139-
return lhs->disjunctionCount() > rhs->disjunctionCount();
140-
});
141133
}
142134

143135
bool SplitterStep::mergePartialSolutions() const {

lib/Sema/CSStep.h

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,6 @@ class ComponentStep final : public SolverStep {
341341
/// Constraints "in scope" of this step.
342342
ConstraintList *Constraints;
343343

344-
/// Number of disjunction constraints associated with this step,
345-
/// used to aid in ordering of the components.
346-
unsigned NumDisjunctions = 0;
347-
348344
/// Constraint which doesn't have any free type variables associated
349345
/// with it, which makes it disconnected in the graph.
350346
Constraint *OrphanedConstraint = nullptr;
@@ -367,36 +363,23 @@ class ComponentStep final : public SolverStep {
367363
OriginalScore(getCurrentScore()), OriginalBestScore(getBestScore()),
368364
Constraints(constraints) {
369365
if (component.isOrphaned()) {
370-
assert(component.constraints.size() == 1);
371-
OrphanedConstraint = component.constraints.front();
366+
assert(component.getConstraints().size() == 1);
367+
OrphanedConstraint = component.getConstraints().front();
372368
} else {
373369
assert(component.typeVars.size() > 0);
374370
}
375371

376372
TypeVars = std::move(component.typeVars);
377373

378-
for (auto constraint : component.constraints) {
374+
for (auto constraint : component.getConstraints()) {
379375
constraints->erase(constraint);
380-
record(constraint);
376+
Constraints->push_back(constraint);
381377
}
382378
}
383379

384-
private:
385-
/// Record a constraint as associated with this step.
386-
void record(Constraint *constraint) {
387-
Constraints->push_back(constraint);
388-
if (constraint->getKind() == ConstraintKind::Disjunction)
389-
++NumDisjunctions;
390-
}
391-
392-
public:
393-
394380
StepResult take(bool prevFailed) override;
395381
StepResult resume(bool prevFailed) override;
396382

397-
// The number of disjunction constraints associated with this component.
398-
unsigned disjunctionCount() const { return NumDisjunctions; }
399-
400383
void print(llvm::raw_ostream &Out) override {
401384
Out << "ComponentStep with at #" << Index << '\n';
402385
}

lib/Sema/ConstraintGraph.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ namespace {
556556
// We haven't allocated this component yet; do so now.
557557
knownComponentIdx = componentIdxMap.insert(
558558
{rep, componentIdxMap.size()}).first;
559-
components.push_back({ });
559+
components.push_back(Component(components.size()));
560560
}
561561

562562
// Record this type variabgetConstraintsle as part of the component.
@@ -576,13 +576,24 @@ namespace {
576576
auto typeVar = constraintTypeVars.front();
577577
auto rep = findRepresentative(typeVar);
578578
assert(componentIdxMap.count(rep) > 0);
579-
components[componentIdxMap[rep]].constraints.push_back(&constraint);
579+
components[componentIdxMap[rep]].addConstraint(&constraint);
580580
}
581581

582582
// Gather orphaned constraints; each gets its own component.
583583
for (auto orphaned : cg.getOrphanedConstraints()) {
584-
components.push_back({ });
585-
components.back().constraints.push_back(orphaned);
584+
components.push_back(Component(components.size()));
585+
components.back().addConstraint(orphaned);
586+
}
587+
588+
// Create component ordering based on the information associated
589+
// with constraints in each step - e.g. number of disjunctions,
590+
// since components are going to be executed in LIFO order, we'd
591+
// want to have smaller/faster components at the back of the list.
592+
if (components.size() > 1) {
593+
std::sort(components.begin(), components.end(),
594+
[&](const Component &lhs, const Component &rhs) {
595+
return lhs.getNumDisjunctions() > rhs.getNumDisjunctions();
596+
});
586597
}
587598

588599
return components;
@@ -637,6 +648,13 @@ namespace {
637648
};
638649
}
639650

651+
void ConstraintGraph::Component::addConstraint(Constraint *constraint) {
652+
if (constraint->getKind() == ConstraintKind::Disjunction)
653+
++numDisjunctions;
654+
655+
constraints.push_back(constraint);
656+
}
657+
640658
SmallVector<ConstraintGraph::Component, 1>
641659
ConstraintGraph::computeConnectedComponents(
642660
ArrayRef<TypeVariableType *> typeVars) {

lib/Sema/ConstraintGraph.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,37 @@ class ConstraintGraph {
209209
/// The type variables in this component.
210210
TinyPtrVector<TypeVariableType *> typeVars;
211211

212+
/// The original index of this component in the list of components,
213+
/// used to provide the index of where the partial solutions will occur.
214+
/// FIXME: This is needed due to some ordering dependencies in the
215+
/// merging of partial solutions, which appears to also be related
216+
/// DisjunctionStep::pruneOverloads() short-circuiting. It should be
217+
/// removed.
218+
unsigned solutionIndex;
219+
220+
private:
221+
/// The number of disjunctions in this component.
222+
unsigned numDisjunctions = 0;
223+
212224
/// The constraints in this component.
213225
TinyPtrVector<Constraint *> constraints;
214226

227+
public:
228+
Component(unsigned solutionIndex) : solutionIndex(solutionIndex) { }
229+
215230
/// Whether this component represents an orphaned constraint.
216231
bool isOrphaned() const {
217232
return typeVars.empty();
218233
}
234+
235+
/// Add a constraint.
236+
void addConstraint(Constraint *constraint);
237+
238+
const TinyPtrVector<Constraint *> &getConstraints() const {
239+
return constraints;
240+
}
241+
242+
unsigned getNumDisjunctions() const { return numDisjunctions; }
219243
};
220244

221245
/// Compute the connected components of the graph.

0 commit comments

Comments
 (0)