[ConstraintGraph] Don't notify referenced var if constraint is not useful

Performance optimization that skips notifying referenced variables
if it's clear that the constraint is not going to be useful for them.
This commit is contained in:
Pavel Yaskevich
2021-06-09 15:59:18 -07:00
parent 7fd69a04b4
commit 7e022b27c1

View File

@@ -103,6 +103,23 @@ ConstraintGraphNode::getEquivalenceClassUnsafe() const{
}
#pragma mark Node mutation
static bool isUsefulForReferencedVars(Constraint *constraint) {
switch (constraint->getKind()) {
// Don't attempt to propagate information about `Bind`s and
// `BindOverload`s to referenced variables since they are
// adjacent through that binding already, and there is no
// useful information in trying to process that kind of
// constraint.
case ConstraintKind::Bind:
case ConstraintKind::BindOverload:
return false;
default:
return true;
}
}
void ConstraintGraphNode::addConstraint(Constraint *constraint) {
assert(ConstraintIndex.count(constraint) == 0 && "Constraint re-insertion");
ConstraintIndex[constraint] = Constraints.size();
@@ -111,9 +128,11 @@ void ConstraintGraphNode::addConstraint(Constraint *constraint) {
{
introduceToInference(constraint);
notifyReferencedVars([&](ConstraintGraphNode &referencedVar) {
referencedVar.introduceToInference(constraint);
});
if (isUsefulForReferencedVars(constraint)) {
notifyReferencedVars([&](ConstraintGraphNode &referencedVar) {
referencedVar.introduceToInference(constraint);
});
}
}
}
@@ -129,9 +148,11 @@ void ConstraintGraphNode::removeConstraint(Constraint *constraint) {
{
retractFromInference(constraint);
notifyReferencedVars([&](ConstraintGraphNode &referencedVar) {
referencedVar.retractFromInference(constraint);
});
if (isUsefulForReferencedVars(constraint)) {
notifyReferencedVars([&](ConstraintGraphNode &referencedVar) {
referencedVar.retractFromInference(constraint);
});
}
}
// If this is the last constraint, just pop it off the list and we're done.
@@ -230,6 +251,9 @@ void ConstraintGraphNode::addToEquivalenceClass(
for (auto *constraint : node.getConstraints()) {
introduceToInference(constraint);
if (!isUsefulForReferencedVars(constraint))
continue;
notifyReferencedVars([&](ConstraintGraphNode &referencedVar) {
referencedVar.introduceToInference(constraint);
});
@@ -295,22 +319,6 @@ inference::PotentialBindings &ConstraintGraphNode::getCurrentBindings() {
return *Bindings;
}
static bool isUsefulForReferencedVars(Constraint *constraint) {
switch (constraint->getKind()) {
// Don't attempt to propagate information about `Bind`s and
// `BindOverload`s to referenced variables since they are
// adjacent through that binding already, and there is no
// useful information in trying to process that kind of
// constraint.
case ConstraintKind::Bind:
case ConstraintKind::BindOverload:
return false;
default:
return true;
}
}
void ConstraintGraphNode::introduceToInference(Constraint *constraint) {
if (forRepresentativeVar()) {
auto fixedType = TypeVar->getImpl().getFixedType(/*record=*/nullptr);