xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Analysis/CallGraphSCCPass.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the CallGraphSCCPass class, which is used for passes which
10 // are implemented as bottom-up traversals on the call graph.  Because there may
11 // be cycles in the call graph, passes of this type operate on the call-graph in
12 // SCC order: that is, they process function bottom-up, except for recursive
13 // functions, which they process all at once.
14 //
15 // These passes are inherently interprocedural, and are required to keep the
16 // call graph up-to-date if they do anything which could modify it.
17 //
18 //===----------------------------------------------------------------------===//
19 
20 #ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
21 #define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
22 
23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/Pass.h"
25 #include "llvm/Support/Compiler.h"
26 #include <vector>
27 
28 namespace llvm {
29 
30 class CallGraph;
31 class CallGraphNode;
32 class CallGraphSCC;
33 class PMStack;
34 
35 class LLVM_ABI CallGraphSCCPass : public Pass {
36 public:
CallGraphSCCPass(char & pid)37   explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {}
38 
39   /// createPrinterPass - Get a pass that prints the Module
40   /// corresponding to a CallGraph.
41   Pass *createPrinterPass(raw_ostream &OS,
42                           const std::string &Banner) const override;
43 
44   using llvm::Pass::doInitialization;
45   using llvm::Pass::doFinalization;
46 
47   /// doInitialization - This method is called before the SCC's of the program
48   /// has been processed, allowing the pass to do initialization as necessary.
doInitialization(CallGraph & CG)49   virtual bool doInitialization(CallGraph &CG) {
50     return false;
51   }
52 
53   /// runOnSCC - This method should be implemented by the subclass to perform
54   /// whatever action is necessary for the specified SCC.  Note that
55   /// non-recursive (or only self-recursive) functions will have an SCC size of
56   /// 1, where recursive portions of the call graph will have SCC size > 1.
57   ///
58   /// SCC passes that add or delete functions to the SCC are required to update
59   /// the SCC list, otherwise stale pointers may be dereferenced.
60   virtual bool runOnSCC(CallGraphSCC &SCC) = 0;
61 
62   /// doFinalization - This method is called after the SCC's of the program has
63   /// been processed, allowing the pass to do final cleanup as necessary.
doFinalization(CallGraph & CG)64   virtual bool doFinalization(CallGraph &CG) {
65     return false;
66   }
67 
68   /// Assign pass manager to manager this pass
69   void assignPassManager(PMStack &PMS, PassManagerType PMT) override;
70 
71   ///  Return what kind of Pass Manager can manage this pass.
getPotentialPassManagerType()72   PassManagerType getPotentialPassManagerType() const override {
73     return PMT_CallGraphPassManager;
74   }
75 
76   /// getAnalysisUsage - For this class, we declare that we require and preserve
77   /// the call graph.  If the derived class implements this method, it should
78   /// always explicitly call the implementation here.
79   void getAnalysisUsage(AnalysisUsage &Info) const override;
80 };
81 
82 /// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
83 class CallGraphSCC {
84   const CallGraph &CG; // The call graph for this SCC.
85   void *Context; // The CGPassManager object that is vending this.
86   std::vector<CallGraphNode *> Nodes;
87 
88 public:
CallGraphSCC(CallGraph & cg,void * context)89   CallGraphSCC(CallGraph &cg, void *context) : CG(cg), Context(context) {}
90 
initialize(ArrayRef<CallGraphNode * > NewNodes)91   void initialize(ArrayRef<CallGraphNode *> NewNodes) {
92     Nodes.assign(NewNodes.begin(), NewNodes.end());
93   }
94 
isSingular()95   bool isSingular() const { return Nodes.size() == 1; }
size()96   unsigned size() const { return Nodes.size(); }
97 
98   /// ReplaceNode - This informs the SCC and the pass manager that the specified
99   /// Old node has been deleted, and New is to be used in its place.
100   LLVM_ABI void ReplaceNode(CallGraphNode *Old, CallGraphNode *New);
101 
102   /// DeleteNode - This informs the SCC and the pass manager that the specified
103   /// Old node has been deleted.
104   LLVM_ABI void DeleteNode(CallGraphNode *Old);
105 
106   using iterator = std::vector<CallGraphNode *>::const_iterator;
107 
begin()108   iterator begin() const { return Nodes.begin(); }
end()109   iterator end() const { return Nodes.end(); }
110 
getCallGraph()111   const CallGraph &getCallGraph() { return CG; }
112 };
113 
114 LLVM_ABI void initializeDummyCGSCCPassPass(PassRegistry &);
115 
116 /// This pass is required by interprocedural register allocation. It forces
117 /// codegen to follow bottom up order on call graph.
118 class DummyCGSCCPass : public CallGraphSCCPass {
119 public:
120   LLVM_ABI static char ID;
121 
DummyCGSCCPass()122   DummyCGSCCPass() : CallGraphSCCPass(ID) {
123     PassRegistry &Registry = *PassRegistry::getPassRegistry();
124     initializeDummyCGSCCPassPass(Registry);
125   }
126 
runOnSCC(CallGraphSCC & SCC)127   bool runOnSCC(CallGraphSCC &SCC) override { return false; }
128 
getAnalysisUsage(AnalysisUsage & AU)129   void getAnalysisUsage(AnalysisUsage &AU) const override {
130     AU.setPreservesAll();
131   }
132 };
133 
134 } // end namespace llvm
135 
136 #endif // LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
137