@@ -33,6 +33,8 @@ class LPMUpdater;
33
33
// / 1. Single instruction node containing just one instruction.
34
34
// / 2. Multiple instruction node where two or more instructions from
35
35
// / the same basic block are merged into one node.
36
+ // / 3. Root node is a special node that connects to all components such that
37
+ // / there is always a path from it to any node in the graph.
36
38
class DDGNode : public DDGNodeBase {
37
39
public:
38
40
using InstructionListType = SmallVectorImpl<Instruction *>;
@@ -41,6 +43,7 @@ class DDGNode : public DDGNodeBase {
41
43
Unknown,
42
44
SingleInstruction,
43
45
MultiInstruction,
46
+ Root,
44
47
};
45
48
46
49
DDGNode () = delete ;
@@ -78,6 +81,22 @@ class DDGNode : public DDGNodeBase {
78
81
NodeKind Kind;
79
82
};
80
83
84
+ // / Subclass of DDGNode representing the root node of the graph.
85
+ // / There should only be one such node in a given graph.
86
+ class RootDDGNode : public DDGNode {
87
+ public:
88
+ RootDDGNode () : DDGNode(NodeKind::Root) {}
89
+ RootDDGNode (const RootDDGNode &N) = delete ;
90
+ RootDDGNode (RootDDGNode &&N) : DDGNode(std::move(N)) {}
91
+ ~RootDDGNode () {}
92
+
93
+ // / Define classof to be able to use isa<>, cast<>, dyn_cast<>, etc.
94
+ static bool classof (const DDGNode *N) {
95
+ return N->getKind () == NodeKind::Root;
96
+ }
97
+ static bool classof (const RootDDGNode *N) { return true ; }
98
+ };
99
+
81
100
// / Subclass of DDGNode representing single or multi-instruction nodes.
82
101
class SimpleDDGNode : public DDGNode {
83
102
public:
@@ -139,10 +158,12 @@ class SimpleDDGNode : public DDGNode {
139
158
// / Data Dependency Graph Edge.
140
159
// / An edge in the DDG can represent a def-use relationship or
141
160
// / a memory dependence based on the result of DependenceAnalysis.
161
+ // / A rooted edge connects the root node to one of the components
162
+ // / of the graph.
142
163
class DDGEdge : public DDGEdgeBase {
143
164
public:
144
165
// / The kind of edge in the DDG
145
- enum class EdgeKind { Unknown, RegisterDefUse, MemoryDependence };
166
+ enum class EdgeKind { Unknown, RegisterDefUse, MemoryDependence, Rooted };
146
167
147
168
explicit DDGEdge (DDGNode &N) = delete;
148
169
DDGEdge (DDGNode &N, EdgeKind K) : DDGEdgeBase(N), Kind(K) {}
@@ -169,6 +190,10 @@ class DDGEdge : public DDGEdgeBase {
169
190
// / Return true if this is a memory dependence edge, and false otherwise.
170
191
bool isMemoryDependence () const { return Kind == EdgeKind::MemoryDependence; }
171
192
193
+ // / Return true if this is an edge stemming from the root node, and false
194
+ // / otherwise.
195
+ bool isRooted () const { return Kind == EdgeKind::Rooted; }
196
+
172
197
private:
173
198
EdgeKind Kind;
174
199
};
@@ -182,14 +207,21 @@ template <typename NodeType> class DependenceGraphInfo {
182
207
DependenceGraphInfo () = delete ;
183
208
DependenceGraphInfo (const DependenceGraphInfo &G) = delete ;
184
209
DependenceGraphInfo (const std::string &N, const DependenceInfo &DepInfo)
185
- : Name(N), DI(DepInfo) {}
210
+ : Name(N), DI(DepInfo), Root( nullptr ) {}
186
211
DependenceGraphInfo (DependenceGraphInfo &&G)
187
- : Name(std::move(G.Name)), DI(std::move(G.DI)) {}
212
+ : Name(std::move(G.Name)), DI(std::move(G.DI)), Root(G.Root) {}
188
213
virtual ~DependenceGraphInfo () {}
189
214
190
215
// / Return the label that is used to name this graph.
191
216
const StringRef getName () const { return Name; }
192
217
218
+ // / Return the root node of the graph.
219
+ NodeType &getRoot () const {
220
+ assert (Root && " Root node is not available yet. Graph construction may "
221
+ " still be in progress\n " );
222
+ return *Root;
223
+ }
224
+
193
225
protected:
194
226
// Name of the graph.
195
227
std::string Name;
@@ -198,6 +230,10 @@ template <typename NodeType> class DependenceGraphInfo {
198
230
// dependencies don't need to be stored. Instead when the dependence is
199
231
// queried it is recomputed using @DI.
200
232
const DependenceInfo DI;
233
+
234
+ // A special node in the graph that has an edge to every connected component of
235
+ // the graph, to ensure all nodes are reachable in a graph walk.
236
+ NodeType *Root = nullptr ;
201
237
};
202
238
203
239
using DDGInfo = DependenceGraphInfo<DDGNode>;
@@ -217,6 +253,12 @@ class DataDependenceGraph : public DDGBase, public DDGInfo {
217
253
DataDependenceGraph (Function &F, DependenceInfo &DI);
218
254
DataDependenceGraph (const Loop &L, DependenceInfo &DI);
219
255
~DataDependenceGraph ();
256
+
257
+ protected:
258
+ // / Add node \p N to the graph, if it's not added yet, and keep track of
259
+ // / the root node. Return true if node is successfully added.
260
+ bool addNode (NodeType &N);
261
+
220
262
};
221
263
222
264
// / Concrete implementation of a pure data dependence graph builder. This class
@@ -230,6 +272,12 @@ class DDGBuilder : public AbstractDependenceGraphBuilder<DataDependenceGraph> {
230
272
DDGBuilder (DataDependenceGraph &G, DependenceInfo &D,
231
273
const BasicBlockListType &BBs)
232
274
: AbstractDependenceGraphBuilder(G, D, BBs) {}
275
+ DDGNode &createRootNode () final override {
276
+ auto *RN = new RootDDGNode ();
277
+ assert (RN && " Failed to allocate memory for DDG root node." );
278
+ Graph.addNode (*RN);
279
+ return *RN;
280
+ }
233
281
DDGNode &createFineGrainedNode (Instruction &I) final override {
234
282
auto *SN = new SimpleDDGNode (I);
235
283
assert (SN && " Failed to allocate memory for simple DDG node." );
@@ -248,6 +296,14 @@ class DDGBuilder : public AbstractDependenceGraphBuilder<DataDependenceGraph> {
248
296
Graph.connect (Src, Tgt, *E);
249
297
return *E;
250
298
}
299
+ DDGEdge &createRootedEdge (DDGNode &Src, DDGNode &Tgt) final override {
300
+ auto *E = new DDGEdge (Tgt, DDGEdge::EdgeKind::Rooted);
301
+ assert (E && " Failed to allocate memory for edge" );
302
+ assert (isa<RootDDGNode>(Src) && " Expected root node" );
303
+ Graph.connect (Src, Tgt, *E);
304
+ return *E;
305
+ }
306
+
251
307
};
252
308
253
309
raw_ostream &operator <<(raw_ostream &OS, const DDGNode &N);
@@ -317,7 +373,9 @@ template <> struct GraphTraits<DDGNode *> {
317
373
template <>
318
374
struct GraphTraits <DataDependenceGraph *> : public GraphTraits<DDGNode *> {
319
375
using nodes_iterator = DataDependenceGraph::iterator;
320
- static NodeRef getEntryNode (DataDependenceGraph *DG) { return *DG->begin (); }
376
+ static NodeRef getEntryNode (DataDependenceGraph *DG) {
377
+ return &DG->getRoot ();
378
+ }
321
379
static nodes_iterator nodes_begin (DataDependenceGraph *DG) {
322
380
return DG->begin ();
323
381
}
@@ -357,7 +415,7 @@ struct GraphTraits<const DataDependenceGraph *>
357
415
: public GraphTraits<const DDGNode *> {
358
416
using nodes_iterator = DataDependenceGraph::const_iterator;
359
417
static NodeRef getEntryNode (const DataDependenceGraph *DG) {
360
- return * DG->begin ();
418
+ return & DG->getRoot ();
361
419
}
362
420
static nodes_iterator nodes_begin (const DataDependenceGraph *DG) {
363
421
return DG->begin ();
0 commit comments