mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
s/ConstraintGraph::Node/ConstraintGraphNode
Swift SVN r11002
This commit is contained in:
@@ -104,7 +104,7 @@ gatherReferencedTypeVars(ConstraintSystem &cs,
|
|||||||
|
|
||||||
#pragma mark Graph accessors
|
#pragma mark Graph accessors
|
||||||
|
|
||||||
std::pair<ConstraintGraph::Node &, unsigned>
|
std::pair<ConstraintGraphNode &, unsigned>
|
||||||
ConstraintGraph::lookupNode(TypeVariableType *typeVar) {
|
ConstraintGraph::lookupNode(TypeVariableType *typeVar) {
|
||||||
// Check whether we've already created a node for this type variable.
|
// Check whether we've already created a node for this type variable.
|
||||||
auto known = Nodes.find(typeVar);
|
auto known = Nodes.find(typeVar);
|
||||||
@@ -115,7 +115,7 @@ ConstraintGraph::lookupNode(TypeVariableType *typeVar) {
|
|||||||
|
|
||||||
// Allocate the new node.
|
// Allocate the new node.
|
||||||
StoredNode &stored = Nodes[typeVar];
|
StoredNode &stored = Nodes[typeVar];
|
||||||
stored.NodePtr = new Node(typeVar);
|
stored.NodePtr = new ConstraintGraphNode(typeVar);
|
||||||
stored.Index = TypeVariables.size();
|
stored.Index = TypeVariables.size();
|
||||||
|
|
||||||
// Record this type variable.
|
// Record this type variable.
|
||||||
@@ -138,27 +138,27 @@ ConstraintGraph::lookupNode(TypeVariableType *typeVar) {
|
|||||||
return { *stored.NodePtr, stored.Index };
|
return { *stored.NodePtr, stored.Index };
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayRef<TypeVariableType *> ConstraintGraph::Node::getEquivalenceClass() const{
|
ArrayRef<TypeVariableType *> ConstraintGraphNode::getEquivalenceClass() const{
|
||||||
assert(TypeVar == TypeVar->getImpl().getRepresentative(nullptr) &&
|
assert(TypeVar == TypeVar->getImpl().getRepresentative(nullptr) &&
|
||||||
"Can't request equivalence class from non-representative type var");
|
"Can't request equivalence class from non-representative type var");
|
||||||
return getEquivalenceClassUnsafe();
|
return getEquivalenceClassUnsafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayRef<TypeVariableType *>
|
ArrayRef<TypeVariableType *>
|
||||||
ConstraintGraph::Node::getEquivalenceClassUnsafe() const{
|
ConstraintGraphNode::getEquivalenceClassUnsafe() const{
|
||||||
if (EquivalenceClass.empty())
|
if (EquivalenceClass.empty())
|
||||||
EquivalenceClass.push_back(TypeVar);
|
EquivalenceClass.push_back(TypeVar);
|
||||||
return EquivalenceClass;
|
return EquivalenceClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Node mutation
|
#pragma mark Node mutation
|
||||||
void ConstraintGraph::Node::addConstraint(Constraint *constraint) {
|
void ConstraintGraphNode::addConstraint(Constraint *constraint) {
|
||||||
assert(ConstraintIndex.count(constraint) == 0 && "Constraint re-insertion");
|
assert(ConstraintIndex.count(constraint) == 0 && "Constraint re-insertion");
|
||||||
ConstraintIndex[constraint] = Constraints.size();
|
ConstraintIndex[constraint] = Constraints.size();
|
||||||
Constraints.push_back(constraint);
|
Constraints.push_back(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintGraph::Node::removeConstraint(Constraint *constraint) {
|
void ConstraintGraphNode::removeConstraint(Constraint *constraint) {
|
||||||
auto pos = ConstraintIndex.find(constraint);
|
auto pos = ConstraintIndex.find(constraint);
|
||||||
assert(pos != ConstraintIndex.end());
|
assert(pos != ConstraintIndex.end());
|
||||||
|
|
||||||
@@ -183,8 +183,8 @@ void ConstraintGraph::Node::removeConstraint(Constraint *constraint) {
|
|||||||
Constraints.pop_back();
|
Constraints.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstraintGraph::Node::Adjacency &
|
ConstraintGraphNode::Adjacency &
|
||||||
ConstraintGraph::Node::getAdjacency(TypeVariableType *typeVar) {
|
ConstraintGraphNode::getAdjacency(TypeVariableType *typeVar) {
|
||||||
assert(typeVar != TypeVar && "Cannot be adjacent to oneself");
|
assert(typeVar != TypeVar && "Cannot be adjacent to oneself");
|
||||||
|
|
||||||
// Look for existing adjacency information.
|
// Look for existing adjacency information.
|
||||||
@@ -202,7 +202,7 @@ ConstraintGraph::Node::getAdjacency(TypeVariableType *typeVar) {
|
|||||||
return pos->second;
|
return pos->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintGraph::Node::modifyAdjacency(
|
void ConstraintGraphNode::modifyAdjacency(
|
||||||
TypeVariableType *typeVar,
|
TypeVariableType *typeVar,
|
||||||
std::function<void(Adjacency& adj)> modify) {
|
std::function<void(Adjacency& adj)> modify) {
|
||||||
// Find the adjacency information.
|
// Find the adjacency information.
|
||||||
@@ -237,21 +237,21 @@ void ConstraintGraph::Node::modifyAdjacency(
|
|||||||
Adjacencies.pop_back();
|
Adjacencies.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintGraph::Node::addAdjacency(TypeVariableType *typeVar) {
|
void ConstraintGraphNode::addAdjacency(TypeVariableType *typeVar) {
|
||||||
auto &adjacency = getAdjacency(typeVar);
|
auto &adjacency = getAdjacency(typeVar);
|
||||||
|
|
||||||
// Bump the degree of the adjacency.
|
// Bump the degree of the adjacency.
|
||||||
++adjacency.NumConstraints;
|
++adjacency.NumConstraints;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintGraph::Node::removeAdjacency(TypeVariableType *typeVar) {
|
void ConstraintGraphNode::removeAdjacency(TypeVariableType *typeVar) {
|
||||||
modifyAdjacency(typeVar, [](Adjacency &adj) {
|
modifyAdjacency(typeVar, [](Adjacency &adj) {
|
||||||
assert(adj.NumConstraints > 0 && "No adjacency to remove?");
|
assert(adj.NumConstraints > 0 && "No adjacency to remove?");
|
||||||
--adj.NumConstraints;
|
--adj.NumConstraints;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintGraph::Node::addToEquivalenceClass(
|
void ConstraintGraphNode::addToEquivalenceClass(
|
||||||
ArrayRef<TypeVariableType *> typeVars) {
|
ArrayRef<TypeVariableType *> typeVars) {
|
||||||
assert(TypeVar == TypeVar->getImpl().getRepresentative(nullptr) &&
|
assert(TypeVar == TypeVar->getImpl().getRepresentative(nullptr) &&
|
||||||
"Can't extend equivalence class of non-representative type var");
|
"Can't extend equivalence class of non-representative type var");
|
||||||
@@ -260,14 +260,14 @@ void ConstraintGraph::Node::addToEquivalenceClass(
|
|||||||
EquivalenceClass.append(typeVars.begin(), typeVars.end());
|
EquivalenceClass.append(typeVars.begin(), typeVars.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintGraph::Node::addFixedBinding(TypeVariableType *typeVar) {
|
void ConstraintGraphNode::addFixedBinding(TypeVariableType *typeVar) {
|
||||||
auto &adjacency = getAdjacency(typeVar);
|
auto &adjacency = getAdjacency(typeVar);
|
||||||
|
|
||||||
assert(!adjacency.FixedBinding && "Already marked as a fixed binding?");
|
assert(!adjacency.FixedBinding && "Already marked as a fixed binding?");
|
||||||
adjacency.FixedBinding = true;
|
adjacency.FixedBinding = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintGraph::Node::removeFixedBinding(TypeVariableType *typeVar) {
|
void ConstraintGraphNode::removeFixedBinding(TypeVariableType *typeVar) {
|
||||||
modifyAdjacency(typeVar, [](Adjacency &adj) {
|
modifyAdjacency(typeVar, [](Adjacency &adj) {
|
||||||
assert(adj.FixedBinding && "Not a fixed binding?");
|
assert(adj.FixedBinding && "Not a fixed binding?");
|
||||||
adj.FixedBinding = false;
|
adj.FixedBinding = false;
|
||||||
@@ -358,7 +358,7 @@ void ConstraintGraph::Change::undo(ConstraintGraph &cg) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ChangeKind::ExtendedEquivalenceClass: {
|
case ChangeKind::ExtendedEquivalenceClass: {
|
||||||
Node &node = cg[EquivClass.TypeVar];
|
auto &node = cg[EquivClass.TypeVar];
|
||||||
node.EquivalenceClass.erase(
|
node.EquivalenceClass.erase(
|
||||||
node.EquivalenceClass.begin() + EquivClass.PrevSize,
|
node.EquivalenceClass.begin() + EquivClass.PrevSize,
|
||||||
node.EquivalenceClass.end());
|
node.EquivalenceClass.end());
|
||||||
@@ -398,7 +398,7 @@ void ConstraintGraph::addConstraint(Constraint *constraint) {
|
|||||||
// For the nodes corresponding to each type variable...
|
// For the nodes corresponding to each type variable...
|
||||||
for (auto typeVar : referencedTypeVars) {
|
for (auto typeVar : referencedTypeVars) {
|
||||||
// Find the node for this type variable.
|
// Find the node for this type variable.
|
||||||
Node &node = (*this)[typeVar];
|
auto &node = (*this)[typeVar];
|
||||||
|
|
||||||
// Note the constraint within the node for that type variable.
|
// Note the constraint within the node for that type variable.
|
||||||
node.addConstraint(constraint);
|
node.addConstraint(constraint);
|
||||||
@@ -427,7 +427,7 @@ void ConstraintGraph::removeConstraint(Constraint *constraint) {
|
|||||||
// For the nodes corresponding to each type variable...
|
// For the nodes corresponding to each type variable...
|
||||||
for (auto typeVar : referencedTypeVars) {
|
for (auto typeVar : referencedTypeVars) {
|
||||||
// Find the node for this type variable.
|
// Find the node for this type variable.
|
||||||
Node &node = (*this)[typeVar];
|
auto &node = (*this)[typeVar];
|
||||||
|
|
||||||
// Remove the constraint.
|
// Remove the constraint.
|
||||||
node.removeConstraint(constraint);
|
node.removeConstraint(constraint);
|
||||||
@@ -481,7 +481,7 @@ void ConstraintGraph::bindTypeVariable(TypeVariableType *typeVar, Type fixed) {
|
|||||||
SmallVector<TypeVariableType *, 4> typeVars;
|
SmallVector<TypeVariableType *, 4> typeVars;
|
||||||
llvm::SmallPtrSet<TypeVariableType *, 4> knownTypeVars;
|
llvm::SmallPtrSet<TypeVariableType *, 4> knownTypeVars;
|
||||||
fixed->getTypeVariables(typeVars);
|
fixed->getTypeVariables(typeVars);
|
||||||
Node &node = (*this)[typeVar];
|
auto &node = (*this)[typeVar];
|
||||||
for (auto otherTypeVar : typeVars) {
|
for (auto otherTypeVar : typeVars) {
|
||||||
if (knownTypeVars.insert(otherTypeVar)) {
|
if (knownTypeVars.insert(otherTypeVar)) {
|
||||||
(*this)[otherTypeVar].addFixedBinding(typeVar);
|
(*this)[otherTypeVar].addFixedBinding(typeVar);
|
||||||
@@ -504,7 +504,7 @@ void ConstraintGraph::unbindTypeVariable(TypeVariableType *typeVar, Type fixed){
|
|||||||
SmallVector<TypeVariableType *, 4> typeVars;
|
SmallVector<TypeVariableType *, 4> typeVars;
|
||||||
llvm::SmallPtrSet<TypeVariableType *, 4> knownTypeVars;
|
llvm::SmallPtrSet<TypeVariableType *, 4> knownTypeVars;
|
||||||
fixed->getTypeVariables(typeVars);
|
fixed->getTypeVariables(typeVars);
|
||||||
Node &node = (*this)[typeVar];
|
auto &node = (*this)[typeVar];
|
||||||
for (auto otherTypeVar : typeVars) {
|
for (auto otherTypeVar : typeVars) {
|
||||||
if (knownTypeVars.insert(otherTypeVar)) {
|
if (knownTypeVars.insert(otherTypeVar)) {
|
||||||
(*this)[otherTypeVar].removeFixedBinding(typeVar);
|
(*this)[otherTypeVar].removeFixedBinding(typeVar);
|
||||||
@@ -528,7 +528,7 @@ void ConstraintGraph::gatherConstraints(
|
|||||||
|
|
||||||
/// Depth-first search for connected components
|
/// Depth-first search for connected components
|
||||||
static void connectedComponentsDFS(ConstraintGraph &cg,
|
static void connectedComponentsDFS(ConstraintGraph &cg,
|
||||||
ConstraintGraph::Node &node,
|
ConstraintGraphNode &node,
|
||||||
unsigned component,
|
unsigned component,
|
||||||
SmallVectorImpl<unsigned> &components) {
|
SmallVectorImpl<unsigned> &components) {
|
||||||
// Local function that recurses on the given set of type variables.
|
// Local function that recurses on the given set of type variables.
|
||||||
@@ -644,7 +644,7 @@ unsigned ConstraintGraph::computeConnectedComponents(
|
|||||||
|
|
||||||
#pragma mark Debugging output
|
#pragma mark Debugging output
|
||||||
|
|
||||||
void ConstraintGraph::Node::print(llvm::raw_ostream &out, unsigned indent) {
|
void ConstraintGraphNode::print(llvm::raw_ostream &out, unsigned indent) {
|
||||||
out.indent(indent);
|
out.indent(indent);
|
||||||
TypeVar->print(out);
|
TypeVar->print(out);
|
||||||
out << ":\n";
|
out << ":\n";
|
||||||
@@ -708,7 +708,7 @@ void ConstraintGraph::Node::print(llvm::raw_ostream &out, unsigned indent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintGraph::Node::dump() {
|
void ConstraintGraphNode::dump() {
|
||||||
print(llvm::dbgs(), 0);
|
print(llvm::dbgs(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,7 +762,7 @@ void ConstraintGraph::dumpConnectedComponents() {
|
|||||||
/// provide extra, contextual information about the failure.
|
/// provide extra, contextual information about the failure.
|
||||||
static void _require(bool condition, const Twine &complaint,
|
static void _require(bool condition, const Twine &complaint,
|
||||||
ConstraintGraph &cg,
|
ConstraintGraph &cg,
|
||||||
ConstraintGraph::Node *node,
|
ConstraintGraphNode *node,
|
||||||
const std::function<void()> &extraContext = nullptr) {
|
const std::function<void()> &extraContext = nullptr) {
|
||||||
if (condition)
|
if (condition)
|
||||||
return;
|
return;
|
||||||
@@ -794,7 +794,7 @@ static void printValue(llvm::raw_ostream &os, unsigned value) {
|
|||||||
os << value;
|
os << value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintGraph::Node::verify(ConstraintGraph &cg) {
|
void ConstraintGraphNode::verify(ConstraintGraph &cg) {
|
||||||
#define require(condition, complaint) _require(condition, complaint, cg, this)
|
#define require(condition, complaint) _require(condition, complaint, cg, this)
|
||||||
#define requireWithContext(condition, complaint, context) \
|
#define requireWithContext(condition, complaint, context) \
|
||||||
_require(condition, complaint, cg, this, context)
|
_require(condition, complaint, cg, this, context)
|
||||||
@@ -835,7 +835,8 @@ void ConstraintGraph::Node::verify(ConstraintGraph &cg) {
|
|||||||
llvm::DenseMap<TypeVariableType *, unsigned> expectedAdjacencies;
|
llvm::DenseMap<TypeVariableType *, unsigned> expectedAdjacencies;
|
||||||
for (auto constraint : Constraints) {
|
for (auto constraint : Constraints) {
|
||||||
SmallVector<TypeVariableType *, 4> referencedTypeVars;
|
SmallVector<TypeVariableType *, 4> referencedTypeVars;
|
||||||
gatherReferencedTypeVars(cg.CS, constraint, referencedTypeVars);
|
gatherReferencedTypeVars(cg.getConstraintSystem(), constraint,
|
||||||
|
referencedTypeVars);
|
||||||
|
|
||||||
for (auto adjTypeVar : referencedTypeVars) {
|
for (auto adjTypeVar : referencedTypeVars) {
|
||||||
if (adjTypeVar == TypeVar)
|
if (adjTypeVar == TypeVar)
|
||||||
@@ -974,7 +975,7 @@ void ConstraintGraph::verify() {
|
|||||||
llvm::dbgs() << "\n";
|
llvm::dbgs() << "\n";
|
||||||
});
|
});
|
||||||
|
|
||||||
Node &node = *nodePos->second.NodePtr;
|
auto &node = *nodePos->second.NodePtr;
|
||||||
auto constraintPos = node.ConstraintIndex.find(&constraint);
|
auto constraintPos = node.ConstraintIndex.find(&constraint);
|
||||||
requireWithContext(constraintPos != node.ConstraintIndex.end(),
|
requireWithContext(constraintPos != node.ConstraintIndex.end(),
|
||||||
"type variable doesn't know about constraint",
|
"type variable doesn't know about constraint",
|
||||||
|
|||||||
@@ -35,9 +35,130 @@ class TypeVariableType;
|
|||||||
namespace constraints {
|
namespace constraints {
|
||||||
|
|
||||||
class Constraint;
|
class Constraint;
|
||||||
|
class ConstraintGraph;
|
||||||
class ConstraintGraphScope;
|
class ConstraintGraphScope;
|
||||||
class ConstraintSystem;
|
class ConstraintSystem;
|
||||||
|
|
||||||
|
/// A single node in the constraint graph, which represents a type variable.
|
||||||
|
class ConstraintGraphNode {
|
||||||
|
/// Describes information about an adjacency between two type variables.
|
||||||
|
struct Adjacency {
|
||||||
|
/// Index into the vector of adjacent type variables, \c Adjacencies.
|
||||||
|
unsigned Index : 31;
|
||||||
|
|
||||||
|
/// Whether a fixed type binding relates the two type variables.
|
||||||
|
unsigned FixedBinding : 1;
|
||||||
|
|
||||||
|
/// The number of constraints that link this type variable to the
|
||||||
|
/// enclosing node.
|
||||||
|
unsigned NumConstraints;
|
||||||
|
|
||||||
|
bool empty() const {
|
||||||
|
return !FixedBinding && !NumConstraints;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ConstraintGraphNode(TypeVariableType *typeVar) : TypeVar(typeVar) { }
|
||||||
|
|
||||||
|
ConstraintGraphNode(const ConstraintGraphNode&) = delete;
|
||||||
|
ConstraintGraphNode &operator=(const ConstraintGraphNode&) = delete;
|
||||||
|
|
||||||
|
/// Retrieve the type variable this node represents.
|
||||||
|
TypeVariableType *getTypeVariable() const { return TypeVar; }
|
||||||
|
|
||||||
|
/// Retrieve the set of constraints that mention this type variable.
|
||||||
|
///
|
||||||
|
/// These are the hyperedges of the graph, connecting this node to
|
||||||
|
/// various other nodes.
|
||||||
|
ArrayRef<Constraint *> getConstraints() const { return Constraints; }
|
||||||
|
|
||||||
|
/// Retrieve the set of type variables to which this node is adjacent.
|
||||||
|
ArrayRef<TypeVariableType *> getAdjacencies() const {
|
||||||
|
return Adjacencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve all of the type variables in the same equivalence class
|
||||||
|
/// as this type variable.
|
||||||
|
ArrayRef<TypeVariableType *> getEquivalenceClass() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Retrieve all of the type variables in the same equivalence class
|
||||||
|
/// as this type variable.
|
||||||
|
ArrayRef<TypeVariableType *> getEquivalenceClassUnsafe() const;
|
||||||
|
|
||||||
|
/// Add a constraint to the list of constraints.
|
||||||
|
void addConstraint(Constraint *constraint);
|
||||||
|
|
||||||
|
/// Remove a constraint from the list of constraints.
|
||||||
|
///
|
||||||
|
/// Note that this only removes the constraint itself; it does not
|
||||||
|
/// remove the corresponding adjacencies.
|
||||||
|
void removeConstraint(Constraint *constraint);
|
||||||
|
|
||||||
|
/// Retrieve adjacency information for the given type variable.
|
||||||
|
Adjacency &getAdjacency(TypeVariableType *typeVar);
|
||||||
|
|
||||||
|
/// Modify the adjacency information for the given type variable
|
||||||
|
/// directly. If the adjacency becomes empty afterward, it will be
|
||||||
|
/// removed.
|
||||||
|
void modifyAdjacency(TypeVariableType *typeVar,
|
||||||
|
std::function<void(Adjacency& adj)> modify);
|
||||||
|
|
||||||
|
/// Add an adjacency to the list of adjacencies.
|
||||||
|
void addAdjacency(TypeVariableType *typeVar);
|
||||||
|
|
||||||
|
/// Remove an adjacency from the list of adjacencies.
|
||||||
|
void removeAdjacency(TypeVariableType *typeVar);
|
||||||
|
|
||||||
|
/// Add the given type variables to this node's equivalence class.
|
||||||
|
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);
|
||||||
|
|
||||||
|
/// The type variable this node represents.
|
||||||
|
TypeVariableType *TypeVar;
|
||||||
|
|
||||||
|
/// The vector of constraints that mention this type variable, in a stable
|
||||||
|
/// order for iteration.
|
||||||
|
SmallVector<Constraint *, 2> Constraints;
|
||||||
|
|
||||||
|
/// A mapping from the set of constraints that mention this type variable
|
||||||
|
/// to the index within the vector of constraints.
|
||||||
|
llvm::SmallDenseMap<Constraint *, unsigned, 2> ConstraintIndex;
|
||||||
|
|
||||||
|
/// The set of adjacent type variables, in a stable order.
|
||||||
|
SmallVector<TypeVariableType *, 2> Adjacencies;
|
||||||
|
|
||||||
|
/// A mapping from each of the type variables adjacent to this
|
||||||
|
/// type variable to the index of the adjacency information in
|
||||||
|
/// \c Adjacencies.
|
||||||
|
llvm::SmallDenseMap<TypeVariableType *, Adjacency, 2> AdjacencyInfo;
|
||||||
|
|
||||||
|
/// All of the type variables in the same equivalence class as this
|
||||||
|
/// representative type variable.
|
||||||
|
///
|
||||||
|
/// Note that this field is only valid for type variables that
|
||||||
|
/// are representatives of their equivalence classes.
|
||||||
|
mutable SmallVector<TypeVariableType *, 2> EquivalenceClass;
|
||||||
|
|
||||||
|
/// Print this graph node.
|
||||||
|
void print(llvm::raw_ostream &out, unsigned indent);
|
||||||
|
|
||||||
|
LLVM_ATTRIBUTE_DEPRECATED(void dump() LLVM_ATTRIBUTE_USED,
|
||||||
|
"only for use within the debugger");
|
||||||
|
|
||||||
|
/// Verify the invariants of this node within the given constraint graph.
|
||||||
|
void verify(ConstraintGraph &cg);
|
||||||
|
|
||||||
|
friend class ConstraintGraph;
|
||||||
|
};
|
||||||
|
|
||||||
/// A graph that describes the relationships among the various type variables
|
/// A graph that describes the relationships among the various type variables
|
||||||
/// and constraints within a constraint system.
|
/// and constraints within a constraint system.
|
||||||
///
|
///
|
||||||
@@ -49,126 +170,6 @@ class ConstraintSystem;
|
|||||||
/// its adjacencies (the type variables) separately.
|
/// its adjacencies (the type variables) separately.
|
||||||
class ConstraintGraph {
|
class ConstraintGraph {
|
||||||
public:
|
public:
|
||||||
/// A single node in the constraint graph, which represents a type variable.
|
|
||||||
class Node {
|
|
||||||
/// Describes information about an adjacency between two type variables.
|
|
||||||
struct Adjacency {
|
|
||||||
/// Index into the vector of adjacent type variables, \c Adjacencies.
|
|
||||||
unsigned Index : 31;
|
|
||||||
|
|
||||||
/// Whether a fixed type binding relates the two type variables.
|
|
||||||
unsigned FixedBinding : 1;
|
|
||||||
|
|
||||||
/// The number of constraints that link this type variable to the
|
|
||||||
/// enclosing node.
|
|
||||||
unsigned NumConstraints;
|
|
||||||
|
|
||||||
bool empty() const {
|
|
||||||
return !FixedBinding && !NumConstraints;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Node(TypeVariableType *typeVar) : TypeVar(typeVar) { }
|
|
||||||
|
|
||||||
Node(const Node&) = delete;
|
|
||||||
Node &operator=(const Node&) = delete;
|
|
||||||
|
|
||||||
/// Retrieve the type variable this node represents.
|
|
||||||
TypeVariableType *getTypeVariable() const { return TypeVar; }
|
|
||||||
|
|
||||||
/// Retrieve the set of constraints that mention this type variable.
|
|
||||||
///
|
|
||||||
/// These are the hyperedges of the graph, connecting this node to
|
|
||||||
/// various other nodes.
|
|
||||||
ArrayRef<Constraint *> getConstraints() const { return Constraints; }
|
|
||||||
|
|
||||||
/// Retrieve the set of type variables to which this node is adjacent.
|
|
||||||
ArrayRef<TypeVariableType *> getAdjacencies() const {
|
|
||||||
return Adjacencies;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieve all of the type variables in the same equivalence class
|
|
||||||
/// as this type variable.
|
|
||||||
ArrayRef<TypeVariableType *> getEquivalenceClass() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Retrieve all of the type variables in the same equivalence class
|
|
||||||
/// as this type variable.
|
|
||||||
ArrayRef<TypeVariableType *> getEquivalenceClassUnsafe() const;
|
|
||||||
|
|
||||||
/// Add a constraint to the list of constraints.
|
|
||||||
void addConstraint(Constraint *constraint);
|
|
||||||
|
|
||||||
/// Remove a constraint from the list of constraints.
|
|
||||||
///
|
|
||||||
/// Note that this only removes the constraint itself; it does not
|
|
||||||
/// remove the corresponding adjacencies.
|
|
||||||
void removeConstraint(Constraint *constraint);
|
|
||||||
|
|
||||||
/// Retrieve adjacency information for the given type variable.
|
|
||||||
Adjacency &getAdjacency(TypeVariableType *typeVar);
|
|
||||||
|
|
||||||
/// Modify the adjacency information for the given type variable
|
|
||||||
/// directly. If the adjacency becomes empty afterward, it will be
|
|
||||||
/// removed.
|
|
||||||
void modifyAdjacency(TypeVariableType *typeVar,
|
|
||||||
std::function<void(Adjacency& adj)> modify);
|
|
||||||
|
|
||||||
/// Add an adjacency to the list of adjacencies.
|
|
||||||
void addAdjacency(TypeVariableType *typeVar);
|
|
||||||
|
|
||||||
/// Remove an adjacency from the list of adjacencies.
|
|
||||||
void removeAdjacency(TypeVariableType *typeVar);
|
|
||||||
|
|
||||||
/// Add the given type variables to this node's equivalence class.
|
|
||||||
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);
|
|
||||||
|
|
||||||
/// The type variable this node represents.
|
|
||||||
TypeVariableType *TypeVar;
|
|
||||||
|
|
||||||
/// The vector of constraints that mention this type variable, in a stable
|
|
||||||
/// order for iteration.
|
|
||||||
SmallVector<Constraint *, 2> Constraints;
|
|
||||||
|
|
||||||
/// A mapping from the set of constraints that mention this type variable
|
|
||||||
/// to the index within the vector of constraints.
|
|
||||||
llvm::SmallDenseMap<Constraint *, unsigned, 2> ConstraintIndex;
|
|
||||||
|
|
||||||
/// The set of adjacent type variables, in a stable order.
|
|
||||||
SmallVector<TypeVariableType *, 2> Adjacencies;
|
|
||||||
|
|
||||||
/// A mapping from each of the type variables adjacent to this
|
|
||||||
/// type variable to the index of the adjacency information in
|
|
||||||
/// \c Adjacencies.
|
|
||||||
llvm::SmallDenseMap<TypeVariableType *, Adjacency, 2> AdjacencyInfo;
|
|
||||||
|
|
||||||
/// All of the type variables in the same equivalence class as this
|
|
||||||
/// representative type variable.
|
|
||||||
///
|
|
||||||
/// Note that this field is only valid for type variables that
|
|
||||||
/// are representatives of their equivalence classes.
|
|
||||||
mutable SmallVector<TypeVariableType *, 2> EquivalenceClass;
|
|
||||||
|
|
||||||
/// Print this graph node.
|
|
||||||
void print(llvm::raw_ostream &out, unsigned indent);
|
|
||||||
|
|
||||||
LLVM_ATTRIBUTE_DEPRECATED(void dump() LLVM_ATTRIBUTE_USED,
|
|
||||||
"only for use within the debugger");
|
|
||||||
|
|
||||||
/// Verify the invariants of this node within the given constraint graph.
|
|
||||||
void verify(ConstraintGraph &cg);
|
|
||||||
|
|
||||||
friend class ConstraintGraph;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Constraint a constraint graph for the given constraint system.
|
/// Constraint a constraint graph for the given constraint system.
|
||||||
ConstraintGraph(ConstraintSystem &cs);
|
ConstraintGraph(ConstraintSystem &cs);
|
||||||
|
|
||||||
@@ -183,12 +184,13 @@ public:
|
|||||||
ConstraintSystem &getConstraintSystem() const { return CS; }
|
ConstraintSystem &getConstraintSystem() const { return CS; }
|
||||||
|
|
||||||
/// Access the node corresponding to the given type variable.
|
/// Access the node corresponding to the given type variable.
|
||||||
Node &operator[](TypeVariableType *typeVar) {
|
ConstraintGraphNode &operator[](TypeVariableType *typeVar) {
|
||||||
return lookupNode(typeVar).first;
|
return lookupNode(typeVar).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve the node and index corresponding to the given type variable.
|
/// Retrieve the node and index corresponding to the given type variable.
|
||||||
std::pair<Node &, unsigned> lookupNode(TypeVariableType *typeVar);
|
std::pair<ConstraintGraphNode &, unsigned>
|
||||||
|
lookupNode(TypeVariableType *typeVar);
|
||||||
|
|
||||||
/// Add a new constraint to the graph.
|
/// Add a new constraint to the graph.
|
||||||
void addConstraint(Constraint *constraint);
|
void addConstraint(Constraint *constraint);
|
||||||
@@ -278,7 +280,7 @@ private:
|
|||||||
struct StoredNode {
|
struct StoredNode {
|
||||||
/// \brief The node itself, stored as a pointer so we can efficiently
|
/// \brief The node itself, stored as a pointer so we can efficiently
|
||||||
/// copy/move \c StoredNodes.
|
/// copy/move \c StoredNodes.
|
||||||
Node *NodePtr;
|
ConstraintGraphNode *NodePtr;
|
||||||
|
|
||||||
/// \brief The index in the \c TypeVariables vector where the corresponding
|
/// \brief The index in the \c TypeVariables vector where the corresponding
|
||||||
/// type variable is stored.
|
/// type variable is stored.
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ ConstraintSystem::ConstraintSystem(TypeChecker &tc, DeclContext *dc)
|
|||||||
|
|
||||||
// Create the constraint graph.
|
// Create the constraint graph.
|
||||||
// FIXME: Enable this by default.
|
// FIXME: Enable this by default.
|
||||||
// CG = new ConstraintGraph(*this);
|
CG = new ConstraintGraph(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstraintSystem::~ConstraintSystem() {
|
ConstraintSystem::~ConstraintSystem() {
|
||||||
|
|||||||
Reference in New Issue
Block a user