Skip to content

Commit 0784af5

Browse files
authored
Merge pull request swiftlang#36057 from xedin/cs-graph-refactor-fixed-bindings
[ConstraintGraph] Split fixed binding storage into referenced by/from
2 parents ffffc30 + 8137c7b commit 0784af5

File tree

2 files changed

+76
-34
lines changed

2 files changed

+76
-34
lines changed

include/swift/Sema/ConstraintGraph.h

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ class ConstraintGraphNode {
6363

6464
/// Retrieve the set of type variables that are adjacent due to fixed
6565
/// bindings.
66-
ArrayRef<TypeVariableType *> getFixedBindings() const {
67-
return FixedBindings;
66+
ArrayRef<TypeVariableType *> getReferencedVars() const {
67+
return References.getArrayRef();
68+
}
69+
70+
ArrayRef<TypeVariableType *> getReferencedBy() const {
71+
return ReferencedBy.getArrayRef();
6872
}
6973

7074
/// Retrieve all of the type variables in the same equivalence class
@@ -95,11 +99,18 @@ class ConstraintGraphNode {
9599
void addToEquivalenceClass(ArrayRef<TypeVariableType *> typeVars);
96100

97101
/// Add a type variable related to this type variable through fixed
98-
/// bindings.
99-
void addFixedBinding(TypeVariableType *typeVar);
100-
101-
/// Remove a type variable from the fixed-binding relationship.
102-
void removeFixedBinding(TypeVariableType *typeVar);
102+
/// binding.
103+
void addReferencedVar(TypeVariableType *typeVar);
104+
105+
/// Add a type variable referencing this type variable - this type
106+
/// variable occurs in fixed type of the given type variable.
107+
void addReferencedBy(TypeVariableType *typeVar);
108+
109+
/// Remove a type variable referenced by this node through a fixed binding.
110+
void removeReference(TypeVariableType *typeVar);
111+
112+
/// Remove a type variable which used to reference this type variable.
113+
void removeReferencedBy(TypeVariableType *typeVar);
103114

104115
/// The type variable this node represents.
105116
TypeVariableType *TypeVar;
@@ -112,9 +123,13 @@ class ConstraintGraphNode {
112123
/// to the index within the vector of constraints.
113124
llvm::SmallDenseMap<Constraint *, unsigned, 2> ConstraintIndex;
114125

126+
/// The set of type variables that reference type variable associated
127+
/// with this constraint graph node.
128+
llvm::SmallSetVector<TypeVariableType *, 2> ReferencedBy;
129+
115130
/// The set of type variables that occur within the fixed binding of
116131
/// this type variable.
117-
SmallVector<TypeVariableType *, 2> FixedBindings;
132+
llvm::SmallSetVector<TypeVariableType *, 2> References;
118133

119134
/// All of the type variables in the same equivalence class as this
120135
/// representative type variable.

lib/Sema/ConstraintGraph.cpp

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,28 @@ void ConstraintGraphNode::addToEquivalenceClass(
143143
EquivalenceClass.append(typeVars.begin(), typeVars.end());
144144
}
145145

146-
void ConstraintGraphNode::addFixedBinding(TypeVariableType *typeVar) {
147-
FixedBindings.push_back(typeVar);
146+
void ConstraintGraphNode::addReferencedVar(TypeVariableType *typeVar) {
147+
bool inserted = References.insert(typeVar);
148+
assert(inserted && "Attempt to reference a duplicate type variable");
149+
(void)inserted;
148150
}
149151

150-
void ConstraintGraphNode::removeFixedBinding(TypeVariableType *typeVar) {
151-
FixedBindings.pop_back();
152+
void ConstraintGraphNode::addReferencedBy(TypeVariableType *typeVar) {
153+
bool inserted = ReferencedBy.insert(typeVar);
154+
assert(inserted && "Already referenced by the given type variable");
155+
(void)inserted;
156+
}
157+
158+
void ConstraintGraphNode::removeReference(TypeVariableType *typeVar) {
159+
auto removed = References.remove(typeVar);
160+
assert(removed && "Variables are not connected");
161+
(void)removed;
162+
}
163+
164+
void ConstraintGraphNode::removeReferencedBy(TypeVariableType *typeVar) {
165+
auto removed = ReferencedBy.remove(typeVar);
166+
assert(removed && "Variables are not connected");
167+
(void)removed;
152168
}
153169

154170
#pragma mark Graph scope management
@@ -349,11 +365,10 @@ void ConstraintGraph::bindTypeVariable(TypeVariableType *typeVar, Type fixed) {
349365
fixed->getTypeVariables(typeVars);
350366
auto &node = (*this)[typeVar];
351367
for (auto otherTypeVar : typeVars) {
352-
if (typeVar == otherTypeVar)
353-
continue;
368+
if (typeVar == otherTypeVar) continue;
354369

355-
(*this)[otherTypeVar].addFixedBinding(typeVar);
356-
node.addFixedBinding(otherTypeVar);
370+
(*this)[otherTypeVar].addReferencedBy(typeVar);
371+
node.addReferencedVar(otherTypeVar);
357372
}
358373

359374
// Record the change, if there are active scopes.
@@ -372,8 +387,8 @@ void ConstraintGraph::unbindTypeVariable(TypeVariableType *typeVar, Type fixed){
372387
fixed->getTypeVariables(typeVars);
373388
auto &node = (*this)[typeVar];
374389
for (auto otherTypeVar : typeVars) {
375-
(*this)[otherTypeVar].removeFixedBinding(typeVar);
376-
node.removeFixedBinding(otherTypeVar);
390+
(*this)[otherTypeVar].removeReferencedBy(typeVar);
391+
node.removeReference(otherTypeVar);
377392
}
378393
}
379394

@@ -435,7 +450,8 @@ static void depthFirstSearch(
435450
}
436451

437452
// Walk any type variables related via fixed bindings.
438-
visitAdjacencies(node.getFixedBindings());
453+
visitAdjacencies(node.getReferencedBy());
454+
visitAdjacencies(node.getReferencedVars());
439455
}
440456

441457
llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
@@ -513,7 +529,11 @@ llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
513529
constraints.push_back(constraint);
514530
}
515531

516-
for (auto adjTypeVar : node.getFixedBindings()) {
532+
for (auto adjTypeVar : node.getReferencedBy()) {
533+
addTypeVarConstraints(adjTypeVar);
534+
}
535+
536+
for (auto adjTypeVar : node.getReferencedVars()) {
517537
addTypeVarConstraints(adjTypeVar);
518538
}
519539
}
@@ -1202,24 +1222,31 @@ void ConstraintGraphNode::print(llvm::raw_ostream &out, unsigned indent,
12021222
}
12031223
}
12041224

1205-
// Print fixed bindings.
1206-
if (!FixedBindings.empty()) {
1207-
out.indent(indent + 2);
1208-
out << "Fixed bindings: ";
1209-
SmallVector<TypeVariableType *, 4> sortedFixedBindings(
1210-
FixedBindings.begin(), FixedBindings.end());
1211-
std::sort(sortedFixedBindings.begin(), sortedFixedBindings.end(),
1225+
auto printVarList = [&](ArrayRef<TypeVariableType *> typeVars) {
1226+
SmallVector<TypeVariableType *, 4> sorted(typeVars.begin(), typeVars.end());
1227+
std::sort(sorted.begin(), sorted.end(),
12121228
[&](TypeVariableType *typeVar1, TypeVariableType *typeVar2) {
12131229
return typeVar1->getID() < typeVar2->getID();
12141230
});
12151231

1216-
interleave(sortedFixedBindings,
1217-
[&](TypeVariableType *typeVar) {
1218-
out << "$T" << typeVar->getID();
1219-
},
1220-
[&]() {
1221-
out << ", ";
1222-
});
1232+
interleave(
1233+
sorted,
1234+
[&](TypeVariableType *typeVar) { out << typeVar->getString(PO); },
1235+
[&out] { out << ", "; });
1236+
};
1237+
1238+
// Print fixed bindings.
1239+
if (!ReferencedBy.empty()) {
1240+
out.indent(indent + 2);
1241+
out << "Referenced By: ";
1242+
printVarList(getReferencedBy());
1243+
out << "\n";
1244+
}
1245+
1246+
if (!References.empty()) {
1247+
out.indent(indent + 2);
1248+
out << "References: ";
1249+
printVarList(getReferencedVars());
12231250
out << "\n";
12241251
}
12251252

0 commit comments

Comments
 (0)