/builds/2mk6rsew/0/parcoach/parcoach/src/include/parcoach/andersen/SparseBitVectorGraph.h
Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef ANDERSEN_SPARSEBITVECTOR_GRAPH_H |
2 | | #define ANDERSEN_SPARSEBITVECTOR_GRAPH_H |
3 | | |
4 | | #include "GraphTraits.h" |
5 | | #include "NodeFactory.h" |
6 | | |
7 | | #include "llvm/ADT/DenseMap.h" |
8 | | #include "llvm/ADT/SparseBitVector.h" |
9 | | |
10 | | #include <algorithm> |
11 | | #include <unordered_map> |
12 | | |
13 | | // The node of a graph class where successor edges are represented by sparse bit |
14 | | // vectors |
15 | | class SparseBitVectorGraphNode { |
16 | | private: |
17 | | NodeIndex idx; |
18 | | llvm::SparseBitVector<> succs; |
19 | | |
20 | 94.3k | void insertEdge(NodeIndex n) { return succs.set(n); } |
21 | | |
22 | 42.6k | SparseBitVectorGraphNode(NodeIndex i) : idx(i) {} |
23 | | |
24 | | public: |
25 | | using iterator = llvm::SparseBitVector<>::iterator; |
26 | | |
27 | 16.4k | NodeIndex getNodeIndex() const { return idx; } |
28 | | |
29 | 25.8k | iterator begin() const { return succs.begin(); } |
30 | 25.8k | iterator end() const { return succs.end(); } |
31 | | |
32 | 0 | unsigned succ_getSize() const { return succs.count(); } |
33 | | |
34 | | friend class SparseBitVectorGraph; |
35 | | }; |
36 | | |
37 | | // A graph class where successor edges are represented by sparse bit vectors |
38 | | class SparseBitVectorGraph { |
39 | | private: |
40 | | // Here we cannot use DenseMap because we need iterator stability: we might |
41 | | // want to call getOrInsertNode() when another node is being iterated |
42 | | using NodeMapTy = std::unordered_map<NodeIndex, SparseBitVectorGraphNode>; |
43 | | NodeMapTy graph; |
44 | | |
45 | | public: |
46 | | using iterator = NodeMapTy::iterator; |
47 | | using const_iterator = NodeMapTy::const_iterator; |
48 | | |
49 | | private: |
50 | 134k | iterator getOrInsertNodeMap(NodeIndex idx) { |
51 | 134k | auto itr = graph.find(idx); |
52 | 134k | if (itr == graph.end()) |
53 | 42.6k | itr = graph.insert(std::make_pair(idx, SparseBitVectorGraphNode(idx))) |
54 | 42.6k | .first; |
55 | 134k | return itr; |
56 | 134k | } |
57 | | |
58 | | public: |
59 | 1.76k | SparseBitVectorGraph() {} |
60 | | |
61 | 39.6k | SparseBitVectorGraphNode *getOrInsertNode(NodeIndex idx) { |
62 | 39.6k | auto itr = getOrInsertNodeMap(idx); |
63 | 39.6k | return &(itr->second); |
64 | 39.6k | } |
65 | | |
66 | 94.3k | void insertEdge(NodeIndex src, NodeIndex dst) { |
67 | 94.3k | auto itr = getOrInsertNodeMap(src); |
68 | 94.3k | (itr->second).insertEdge(dst); |
69 | 94.3k | } |
70 | | |
71 | | // src's successors += dst's successors |
72 | 0 | void mergeEdge(NodeIndex src, NodeIndex dst) { |
73 | 0 | auto dstItr = graph.find(dst); |
74 | 0 | if (dstItr == graph.end()) |
75 | 0 | return; |
76 | 0 |
|
77 | 0 | auto srcItr = getOrInsertNodeMap(src); |
78 | 0 | (srcItr->second).succs |= (dstItr->second).succs; |
79 | 0 | } |
80 | | |
81 | 0 | SparseBitVectorGraphNode *getNodeWithIndex(NodeIndex idx) { |
82 | 0 | auto itr = graph.find(idx); |
83 | 0 | if (itr == graph.end()) |
84 | 0 | return nullptr; |
85 | 0 | else |
86 | 0 | return &(itr->second); |
87 | 0 | } |
88 | | |
89 | 0 | unsigned getSize() const { return graph.size(); } |
90 | | |
91 | 1.76k | void releaseMemory() { graph.clear(); } |
92 | | |
93 | 1.76k | iterator begin() { return graph.begin(); } |
94 | 1.76k | iterator end() { return graph.end(); } |
95 | 0 | const_iterator begin() const { return graph.begin(); } |
96 | 0 | const_iterator end() const { return graph.end(); } |
97 | | }; |
98 | | |
99 | | // Specialize the AnderGraphTraits for SparseBitVectorGraph |
100 | | template <> class AndersGraphTraits<SparseBitVectorGraph> { |
101 | | public: |
102 | | typedef SparseBitVectorGraphNode NodeType; |
103 | | typedef MapValueIterator<SparseBitVectorGraph::iterator> NodeIterator; |
104 | | typedef SparseBitVectorGraphNode::iterator ChildIterator; |
105 | | |
106 | 25.8k | static inline ChildIterator child_begin(NodeType *n) { return n->begin(); } |
107 | 25.8k | static inline ChildIterator child_end(NodeType *n) { return n->end(); } |
108 | | |
109 | 1.76k | static inline NodeIterator node_begin(SparseBitVectorGraph *g) { |
110 | 1.76k | return NodeIterator(g->begin()); |
111 | 1.76k | } |
112 | 1.76k | static inline NodeIterator node_end(SparseBitVectorGraph *g) { |
113 | 1.76k | return NodeIterator(g->end()); |
114 | 1.76k | } |
115 | | }; |
116 | | |
117 | | #endif |