mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #36057 from xedin/cs-graph-refactor-fixed-bindings
[ConstraintGraph] Split fixed binding storage into referenced by/from
This commit is contained in:
@@ -63,8 +63,12 @@ public:
|
||||
|
||||
/// Retrieve the set of type variables that are adjacent due to fixed
|
||||
/// bindings.
|
||||
ArrayRef<TypeVariableType *> getFixedBindings() const {
|
||||
return FixedBindings;
|
||||
ArrayRef<TypeVariableType *> getReferencedVars() const {
|
||||
return References.getArrayRef();
|
||||
}
|
||||
|
||||
ArrayRef<TypeVariableType *> getReferencedBy() const {
|
||||
return ReferencedBy.getArrayRef();
|
||||
}
|
||||
|
||||
/// Retrieve all of the type variables in the same equivalence class
|
||||
@@ -95,11 +99,18 @@ private:
|
||||
void addToEquivalenceClass(ArrayRef<TypeVariableType *> typeVars);
|
||||
|
||||
/// Add a type variable related to this type variable through fixed
|
||||
/// bindings.
|
||||
void addFixedBinding(TypeVariableType *typeVar);
|
||||
|
||||
/// Remove a type variable from the fixed-binding relationship.
|
||||
void removeFixedBinding(TypeVariableType *typeVar);
|
||||
/// binding.
|
||||
void addReferencedVar(TypeVariableType *typeVar);
|
||||
|
||||
/// Add a type variable referencing this type variable - this type
|
||||
/// variable occurs in fixed type of the given type variable.
|
||||
void addReferencedBy(TypeVariableType *typeVar);
|
||||
|
||||
/// Remove a type variable referenced by this node through a fixed binding.
|
||||
void removeReference(TypeVariableType *typeVar);
|
||||
|
||||
/// Remove a type variable which used to reference this type variable.
|
||||
void removeReferencedBy(TypeVariableType *typeVar);
|
||||
|
||||
/// The type variable this node represents.
|
||||
TypeVariableType *TypeVar;
|
||||
@@ -112,9 +123,13 @@ private:
|
||||
/// to the index within the vector of constraints.
|
||||
llvm::SmallDenseMap<Constraint *, unsigned, 2> ConstraintIndex;
|
||||
|
||||
/// The set of type variables that reference type variable associated
|
||||
/// with this constraint graph node.
|
||||
llvm::SmallSetVector<TypeVariableType *, 2> ReferencedBy;
|
||||
|
||||
/// The set of type variables that occur within the fixed binding of
|
||||
/// this type variable.
|
||||
SmallVector<TypeVariableType *, 2> FixedBindings;
|
||||
llvm::SmallSetVector<TypeVariableType *, 2> References;
|
||||
|
||||
/// All of the type variables in the same equivalence class as this
|
||||
/// representative type variable.
|
||||
|
||||
@@ -143,12 +143,28 @@ void ConstraintGraphNode::addToEquivalenceClass(
|
||||
EquivalenceClass.append(typeVars.begin(), typeVars.end());
|
||||
}
|
||||
|
||||
void ConstraintGraphNode::addFixedBinding(TypeVariableType *typeVar) {
|
||||
FixedBindings.push_back(typeVar);
|
||||
void ConstraintGraphNode::addReferencedVar(TypeVariableType *typeVar) {
|
||||
bool inserted = References.insert(typeVar);
|
||||
assert(inserted && "Attempt to reference a duplicate type variable");
|
||||
(void)inserted;
|
||||
}
|
||||
|
||||
void ConstraintGraphNode::removeFixedBinding(TypeVariableType *typeVar) {
|
||||
FixedBindings.pop_back();
|
||||
void ConstraintGraphNode::addReferencedBy(TypeVariableType *typeVar) {
|
||||
bool inserted = ReferencedBy.insert(typeVar);
|
||||
assert(inserted && "Already referenced by the given type variable");
|
||||
(void)inserted;
|
||||
}
|
||||
|
||||
void ConstraintGraphNode::removeReference(TypeVariableType *typeVar) {
|
||||
auto removed = References.remove(typeVar);
|
||||
assert(removed && "Variables are not connected");
|
||||
(void)removed;
|
||||
}
|
||||
|
||||
void ConstraintGraphNode::removeReferencedBy(TypeVariableType *typeVar) {
|
||||
auto removed = ReferencedBy.remove(typeVar);
|
||||
assert(removed && "Variables are not connected");
|
||||
(void)removed;
|
||||
}
|
||||
|
||||
#pragma mark Graph scope management
|
||||
@@ -349,11 +365,10 @@ void ConstraintGraph::bindTypeVariable(TypeVariableType *typeVar, Type fixed) {
|
||||
fixed->getTypeVariables(typeVars);
|
||||
auto &node = (*this)[typeVar];
|
||||
for (auto otherTypeVar : typeVars) {
|
||||
if (typeVar == otherTypeVar)
|
||||
continue;
|
||||
if (typeVar == otherTypeVar) continue;
|
||||
|
||||
(*this)[otherTypeVar].addFixedBinding(typeVar);
|
||||
node.addFixedBinding(otherTypeVar);
|
||||
(*this)[otherTypeVar].addReferencedBy(typeVar);
|
||||
node.addReferencedVar(otherTypeVar);
|
||||
}
|
||||
|
||||
// Record the change, if there are active scopes.
|
||||
@@ -372,8 +387,8 @@ void ConstraintGraph::unbindTypeVariable(TypeVariableType *typeVar, Type fixed){
|
||||
fixed->getTypeVariables(typeVars);
|
||||
auto &node = (*this)[typeVar];
|
||||
for (auto otherTypeVar : typeVars) {
|
||||
(*this)[otherTypeVar].removeFixedBinding(typeVar);
|
||||
node.removeFixedBinding(otherTypeVar);
|
||||
(*this)[otherTypeVar].removeReferencedBy(typeVar);
|
||||
node.removeReference(otherTypeVar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,7 +450,8 @@ static void depthFirstSearch(
|
||||
}
|
||||
|
||||
// Walk any type variables related via fixed bindings.
|
||||
visitAdjacencies(node.getFixedBindings());
|
||||
visitAdjacencies(node.getReferencedBy());
|
||||
visitAdjacencies(node.getReferencedVars());
|
||||
}
|
||||
|
||||
llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
|
||||
@@ -513,7 +529,11 @@ llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
|
||||
constraints.push_back(constraint);
|
||||
}
|
||||
|
||||
for (auto adjTypeVar : node.getFixedBindings()) {
|
||||
for (auto adjTypeVar : node.getReferencedBy()) {
|
||||
addTypeVarConstraints(adjTypeVar);
|
||||
}
|
||||
|
||||
for (auto adjTypeVar : node.getReferencedVars()) {
|
||||
addTypeVarConstraints(adjTypeVar);
|
||||
}
|
||||
}
|
||||
@@ -1202,24 +1222,31 @@ void ConstraintGraphNode::print(llvm::raw_ostream &out, unsigned indent,
|
||||
}
|
||||
}
|
||||
|
||||
// Print fixed bindings.
|
||||
if (!FixedBindings.empty()) {
|
||||
out.indent(indent + 2);
|
||||
out << "Fixed bindings: ";
|
||||
SmallVector<TypeVariableType *, 4> sortedFixedBindings(
|
||||
FixedBindings.begin(), FixedBindings.end());
|
||||
std::sort(sortedFixedBindings.begin(), sortedFixedBindings.end(),
|
||||
auto printVarList = [&](ArrayRef<TypeVariableType *> typeVars) {
|
||||
SmallVector<TypeVariableType *, 4> sorted(typeVars.begin(), typeVars.end());
|
||||
std::sort(sorted.begin(), sorted.end(),
|
||||
[&](TypeVariableType *typeVar1, TypeVariableType *typeVar2) {
|
||||
return typeVar1->getID() < typeVar2->getID();
|
||||
});
|
||||
|
||||
interleave(sortedFixedBindings,
|
||||
[&](TypeVariableType *typeVar) {
|
||||
out << "$T" << typeVar->getID();
|
||||
},
|
||||
[&]() {
|
||||
out << ", ";
|
||||
});
|
||||
interleave(
|
||||
sorted,
|
||||
[&](TypeVariableType *typeVar) { out << typeVar->getString(PO); },
|
||||
[&out] { out << ", "; });
|
||||
};
|
||||
|
||||
// Print fixed bindings.
|
||||
if (!ReferencedBy.empty()) {
|
||||
out.indent(indent + 2);
|
||||
out << "Referenced By: ";
|
||||
printVarList(getReferencedBy());
|
||||
out << "\n";
|
||||
}
|
||||
|
||||
if (!References.empty()) {
|
||||
out.indent(indent + 2);
|
||||
out << "References: ";
|
||||
printVarList(getReferencedVars());
|
||||
out << "\n";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user