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