@@ -36,17 +36,34 @@ class DataNode : public llvm::DGNode<DataNode<DataType, EdgeType>, EdgeType> {
36
36
37
37
DataType getData () const { return Data; }
38
38
39
- void addPred (EdgeType &E){ PredEdges.insert (&E); }
40
- const llvm::SetVector<EdgeType *> &getPreds () { return PredEdges; }
39
+ void connectTo (NodeType &Other) {
40
+ auto *BLR = new EdgeType (Other);
41
+ this ->addEdge (*BLR);
42
+ auto *BRL = new EdgeType (*this );
43
+ Other.addPredecessor (*BRL);
44
+ }
45
+
46
+ const llvm::SetVector<EdgeType *> &getPredecessors () {
47
+ return PredecessorEdges;
48
+ }
41
49
50
+ // Nodes are defined exactly by the data they contain, not by their
51
+ // connections to other nodes.
42
52
bool isEqualTo (const DataNode &N) const { return this ->Data == N.Data ; }
43
53
44
54
private:
55
+ // Data element stored in each node. This is used by isEqualTo to discriminate
56
+ // between nodes.
45
57
DataType Data;
46
58
47
- llvm::SetVector<EdgeType *> PredEdges;
59
+ // While the constraint graph is directed, we want to efficiently traverse
60
+ // edges in the opposite direction. This set contains an edge entry pointing
61
+ // back to every node that has an edge to this node.
62
+ llvm::SetVector<EdgeType *> PredecessorEdges;
63
+ void addPredecessor (EdgeType &E){ PredecessorEdges.insert (&E); }
48
64
};
49
65
66
+ // Boilerplate template specialization
50
67
template <typename Data, typename EdgeType>
51
68
struct llvm ::GraphTraits<DataNode<Data, EdgeType> *> {
52
69
using NodeRef = DataNode<Data, EdgeType> *;
@@ -110,13 +127,9 @@ class DataGraph :
110
127
}
111
128
112
129
void addEdge (Data L, Data R) {
113
- NodeType *BL = this ->addVertex (L);
114
- NodeType *BR = this ->addVertex (R);
115
-
116
- auto *BLR = new EdgeType (*BR);
117
- BL->addEdge (*BLR);
118
- auto *BRL = new EdgeType (*BL);
119
- BR->addPred (*BRL);
130
+ NodeType *BL = this ->findOrCreateNode (L);
131
+ NodeType *BR = this ->findOrCreateNode (R);
132
+ BL->connectTo (*BR);
120
133
}
121
134
122
135
bool getNeighbors (Data D, std::set<Data> &DataSet, bool Succ){
@@ -128,7 +141,7 @@ class DataGraph :
128
141
if (Succ)
129
142
Edges = (*N)->getEdges ();
130
143
else
131
- Edges = (*N)->getPreds ();
144
+ Edges = (*N)->getPredecessors ();
132
145
for (auto *E : Edges)
133
146
DataSet.insert (E->getTargetNode ().getData ());
134
147
return !DataSet.empty ();
@@ -151,7 +164,10 @@ class DataGraph :
151
164
}
152
165
153
166
protected:
154
- virtual NodeType *addVertex (Data D) {
167
+ // Finds the node containing the Data if it exists, otherwise a new Node
168
+ // is allocated. Node equality is defined only by the data stored in a node,
169
+ // so if any node already contains the data, this node will be found.
170
+ virtual NodeType *findOrCreateNode (Data D) {
155
171
auto *OldN = this ->findNode (NodeType (D));
156
172
if (OldN != this ->end ())
157
173
return *OldN;
@@ -182,7 +198,7 @@ class ConstraintsGraph : public DataGraph<Atom *> {
182
198
protected:
183
199
// Add vertex is overridden to save const atoms as they are added to the graph
184
200
// so that getAllConstAtoms can efficiently retrieve them.
185
- NodeType *addVertex (Atom *A) override ;
201
+ NodeType *findOrCreateNode (Atom *A) override ;
186
202
private:
187
203
std::set<ConstAtom*> AllConstAtoms;
188
204
};
0 commit comments