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