Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:11

0001 //===- CallGraph.h - Build a Module's call graph ----------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 /// \file
0009 ///
0010 /// This file provides interfaces used to build and manipulate a call graph,
0011 /// which is a very useful tool for interprocedural optimization.
0012 ///
0013 /// Every function in a module is represented as a node in the call graph.  The
0014 /// callgraph node keeps track of which functions are called by the function
0015 /// corresponding to the node.
0016 ///
0017 /// A call graph may contain nodes where the function that they correspond to
0018 /// is null.  These 'external' nodes are used to represent control flow that is
0019 /// not represented (or analyzable) in the module.  In particular, this
0020 /// analysis builds one external node such that:
0021 ///   1. All functions in the module without internal linkage will have edges
0022 ///      from this external node, indicating that they could be called by
0023 ///      functions outside of the module.
0024 ///   2. All functions whose address is used for something more than a direct
0025 ///      call, for example being stored into a memory location will also have
0026 ///      an edge from this external node.  Since they may be called by an
0027 ///      unknown caller later, they must be tracked as such.
0028 ///
0029 /// There is a second external node added for calls that leave this module.
0030 /// Functions have a call edge to the external node iff:
0031 ///   1. The function is external, reflecting the fact that they could call
0032 ///      anything without internal linkage or that has its address taken.
0033 ///   2. The function contains an indirect function call.
0034 ///
0035 /// As an extension in the future, there may be multiple nodes with a null
0036 /// function.  These will be used when we can prove (through pointer analysis)
0037 /// that an indirect call site can call only a specific set of functions.
0038 ///
0039 /// Because of these properties, the CallGraph captures a conservative superset
0040 /// of all of the caller-callee relationships, which is useful for
0041 /// transformations.
0042 ///
0043 //===----------------------------------------------------------------------===//
0044 
0045 #ifndef LLVM_ANALYSIS_CALLGRAPH_H
0046 #define LLVM_ANALYSIS_CALLGRAPH_H
0047 
0048 #include "llvm/IR/InstrTypes.h"
0049 #include "llvm/IR/PassManager.h"
0050 #include "llvm/IR/ValueHandle.h"
0051 #include "llvm/Pass.h"
0052 #include <cassert>
0053 #include <map>
0054 #include <memory>
0055 #include <utility>
0056 #include <vector>
0057 
0058 namespace llvm {
0059 
0060 template <class GraphType> struct GraphTraits;
0061 class CallGraphNode;
0062 class Function;
0063 class Module;
0064 class raw_ostream;
0065 
0066 /// The basic data container for the call graph of a \c Module of IR.
0067 ///
0068 /// This class exposes both the interface to the call graph for a module of IR.
0069 ///
0070 /// The core call graph itself can also be updated to reflect changes to the IR.
0071 class CallGraph {
0072   Module &M;
0073 
0074   using FunctionMapTy =
0075       std::map<const Function *, std::unique_ptr<CallGraphNode>>;
0076 
0077   /// A map from \c Function* to \c CallGraphNode*.
0078   FunctionMapTy FunctionMap;
0079 
0080   /// This node has edges to all external functions and those internal
0081   /// functions that have their address taken.
0082   CallGraphNode *ExternalCallingNode;
0083 
0084   /// This node has edges to it from all functions making indirect calls
0085   /// or calling an external function.
0086   std::unique_ptr<CallGraphNode> CallsExternalNode;
0087 
0088 public:
0089   explicit CallGraph(Module &M);
0090   CallGraph(CallGraph &&Arg);
0091   ~CallGraph();
0092 
0093   void print(raw_ostream &OS) const;
0094   void dump() const;
0095 
0096   using iterator = FunctionMapTy::iterator;
0097   using const_iterator = FunctionMapTy::const_iterator;
0098 
0099   /// Returns the module the call graph corresponds to.
0100   Module &getModule() const { return M; }
0101 
0102   bool invalidate(Module &, const PreservedAnalyses &PA,
0103                   ModuleAnalysisManager::Invalidator &);
0104 
0105   inline iterator begin() { return FunctionMap.begin(); }
0106   inline iterator end() { return FunctionMap.end(); }
0107   inline const_iterator begin() const { return FunctionMap.begin(); }
0108   inline const_iterator end() const { return FunctionMap.end(); }
0109 
0110   /// Returns the call graph node for the provided function.
0111   inline const CallGraphNode *operator[](const Function *F) const {
0112     const_iterator I = FunctionMap.find(F);
0113     assert(I != FunctionMap.end() && "Function not in callgraph!");
0114     return I->second.get();
0115   }
0116 
0117   /// Returns the call graph node for the provided function.
0118   inline CallGraphNode *operator[](const Function *F) {
0119     const_iterator I = FunctionMap.find(F);
0120     assert(I != FunctionMap.end() && "Function not in callgraph!");
0121     return I->second.get();
0122   }
0123 
0124   /// Returns the \c CallGraphNode which is used to represent
0125   /// undetermined calls into the callgraph.
0126   CallGraphNode *getExternalCallingNode() const { return ExternalCallingNode; }
0127 
0128   CallGraphNode *getCallsExternalNode() const {
0129     return CallsExternalNode.get();
0130   }
0131 
0132   /// Old node has been deleted, and New is to be used in its place, update the
0133   /// ExternalCallingNode.
0134   void ReplaceExternalCallEdge(CallGraphNode *Old, CallGraphNode *New);
0135 
0136   //===---------------------------------------------------------------------
0137   // Functions to keep a call graph up to date with a function that has been
0138   // modified.
0139   //
0140 
0141   /// Unlink the function from this module, returning it.
0142   ///
0143   /// Because this removes the function from the module, the call graph node is
0144   /// destroyed.  This is only valid if the function does not call any other
0145   /// functions (ie, there are no edges in it's CGN).  The easiest way to do
0146   /// this is to dropAllReferences before calling this.
0147   Function *removeFunctionFromModule(CallGraphNode *CGN);
0148 
0149   /// Similar to operator[], but this will insert a new CallGraphNode for
0150   /// \c F if one does not already exist.
0151   CallGraphNode *getOrInsertFunction(const Function *F);
0152 
0153   /// Populate \p CGN based on the calls inside the associated function.
0154   void populateCallGraphNode(CallGraphNode *CGN);
0155 
0156   /// Add a function to the call graph, and link the node to all of the
0157   /// functions that it calls.
0158   void addToCallGraph(Function *F);
0159 };
0160 
0161 /// A node in the call graph for a module.
0162 ///
0163 /// Typically represents a function in the call graph. There are also special
0164 /// "null" nodes used to represent theoretical entries in the call graph.
0165 class CallGraphNode {
0166 public:
0167   /// A pair of the calling instruction (a call or invoke)
0168   /// and the call graph node being called.
0169   /// Call graph node may have two types of call records which represent an edge
0170   /// in the call graph - reference or a call edge. Reference edges are not
0171   /// associated with any call instruction and are created with the first field
0172   /// set to `None`, while real call edges have instruction address in this
0173   /// field. Therefore, all real call edges are expected to have a value in the
0174   /// first field and it is not supposed to be `nullptr`.
0175   /// Reference edges, for example, are used for connecting broker function
0176   /// caller to the callback function for callback call sites.
0177   using CallRecord = std::pair<std::optional<WeakTrackingVH>, CallGraphNode *>;
0178 
0179 public:
0180   using CalledFunctionsVector = std::vector<CallRecord>;
0181 
0182   /// Creates a node for the specified function.
0183   inline CallGraphNode(CallGraph *CG, Function *F) : CG(CG), F(F) {}
0184 
0185   CallGraphNode(const CallGraphNode &) = delete;
0186   CallGraphNode &operator=(const CallGraphNode &) = delete;
0187 
0188   ~CallGraphNode() {
0189     assert(NumReferences == 0 && "Node deleted while references remain");
0190   }
0191 
0192   using iterator = std::vector<CallRecord>::iterator;
0193   using const_iterator = std::vector<CallRecord>::const_iterator;
0194 
0195   /// Returns the function that this call graph node represents.
0196   Function *getFunction() const { return F; }
0197 
0198   inline iterator begin() { return CalledFunctions.begin(); }
0199   inline iterator end() { return CalledFunctions.end(); }
0200   inline const_iterator begin() const { return CalledFunctions.begin(); }
0201   inline const_iterator end() const { return CalledFunctions.end(); }
0202   inline bool empty() const { return CalledFunctions.empty(); }
0203   inline unsigned size() const { return (unsigned)CalledFunctions.size(); }
0204 
0205   /// Returns the number of other CallGraphNodes in this CallGraph that
0206   /// reference this node in their callee list.
0207   unsigned getNumReferences() const { return NumReferences; }
0208 
0209   /// Returns the i'th called function.
0210   CallGraphNode *operator[](unsigned i) const {
0211     assert(i < CalledFunctions.size() && "Invalid index");
0212     return CalledFunctions[i].second;
0213   }
0214 
0215   /// Print out this call graph node.
0216   void dump() const;
0217   void print(raw_ostream &OS) const;
0218 
0219   //===---------------------------------------------------------------------
0220   // Methods to keep a call graph up to date with a function that has been
0221   // modified
0222   //
0223 
0224   /// Removes all edges from this CallGraphNode to any functions it
0225   /// calls.
0226   void removeAllCalledFunctions() {
0227     while (!CalledFunctions.empty()) {
0228       CalledFunctions.back().second->DropRef();
0229       CalledFunctions.pop_back();
0230     }
0231   }
0232 
0233   /// Moves all the callee information from N to this node.
0234   void stealCalledFunctionsFrom(CallGraphNode *N) {
0235     assert(CalledFunctions.empty() &&
0236            "Cannot steal callsite information if I already have some");
0237     std::swap(CalledFunctions, N->CalledFunctions);
0238   }
0239 
0240   /// Adds a function to the list of functions called by this one.
0241   void addCalledFunction(CallBase *Call, CallGraphNode *M) {
0242     CalledFunctions.emplace_back(Call ? std::optional<WeakTrackingVH>(Call)
0243                                       : std::optional<WeakTrackingVH>(),
0244                                  M);
0245     M->AddRef();
0246   }
0247 
0248   void removeCallEdge(iterator I) {
0249     I->second->DropRef();
0250     *I = CalledFunctions.back();
0251     CalledFunctions.pop_back();
0252   }
0253 
0254   /// Removes the edge in the node for the specified call site.
0255   ///
0256   /// Note that this method takes linear time, so it should be used sparingly.
0257   void removeCallEdgeFor(CallBase &Call);
0258 
0259   /// Removes all call edges from this node to the specified callee
0260   /// function.
0261   ///
0262   /// This takes more time to execute than removeCallEdgeTo, so it should not
0263   /// be used unless necessary.
0264   void removeAnyCallEdgeTo(CallGraphNode *Callee);
0265 
0266   /// Removes one edge associated with a null callsite from this node to
0267   /// the specified callee function.
0268   void removeOneAbstractEdgeTo(CallGraphNode *Callee);
0269 
0270   /// Replaces the edge in the node for the specified call site with a
0271   /// new one.
0272   ///
0273   /// Note that this method takes linear time, so it should be used sparingly.
0274   void replaceCallEdge(CallBase &Call, CallBase &NewCall,
0275                        CallGraphNode *NewNode);
0276 
0277 private:
0278   friend class CallGraph;
0279 
0280   CallGraph *CG;
0281   Function *F;
0282 
0283   std::vector<CallRecord> CalledFunctions;
0284 
0285   /// The number of times that this CallGraphNode occurs in the
0286   /// CalledFunctions array of this or other CallGraphNodes.
0287   unsigned NumReferences = 0;
0288 
0289   void DropRef() { --NumReferences; }
0290   void AddRef() { ++NumReferences; }
0291 
0292   /// A special function that should only be used by the CallGraph class.
0293   void allReferencesDropped() { NumReferences = 0; }
0294 };
0295 
0296 /// An analysis pass to compute the \c CallGraph for a \c Module.
0297 ///
0298 /// This class implements the concept of an analysis pass used by the \c
0299 /// ModuleAnalysisManager to run an analysis over a module and cache the
0300 /// resulting data.
0301 class CallGraphAnalysis : public AnalysisInfoMixin<CallGraphAnalysis> {
0302   friend AnalysisInfoMixin<CallGraphAnalysis>;
0303 
0304   static AnalysisKey Key;
0305 
0306 public:
0307   /// A formulaic type to inform clients of the result type.
0308   using Result = CallGraph;
0309 
0310   /// Compute the \c CallGraph for the module \c M.
0311   ///
0312   /// The real work here is done in the \c CallGraph constructor.
0313   CallGraph run(Module &M, ModuleAnalysisManager &) { return CallGraph(M); }
0314 };
0315 
0316 /// Printer pass for the \c CallGraphAnalysis results.
0317 class CallGraphPrinterPass : public PassInfoMixin<CallGraphPrinterPass> {
0318   raw_ostream &OS;
0319 
0320 public:
0321   explicit CallGraphPrinterPass(raw_ostream &OS) : OS(OS) {}
0322 
0323   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
0324 
0325   static bool isRequired() { return true; }
0326 };
0327 
0328 /// Printer pass for the summarized \c CallGraphAnalysis results.
0329 class CallGraphSCCsPrinterPass
0330     : public PassInfoMixin<CallGraphSCCsPrinterPass> {
0331   raw_ostream &OS;
0332 
0333 public:
0334   explicit CallGraphSCCsPrinterPass(raw_ostream &OS) : OS(OS) {}
0335 
0336   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
0337 
0338   static bool isRequired() { return true; }
0339 };
0340 
0341 /// The \c ModulePass which wraps up a \c CallGraph and the logic to
0342 /// build it.
0343 ///
0344 /// This class exposes both the interface to the call graph container and the
0345 /// module pass which runs over a module of IR and produces the call graph. The
0346 /// call graph interface is entirelly a wrapper around a \c CallGraph object
0347 /// which is stored internally for each module.
0348 class CallGraphWrapperPass : public ModulePass {
0349   std::unique_ptr<CallGraph> G;
0350 
0351 public:
0352   static char ID; // Class identification, replacement for typeinfo
0353 
0354   CallGraphWrapperPass();
0355   ~CallGraphWrapperPass() override;
0356 
0357   /// The internal \c CallGraph around which the rest of this interface
0358   /// is wrapped.
0359   const CallGraph &getCallGraph() const { return *G; }
0360   CallGraph &getCallGraph() { return *G; }
0361 
0362   using iterator = CallGraph::iterator;
0363   using const_iterator = CallGraph::const_iterator;
0364 
0365   /// Returns the module the call graph corresponds to.
0366   Module &getModule() const { return G->getModule(); }
0367 
0368   inline iterator begin() { return G->begin(); }
0369   inline iterator end() { return G->end(); }
0370   inline const_iterator begin() const { return G->begin(); }
0371   inline const_iterator end() const { return G->end(); }
0372 
0373   /// Returns the call graph node for the provided function.
0374   inline const CallGraphNode *operator[](const Function *F) const {
0375     return (*G)[F];
0376   }
0377 
0378   /// Returns the call graph node for the provided function.
0379   inline CallGraphNode *operator[](const Function *F) { return (*G)[F]; }
0380 
0381   /// Returns the \c CallGraphNode which is used to represent
0382   /// undetermined calls into the callgraph.
0383   CallGraphNode *getExternalCallingNode() const {
0384     return G->getExternalCallingNode();
0385   }
0386 
0387   CallGraphNode *getCallsExternalNode() const {
0388     return G->getCallsExternalNode();
0389   }
0390 
0391   //===---------------------------------------------------------------------
0392   // Functions to keep a call graph up to date with a function that has been
0393   // modified.
0394   //
0395 
0396   /// Unlink the function from this module, returning it.
0397   ///
0398   /// Because this removes the function from the module, the call graph node is
0399   /// destroyed.  This is only valid if the function does not call any other
0400   /// functions (ie, there are no edges in it's CGN).  The easiest way to do
0401   /// this is to dropAllReferences before calling this.
0402   Function *removeFunctionFromModule(CallGraphNode *CGN) {
0403     return G->removeFunctionFromModule(CGN);
0404   }
0405 
0406   /// Similar to operator[], but this will insert a new CallGraphNode for
0407   /// \c F if one does not already exist.
0408   CallGraphNode *getOrInsertFunction(const Function *F) {
0409     return G->getOrInsertFunction(F);
0410   }
0411 
0412   //===---------------------------------------------------------------------
0413   // Implementation of the ModulePass interface needed here.
0414   //
0415 
0416   void getAnalysisUsage(AnalysisUsage &AU) const override;
0417   bool runOnModule(Module &M) override;
0418   void releaseMemory() override;
0419 
0420   void print(raw_ostream &o, const Module *) const override;
0421   void dump() const;
0422 };
0423 
0424 //===----------------------------------------------------------------------===//
0425 // GraphTraits specializations for call graphs so that they can be treated as
0426 // graphs by the generic graph algorithms.
0427 //
0428 
0429 // Provide graph traits for traversing call graphs using standard graph
0430 // traversals.
0431 template <> struct GraphTraits<CallGraphNode *> {
0432   using NodeRef = CallGraphNode *;
0433   using CGNPairTy = CallGraphNode::CallRecord;
0434 
0435   static NodeRef getEntryNode(CallGraphNode *CGN) { return CGN; }
0436   static CallGraphNode *CGNGetValue(CGNPairTy P) { return P.second; }
0437 
0438   using ChildIteratorType =
0439       mapped_iterator<CallGraphNode::iterator, decltype(&CGNGetValue)>;
0440 
0441   static ChildIteratorType child_begin(NodeRef N) {
0442     return ChildIteratorType(N->begin(), &CGNGetValue);
0443   }
0444 
0445   static ChildIteratorType child_end(NodeRef N) {
0446     return ChildIteratorType(N->end(), &CGNGetValue);
0447   }
0448 };
0449 
0450 template <> struct GraphTraits<const CallGraphNode *> {
0451   using NodeRef = const CallGraphNode *;
0452   using CGNPairTy = CallGraphNode::CallRecord;
0453   using EdgeRef = const CallGraphNode::CallRecord &;
0454 
0455   static NodeRef getEntryNode(const CallGraphNode *CGN) { return CGN; }
0456   static const CallGraphNode *CGNGetValue(CGNPairTy P) { return P.second; }
0457 
0458   using ChildIteratorType =
0459       mapped_iterator<CallGraphNode::const_iterator, decltype(&CGNGetValue)>;
0460   using ChildEdgeIteratorType = CallGraphNode::const_iterator;
0461 
0462   static ChildIteratorType child_begin(NodeRef N) {
0463     return ChildIteratorType(N->begin(), &CGNGetValue);
0464   }
0465 
0466   static ChildIteratorType child_end(NodeRef N) {
0467     return ChildIteratorType(N->end(), &CGNGetValue);
0468   }
0469 
0470   static ChildEdgeIteratorType child_edge_begin(NodeRef N) {
0471     return N->begin();
0472   }
0473   static ChildEdgeIteratorType child_edge_end(NodeRef N) { return N->end(); }
0474 
0475   static NodeRef edge_dest(EdgeRef E) { return E.second; }
0476 };
0477 
0478 template <>
0479 struct GraphTraits<CallGraph *> : public GraphTraits<CallGraphNode *> {
0480   using PairTy =
0481       std::pair<const Function *const, std::unique_ptr<CallGraphNode>>;
0482 
0483   static NodeRef getEntryNode(CallGraph *CGN) {
0484     return CGN->getExternalCallingNode(); // Start at the external node!
0485   }
0486 
0487   static CallGraphNode *CGGetValuePtr(const PairTy &P) {
0488     return P.second.get();
0489   }
0490 
0491   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
0492   using nodes_iterator =
0493       mapped_iterator<CallGraph::iterator, decltype(&CGGetValuePtr)>;
0494 
0495   static nodes_iterator nodes_begin(CallGraph *CG) {
0496     return nodes_iterator(CG->begin(), &CGGetValuePtr);
0497   }
0498 
0499   static nodes_iterator nodes_end(CallGraph *CG) {
0500     return nodes_iterator(CG->end(), &CGGetValuePtr);
0501   }
0502 };
0503 
0504 template <>
0505 struct GraphTraits<const CallGraph *> : public GraphTraits<
0506                                             const CallGraphNode *> {
0507   using PairTy =
0508       std::pair<const Function *const, std::unique_ptr<CallGraphNode>>;
0509 
0510   static NodeRef getEntryNode(const CallGraph *CGN) {
0511     return CGN->getExternalCallingNode(); // Start at the external node!
0512   }
0513 
0514   static const CallGraphNode *CGGetValuePtr(const PairTy &P) {
0515     return P.second.get();
0516   }
0517 
0518   // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
0519   using nodes_iterator =
0520       mapped_iterator<CallGraph::const_iterator, decltype(&CGGetValuePtr)>;
0521 
0522   static nodes_iterator nodes_begin(const CallGraph *CG) {
0523     return nodes_iterator(CG->begin(), &CGGetValuePtr);
0524   }
0525 
0526   static nodes_iterator nodes_end(const CallGraph *CG) {
0527     return nodes_iterator(CG->end(), &CGGetValuePtr);
0528   }
0529 };
0530 
0531 } // end namespace llvm
0532 
0533 #endif // LLVM_ANALYSIS_CALLGRAPH_H