Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- CallGraphSCCPass.h - Pass that operates BU on 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 //
0009 // This file defines the CallGraphSCCPass class, which is used for passes which
0010 // are implemented as bottom-up traversals on the call graph.  Because there may
0011 // be cycles in the call graph, passes of this type operate on the call-graph in
0012 // SCC order: that is, they process function bottom-up, except for recursive
0013 // functions, which they process all at once.
0014 //
0015 // These passes are inherently interprocedural, and are required to keep the
0016 // call graph up-to-date if they do anything which could modify it.
0017 //
0018 //===----------------------------------------------------------------------===//
0019 
0020 #ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
0021 #define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
0022 
0023 #include "llvm/ADT/ArrayRef.h"
0024 #include "llvm/Pass.h"
0025 #include <vector>
0026 
0027 namespace llvm {
0028 
0029 class CallGraph;
0030 class CallGraphNode;
0031 class CallGraphSCC;
0032 class PMStack;
0033 
0034 class CallGraphSCCPass : public Pass {
0035 public:
0036   explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {}
0037 
0038   /// createPrinterPass - Get a pass that prints the Module
0039   /// corresponding to a CallGraph.
0040   Pass *createPrinterPass(raw_ostream &OS,
0041                           const std::string &Banner) const override;
0042 
0043   using llvm::Pass::doInitialization;
0044   using llvm::Pass::doFinalization;
0045 
0046   /// doInitialization - This method is called before the SCC's of the program
0047   /// has been processed, allowing the pass to do initialization as necessary.
0048   virtual bool doInitialization(CallGraph &CG) {
0049     return false;
0050   }
0051 
0052   /// runOnSCC - This method should be implemented by the subclass to perform
0053   /// whatever action is necessary for the specified SCC.  Note that
0054   /// non-recursive (or only self-recursive) functions will have an SCC size of
0055   /// 1, where recursive portions of the call graph will have SCC size > 1.
0056   ///
0057   /// SCC passes that add or delete functions to the SCC are required to update
0058   /// the SCC list, otherwise stale pointers may be dereferenced.
0059   virtual bool runOnSCC(CallGraphSCC &SCC) = 0;
0060 
0061   /// doFinalization - This method is called after the SCC's of the program has
0062   /// been processed, allowing the pass to do final cleanup as necessary.
0063   virtual bool doFinalization(CallGraph &CG) {
0064     return false;
0065   }
0066 
0067   /// Assign pass manager to manager this pass
0068   void assignPassManager(PMStack &PMS, PassManagerType PMT) override;
0069 
0070   ///  Return what kind of Pass Manager can manage this pass.
0071   PassManagerType getPotentialPassManagerType() const override {
0072     return PMT_CallGraphPassManager;
0073   }
0074 
0075   /// getAnalysisUsage - For this class, we declare that we require and preserve
0076   /// the call graph.  If the derived class implements this method, it should
0077   /// always explicitly call the implementation here.
0078   void getAnalysisUsage(AnalysisUsage &Info) const override;
0079 
0080 protected:
0081   /// Optional passes call this function to check whether the pass should be
0082   /// skipped. This is the case when optimization bisect is over the limit.
0083   bool skipSCC(CallGraphSCC &SCC) const;
0084 };
0085 
0086 /// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
0087 class CallGraphSCC {
0088   const CallGraph &CG; // The call graph for this SCC.
0089   void *Context; // The CGPassManager object that is vending this.
0090   std::vector<CallGraphNode *> Nodes;
0091 
0092 public:
0093   CallGraphSCC(CallGraph &cg, void *context) : CG(cg), Context(context) {}
0094 
0095   void initialize(ArrayRef<CallGraphNode *> NewNodes) {
0096     Nodes.assign(NewNodes.begin(), NewNodes.end());
0097   }
0098 
0099   bool isSingular() const { return Nodes.size() == 1; }
0100   unsigned size() const { return Nodes.size(); }
0101 
0102   /// ReplaceNode - This informs the SCC and the pass manager that the specified
0103   /// Old node has been deleted, and New is to be used in its place.
0104   void ReplaceNode(CallGraphNode *Old, CallGraphNode *New);
0105 
0106   /// DeleteNode - This informs the SCC and the pass manager that the specified
0107   /// Old node has been deleted.
0108   void DeleteNode(CallGraphNode *Old);
0109 
0110   using iterator = std::vector<CallGraphNode *>::const_iterator;
0111 
0112   iterator begin() const { return Nodes.begin(); }
0113   iterator end() const { return Nodes.end(); }
0114 
0115   const CallGraph &getCallGraph() { return CG; }
0116 };
0117 
0118 void initializeDummyCGSCCPassPass(PassRegistry &);
0119 
0120 /// This pass is required by interprocedural register allocation. It forces
0121 /// codegen to follow bottom up order on call graph.
0122 class DummyCGSCCPass : public CallGraphSCCPass {
0123 public:
0124   static char ID;
0125 
0126   DummyCGSCCPass() : CallGraphSCCPass(ID) {
0127     PassRegistry &Registry = *PassRegistry::getPassRegistry();
0128     initializeDummyCGSCCPassPass(Registry);
0129   }
0130 
0131   bool runOnSCC(CallGraphSCC &SCC) override { return false; }
0132 
0133   void getAnalysisUsage(AnalysisUsage &AU) const override {
0134     AU.setPreservesAll();
0135   }
0136 };
0137 
0138 } // end namespace llvm
0139 
0140 #endif // LLVM_ANALYSIS_CALLGRAPHSCCPASS_H