Coverage Report

Created: 2023-10-30 17:15

/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