mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ConstraintGraph] Optimize edge contraction
Previously on every step solver would iterate over all constraints in attempt to find `BindParam` which could be contracted. Instead of doing that, let's take advantage of the fact that all (participating) closures are recorded in the constraint system during constraint generation, so it should be possible to check either outer parameter types are contractable with their inner uses.
This commit is contained in:
@@ -1312,12 +1312,36 @@ static bool shouldContractEdge(ConstraintKind kind) {
|
||||
}
|
||||
|
||||
bool ConstraintGraph::contractEdges() {
|
||||
// Current constraint system doesn't have any closure expressions
|
||||
// associated with it so there is nothing to here.
|
||||
if (CS.ClosureTypes.empty())
|
||||
return false;
|
||||
|
||||
SmallVector<Constraint *, 16> constraints;
|
||||
CS.findConstraints(constraints, [&](const Constraint &constraint) {
|
||||
for (const auto &closure : CS.ClosureTypes) {
|
||||
for (const auto ¶m : closure.second->getParams()) {
|
||||
auto paramTy = param.getPlainType()->getAs<TypeVariableType>();
|
||||
if (!paramTy)
|
||||
continue;
|
||||
|
||||
// This closure is not currently in scope.
|
||||
if (!CS.TypeVariables.count(paramTy))
|
||||
break;
|
||||
|
||||
// Nothing to contract here since outside parameter
|
||||
// is already bound to a concrete type.
|
||||
if (CS.getFixedType(paramTy))
|
||||
continue;
|
||||
|
||||
for (auto *constraint : (*this)[paramTy].getConstraints()) {
|
||||
// Track how many constraints did contraction algorithm iterated over.
|
||||
incrementConstraintsPerContractionCounter();
|
||||
return shouldContractEdge(constraint.getKind());
|
||||
});
|
||||
|
||||
if (shouldContractEdge(constraint->getKind()))
|
||||
constraints.push_back(constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool didContractEdges = false;
|
||||
for (auto *constraint : constraints) {
|
||||
|
||||
Reference in New Issue
Block a user