Coverage Report

Created: 2023-10-30 17:15

/builds/2mk6rsew/0/parcoach/parcoach/src/aSSA/PTACallGraph.h
Line
Count
Source
1
#ifndef PTACALLGRAPH_H
2
#define PTACALLGRAPH_H
3
4
#include "llvm/ADT/GraphTraits.h"
5
#include "llvm/ADT/STLExtras.h"
6
#include "llvm/IR/Intrinsics.h"
7
#include "llvm/IR/ValueHandle.h"
8
#include "llvm/IR/ValueMap.h"
9
#include "llvm/Passes/PassBuilder.h"
10
11
#include <map>
12
#include <set>
13
14
namespace llvm {
15
class CallBase;
16
class Function;
17
class Module;
18
} // namespace llvm
19
class PTACallGraphNode;
20
class Andersen;
21
22
class PTACallGraphNode {
23
public:
24
  using CallRecord = std::pair<llvm::CallBase const *, PTACallGraphNode *>;
25
26
  using CalledFunctionsVector = std::vector<CallRecord>;
27
28
23.3k
  inline PTACallGraphNode(llvm::Function *F) : F(F) {}
29
30
23.3k
  ~PTACallGraphNode() {}
31
32
  using iterator = std::vector<CallRecord>::iterator;
33
  using const_iterator = std::vector<CallRecord>::const_iterator;
34
35
  /// \brief Returns the function that this call graph node represents.
36
434k
  llvm::Function *getFunction() const { return F; }
37
38
179k
  inline const_iterator begin() const { return CalledFunctions.begin(); }
39
370k
  inline const_iterator end() const { return CalledFunctions.end(); }
40
41
  /// \brief Adds a function to the list of functions called by this one.
42
  void addCalledFunction(llvm::CallBase const *CB, PTACallGraphNode *M);
43
44
private:
45
  friend class PTACallGraph;
46
47
  llvm::AssertingVH<llvm::Function> F;
48
49
  std::vector<CallRecord> CalledFunctions;
50
};
51
52
class PTACallGraph {
53
public:
54
  using FunctionMapTy =
55
      std::map<llvm::Function const *, std::unique_ptr<PTACallGraphNode>>;
56
  using iterator = FunctionMapTy::iterator;
57
  using const_iterator = FunctionMapTy::const_iterator;
58
59
private:
60
  Andersen const &AA;
61
62
  /// \brief A map from \c Function* to \c CallGraphNode*.
63
  FunctionMapTy FunctionMap;
64
65
  // Must be main
66
  PTACallGraphNode *Root;
67
68
  PTACallGraphNode *ProgEntry;
69
70
  std::set<llvm::Function const *> reachableFunctions;
71
72
  /// \brief This node has edges to all external functions and those internal
73
  /// functions that have their address taken.
74
  PTACallGraphNode *ExternalCallingNode;
75
76
  /// \brief This node has edges to it from all functions making indirect calls
77
  /// or calling an external function.
78
  std::unique_ptr<PTACallGraphNode> CallsExternalNode;
79
80
  /// \brief Add a function to the call graph, and link the node to all of the
81
  /// functions that it calls.
82
  void addToCallGraph(llvm::Function const &F);
83
84
  llvm::ValueMap<llvm::Instruction const *, std::set<llvm::Function const *>>
85
      indirectCallMap;
86
87
  PTACallGraphNode *getOrInsertFunction(llvm::Function const *F);
88
89
public:
90
  explicit PTACallGraph(llvm::Module const &M, Andersen const &AA);
91
  ~PTACallGraph();
92
93
1.75k
  PTACallGraphNode *getEntry() const { return Root; }
94
95
  /// \brief Returns the \c CallGraphNode which is used to represent
96
  /// undetermined calls into the callgraph.
97
5.28k
  PTACallGraphNode *getExternalCallingNode() const {
98
5.28k
    return ExternalCallingNode;
99
5.28k
  }
100
101
  bool isReachableFromEntry(llvm::Function const &F) const;
102
28
  auto const &getIndirectCallMap() const { return indirectCallMap; }
103
};
104
105
class PTACallGraphAnalysis
106
    : public llvm::AnalysisInfoMixin<PTACallGraphAnalysis> {
107
  friend llvm::AnalysisInfoMixin<PTACallGraphAnalysis>;
108
  static llvm::AnalysisKey Key;
109
110
public:
111
  // We return a unique_ptr to ensure stability of the analysis' internal state.
112
  using Result = std::unique_ptr<PTACallGraph>;
113
  static Result run(llvm::Module &M, llvm::ModuleAnalysisManager &);
114
};
115
116
//===----------------------------------------------------------------------===//
117
// GraphTraits specializations for call graphs so that they can be treated as
118
// graphs by the generic graph algorithms.
119
//
120
121
// Provide graph traits for tranversing call graphs using standard graph
122
// traversals.
123
124
namespace llvm {
125
126
template <> struct GraphTraits<PTACallGraphNode const *> {
127
  using NodeType = const PTACallGraphNode;
128
  using NodeRef = NodeType *;
129
130
  using CGNPairTy = PTACallGraphNode::CallRecord;
131
132
190k
  static NodeRef CGNDeref(CGNPairTy P) { return P.second; }
133
134
  typedef mapped_iterator<NodeType::const_iterator, decltype(&CGNDeref)>
135
      ChildIteratorType;
136
137
70.1k
  static inline ChildIteratorType child_begin(NodeType *N) {
138
70.1k
    return map_iterator(N->begin(), CGNDeref);
139
70.1k
  }
140
260k
  static inline ChildIteratorType child_end(NodeType *N) {
141
260k
    return map_iterator(N->end(), CGNDeref);
142
260k
  }
143
};
144
145
template <>
146
struct GraphTraits<PTACallGraph const *>
147
    : public GraphTraits<PTACallGraphNode const *> {
148
5.28k
  static NodeType *getEntryNode(PTACallGraph const *CGN) {
149
5.28k
    return CGN->getExternalCallingNode(); // Start at the external node!
150
5.28k
  }
151
};
152
} // namespace llvm
153
154
#endif /* PTACALLGRAPH_H */