10b57cec5SDimitry Andric //===- LegacyPassManagers.h - Legacy Pass Infrastructure --------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares the LLVM Pass Manager infrastructure. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_IR_LEGACYPASSMANAGERS_H 140b57cec5SDimitry Andric #define LLVM_IR_LEGACYPASSMANAGERS_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 170b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h" 180b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 190b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 200b57cec5SDimitry Andric #include "llvm/Pass.h" 210b57cec5SDimitry Andric #include <vector> 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 240b57cec5SDimitry Andric // Overview: 250b57cec5SDimitry Andric // The Pass Manager Infrastructure manages passes. It's responsibilities are: 260b57cec5SDimitry Andric // 270b57cec5SDimitry Andric // o Manage optimization pass execution order 280b57cec5SDimitry Andric // o Make required Analysis information available before pass P is run 290b57cec5SDimitry Andric // o Release memory occupied by dead passes 300b57cec5SDimitry Andric // o If Analysis information is dirtied by a pass then regenerate Analysis 310b57cec5SDimitry Andric // information before it is consumed by another pass. 320b57cec5SDimitry Andric // 330b57cec5SDimitry Andric // Pass Manager Infrastructure uses multiple pass managers. They are 340b57cec5SDimitry Andric // PassManager, FunctionPassManager, MPPassManager, FPPassManager, BBPassManager. 350b57cec5SDimitry Andric // This class hierarchy uses multiple inheritance but pass managers do not 360b57cec5SDimitry Andric // derive from another pass manager. 370b57cec5SDimitry Andric // 380b57cec5SDimitry Andric // PassManager and FunctionPassManager are two top-level pass manager that 390b57cec5SDimitry Andric // represents the external interface of this entire pass manager infrastucture. 400b57cec5SDimitry Andric // 410b57cec5SDimitry Andric // Important classes : 420b57cec5SDimitry Andric // 430b57cec5SDimitry Andric // [o] class PMTopLevelManager; 440b57cec5SDimitry Andric // 450b57cec5SDimitry Andric // Two top level managers, PassManager and FunctionPassManager, derive from 460b57cec5SDimitry Andric // PMTopLevelManager. PMTopLevelManager manages information used by top level 470b57cec5SDimitry Andric // managers such as last user info. 480b57cec5SDimitry Andric // 490b57cec5SDimitry Andric // [o] class PMDataManager; 500b57cec5SDimitry Andric // 510b57cec5SDimitry Andric // PMDataManager manages information, e.g. list of available analysis info, 520b57cec5SDimitry Andric // used by a pass manager to manage execution order of passes. It also provides 530b57cec5SDimitry Andric // a place to implement common pass manager APIs. All pass managers derive from 540b57cec5SDimitry Andric // PMDataManager. 550b57cec5SDimitry Andric // 560b57cec5SDimitry Andric // [o] class FunctionPassManager; 570b57cec5SDimitry Andric // 580b57cec5SDimitry Andric // This is a external interface used to manage FunctionPasses. This 590b57cec5SDimitry Andric // interface relies on FunctionPassManagerImpl to do all the tasks. 600b57cec5SDimitry Andric // 610b57cec5SDimitry Andric // [o] class FunctionPassManagerImpl : public ModulePass, PMDataManager, 620b57cec5SDimitry Andric // public PMTopLevelManager; 630b57cec5SDimitry Andric // 640b57cec5SDimitry Andric // FunctionPassManagerImpl is a top level manager. It manages FPPassManagers 650b57cec5SDimitry Andric // 660b57cec5SDimitry Andric // [o] class FPPassManager : public ModulePass, public PMDataManager; 670b57cec5SDimitry Andric // 680b57cec5SDimitry Andric // FPPassManager manages FunctionPasses and BBPassManagers 690b57cec5SDimitry Andric // 700b57cec5SDimitry Andric // [o] class MPPassManager : public Pass, public PMDataManager; 710b57cec5SDimitry Andric // 720b57cec5SDimitry Andric // MPPassManager manages ModulePasses and FPPassManagers 730b57cec5SDimitry Andric // 740b57cec5SDimitry Andric // [o] class PassManager; 750b57cec5SDimitry Andric // 760b57cec5SDimitry Andric // This is a external interface used by various tools to manages passes. It 770b57cec5SDimitry Andric // relies on PassManagerImpl to do all the tasks. 780b57cec5SDimitry Andric // 790b57cec5SDimitry Andric // [o] class PassManagerImpl : public Pass, public PMDataManager, 800b57cec5SDimitry Andric // public PMTopLevelManager 810b57cec5SDimitry Andric // 820b57cec5SDimitry Andric // PassManagerImpl is a top level pass manager responsible for managing 830b57cec5SDimitry Andric // MPPassManagers. 840b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric #include "llvm/Support/PrettyStackTrace.h" 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric namespace llvm { 890b57cec5SDimitry Andric template <typename T> class ArrayRef; 900b57cec5SDimitry Andric class Module; 910b57cec5SDimitry Andric class StringRef; 920b57cec5SDimitry Andric class Value; 930b57cec5SDimitry Andric class PMDataManager; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric // enums for debugging strings 960b57cec5SDimitry Andric enum PassDebuggingString { 970b57cec5SDimitry Andric EXECUTION_MSG, // "Executing Pass '" + PassName 980b57cec5SDimitry Andric MODIFICATION_MSG, // "Made Modification '" + PassName 990b57cec5SDimitry Andric FREEING_MSG, // " Freeing Pass '" + PassName 1000b57cec5SDimitry Andric ON_FUNCTION_MSG, // "' on Function '" + FunctionName + "'...\n" 1010b57cec5SDimitry Andric ON_MODULE_MSG, // "' on Module '" + ModuleName + "'...\n" 1020b57cec5SDimitry Andric ON_REGION_MSG, // "' on Region '" + Msg + "'...\n'" 1030b57cec5SDimitry Andric ON_LOOP_MSG, // "' on Loop '" + Msg + "'...\n'" 1040b57cec5SDimitry Andric ON_CG_MSG // "' on Call Graph Nodes '" + Msg + "'...\n'" 1050b57cec5SDimitry Andric }; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric /// PassManagerPrettyStackEntry - This is used to print informative information 1080b57cec5SDimitry Andric /// about what pass is running when/if a stack trace is generated. 1090b57cec5SDimitry Andric class PassManagerPrettyStackEntry : public PrettyStackTraceEntry { 1100b57cec5SDimitry Andric Pass *P; 1110b57cec5SDimitry Andric Value *V; 1120b57cec5SDimitry Andric Module *M; 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric public: 1150b57cec5SDimitry Andric explicit PassManagerPrettyStackEntry(Pass *p) 1160b57cec5SDimitry Andric : P(p), V(nullptr), M(nullptr) {} // When P is releaseMemory'd. 1170b57cec5SDimitry Andric PassManagerPrettyStackEntry(Pass *p, Value &v) 1180b57cec5SDimitry Andric : P(p), V(&v), M(nullptr) {} // When P is run on V 1190b57cec5SDimitry Andric PassManagerPrettyStackEntry(Pass *p, Module &m) 1200b57cec5SDimitry Andric : P(p), V(nullptr), M(&m) {} // When P is run on M 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric /// print - Emit information about this stack frame to OS. 1230b57cec5SDimitry Andric void print(raw_ostream &OS) const override; 1240b57cec5SDimitry Andric }; 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1270b57cec5SDimitry Andric // PMStack 1280b57cec5SDimitry Andric // 1290b57cec5SDimitry Andric /// PMStack - This class implements a stack data structure of PMDataManager 1300b57cec5SDimitry Andric /// pointers. 1310b57cec5SDimitry Andric /// 1320b57cec5SDimitry Andric /// Top level pass managers (see PassManager.cpp) maintain active Pass Managers 1330b57cec5SDimitry Andric /// using PMStack. Each Pass implements assignPassManager() to connect itself 1340b57cec5SDimitry Andric /// with appropriate manager. assignPassManager() walks PMStack to find 1350b57cec5SDimitry Andric /// suitable manager. 1360b57cec5SDimitry Andric class PMStack { 1370b57cec5SDimitry Andric public: 1380b57cec5SDimitry Andric typedef std::vector<PMDataManager *>::const_reverse_iterator iterator; 1390b57cec5SDimitry Andric iterator begin() const { return S.rbegin(); } 1400b57cec5SDimitry Andric iterator end() const { return S.rend(); } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric void pop(); 1430b57cec5SDimitry Andric PMDataManager *top() const { return S.back(); } 1440b57cec5SDimitry Andric void push(PMDataManager *PM); 1450b57cec5SDimitry Andric bool empty() const { return S.empty(); } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric void dump() const; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric private: 1500b57cec5SDimitry Andric std::vector<PMDataManager *> S; 1510b57cec5SDimitry Andric }; 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1540b57cec5SDimitry Andric // PMTopLevelManager 1550b57cec5SDimitry Andric // 1560b57cec5SDimitry Andric /// PMTopLevelManager manages LastUser info and collects common APIs used by 1570b57cec5SDimitry Andric /// top level pass managers. 1580b57cec5SDimitry Andric class PMTopLevelManager { 1590b57cec5SDimitry Andric protected: 1600b57cec5SDimitry Andric explicit PMTopLevelManager(PMDataManager *PMDM); 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric unsigned getNumContainedManagers() const { 1630b57cec5SDimitry Andric return (unsigned)PassManagers.size(); 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric void initializeAllAnalysisInfo(); 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric private: 1690b57cec5SDimitry Andric virtual PMDataManager *getAsPMDataManager() = 0; 1700b57cec5SDimitry Andric virtual PassManagerType getTopLevelPassManagerType() = 0; 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric public: 1730b57cec5SDimitry Andric /// Schedule pass P for execution. Make sure that passes required by 1740b57cec5SDimitry Andric /// P are run before P is run. Update analysis info maintained by 1750b57cec5SDimitry Andric /// the manager. Remove dead passes. This is a recursive function. 1760b57cec5SDimitry Andric void schedulePass(Pass *P); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric /// Set pass P as the last user of the given analysis passes. 1790b57cec5SDimitry Andric void setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P); 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric /// Collect passes whose last user is P 1820b57cec5SDimitry Andric void collectLastUses(SmallVectorImpl<Pass *> &LastUses, Pass *P); 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric /// Find the pass that implements Analysis AID. Search immutable 1850b57cec5SDimitry Andric /// passes and all pass managers. If desired pass is not found 1860b57cec5SDimitry Andric /// then return NULL. 1870b57cec5SDimitry Andric Pass *findAnalysisPass(AnalysisID AID); 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric /// Retrieve the PassInfo for an analysis. 1900b57cec5SDimitry Andric const PassInfo *findAnalysisPassInfo(AnalysisID AID) const; 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric /// Find analysis usage information for the pass P. 1930b57cec5SDimitry Andric AnalysisUsage *findAnalysisUsage(Pass *P); 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric virtual ~PMTopLevelManager(); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric /// Add immutable pass and initialize it. 1980b57cec5SDimitry Andric void addImmutablePass(ImmutablePass *P); 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric inline SmallVectorImpl<ImmutablePass *>& getImmutablePasses() { 2010b57cec5SDimitry Andric return ImmutablePasses; 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric void addPassManager(PMDataManager *Manager) { 2050b57cec5SDimitry Andric PassManagers.push_back(Manager); 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric // Add Manager into the list of managers that are not directly 2090b57cec5SDimitry Andric // maintained by this top level pass manager 2100b57cec5SDimitry Andric inline void addIndirectPassManager(PMDataManager *Manager) { 2110b57cec5SDimitry Andric IndirectPassManagers.push_back(Manager); 2120b57cec5SDimitry Andric } 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric // Print passes managed by this top level manager. 2150b57cec5SDimitry Andric void dumpPasses() const; 2160b57cec5SDimitry Andric void dumpArguments() const; 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric // Active Pass Managers 2190b57cec5SDimitry Andric PMStack activeStack; 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric protected: 2220b57cec5SDimitry Andric /// Collection of pass managers 2230b57cec5SDimitry Andric SmallVector<PMDataManager *, 8> PassManagers; 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric private: 2260b57cec5SDimitry Andric /// Collection of pass managers that are not directly maintained 2270b57cec5SDimitry Andric /// by this pass manager 2280b57cec5SDimitry Andric SmallVector<PMDataManager *, 8> IndirectPassManagers; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric // Map to keep track of last user of the analysis pass. 2310b57cec5SDimitry Andric // LastUser->second is the last user of Lastuser->first. 232e8d8bef9SDimitry Andric // This is kept in sync with InversedLastUser. 2330b57cec5SDimitry Andric DenseMap<Pass *, Pass *> LastUser; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric // Map to keep track of passes that are last used by a pass. 236e8d8bef9SDimitry Andric // This is kept in sync with LastUser. 2370b57cec5SDimitry Andric DenseMap<Pass *, SmallPtrSet<Pass *, 8> > InversedLastUser; 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric /// Immutable passes are managed by top level manager. 2400b57cec5SDimitry Andric SmallVector<ImmutablePass *, 16> ImmutablePasses; 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric /// Map from ID to immutable passes. 2430b57cec5SDimitry Andric SmallDenseMap<AnalysisID, ImmutablePass *, 8> ImmutablePassMap; 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric /// A wrapper around AnalysisUsage for the purpose of uniqueing. The wrapper 2470b57cec5SDimitry Andric /// is used to avoid needing to make AnalysisUsage itself a folding set node. 2480b57cec5SDimitry Andric struct AUFoldingSetNode : public FoldingSetNode { 2490b57cec5SDimitry Andric AnalysisUsage AU; 2500b57cec5SDimitry Andric AUFoldingSetNode(const AnalysisUsage &AU) : AU(AU) {} 2510b57cec5SDimitry Andric void Profile(FoldingSetNodeID &ID) const { 2520b57cec5SDimitry Andric Profile(ID, AU); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric static void Profile(FoldingSetNodeID &ID, const AnalysisUsage &AU) { 2550b57cec5SDimitry Andric // TODO: We could consider sorting the dependency arrays within the 2560b57cec5SDimitry Andric // AnalysisUsage (since they are conceptually unordered). 2570b57cec5SDimitry Andric ID.AddBoolean(AU.getPreservesAll()); 2580b57cec5SDimitry Andric auto ProfileVec = [&](const SmallVectorImpl<AnalysisID>& Vec) { 2590b57cec5SDimitry Andric ID.AddInteger(Vec.size()); 2600b57cec5SDimitry Andric for(AnalysisID AID : Vec) 2610b57cec5SDimitry Andric ID.AddPointer(AID); 2620b57cec5SDimitry Andric }; 2630b57cec5SDimitry Andric ProfileVec(AU.getRequiredSet()); 2640b57cec5SDimitry Andric ProfileVec(AU.getRequiredTransitiveSet()); 2650b57cec5SDimitry Andric ProfileVec(AU.getPreservedSet()); 2660b57cec5SDimitry Andric ProfileVec(AU.getUsedSet()); 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric }; 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric // Contains all of the unique combinations of AnalysisUsage. This is helpful 2710b57cec5SDimitry Andric // when we have multiple instances of the same pass since they'll usually 2720b57cec5SDimitry Andric // have the same analysis usage and can share storage. 2730b57cec5SDimitry Andric FoldingSet<AUFoldingSetNode> UniqueAnalysisUsages; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric // Allocator used for allocating UAFoldingSetNodes. This handles deletion of 2760b57cec5SDimitry Andric // all allocated nodes in one fell swoop. 2770b57cec5SDimitry Andric SpecificBumpPtrAllocator<AUFoldingSetNode> AUFoldingSetNodeAllocator; 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric // Maps from a pass to it's associated entry in UniqueAnalysisUsages. Does 2800b57cec5SDimitry Andric // not own the storage associated with either key or value.. 2810b57cec5SDimitry Andric DenseMap<Pass *, AnalysisUsage*> AnUsageMap; 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric /// Collection of PassInfo objects found via analysis IDs and in this top 2840b57cec5SDimitry Andric /// level manager. This is used to memoize queries to the pass registry. 2850b57cec5SDimitry Andric /// FIXME: This is an egregious hack because querying the pass registry is 2860b57cec5SDimitry Andric /// either slow or racy. 2870b57cec5SDimitry Andric mutable DenseMap<AnalysisID, const PassInfo *> AnalysisPassInfos; 2880b57cec5SDimitry Andric }; 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2910b57cec5SDimitry Andric // PMDataManager 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric /// PMDataManager provides the common place to manage the analysis data 2940b57cec5SDimitry Andric /// used by pass managers. 2950b57cec5SDimitry Andric class PMDataManager { 2960b57cec5SDimitry Andric public: 29781ad6265SDimitry Andric explicit PMDataManager() { initializeAnalysisInfo(); } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric virtual ~PMDataManager(); 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric virtual Pass *getAsPass() = 0; 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric /// Augment AvailableAnalysis by adding analysis made available by pass P. 3040b57cec5SDimitry Andric void recordAvailableAnalysis(Pass *P); 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric /// verifyPreservedAnalysis -- Verify analysis presreved by pass P. 3070b57cec5SDimitry Andric void verifyPreservedAnalysis(Pass *P); 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric /// Remove Analysis that is not preserved by the pass 3100b57cec5SDimitry Andric void removeNotPreservedAnalysis(Pass *P); 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric /// Remove dead passes used by P. 3130b57cec5SDimitry Andric void removeDeadPasses(Pass *P, StringRef Msg, 3140b57cec5SDimitry Andric enum PassDebuggingString); 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric /// Remove P. 3170b57cec5SDimitry Andric void freePass(Pass *P, StringRef Msg, 3180b57cec5SDimitry Andric enum PassDebuggingString); 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric /// Add pass P into the PassVector. Update 3210b57cec5SDimitry Andric /// AvailableAnalysis appropriately if ProcessAnalysis is true. 3220b57cec5SDimitry Andric void add(Pass *P, bool ProcessAnalysis = true); 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric /// Add RequiredPass into list of lower level passes required by pass P. 3250b57cec5SDimitry Andric /// RequiredPass is run on the fly by Pass Manager when P requests it 3260b57cec5SDimitry Andric /// through getAnalysis interface. 3270b57cec5SDimitry Andric virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass); 3280b57cec5SDimitry Andric 3295ffd83dbSDimitry Andric virtual std::tuple<Pass *, bool> getOnTheFlyPass(Pass *P, AnalysisID PI, 3305ffd83dbSDimitry Andric Function &F); 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric /// Initialize available analysis information. 3330b57cec5SDimitry Andric void initializeAnalysisInfo() { 3340b57cec5SDimitry Andric AvailableAnalysis.clear(); 335fe6060f1SDimitry Andric for (auto &IA : InheritedAnalysis) 336fe6060f1SDimitry Andric IA = nullptr; 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric // Return true if P preserves high level analysis used by other 3400b57cec5SDimitry Andric // passes that are managed by this manager. 3410b57cec5SDimitry Andric bool preserveHigherLevelAnalysis(Pass *P); 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric /// Populate UsedPasses with analysis pass that are used or required by pass 3440b57cec5SDimitry Andric /// P and are available. Populate ReqPassNotAvailable with analysis pass that 3450b57cec5SDimitry Andric /// are required by pass P but are not available. 3460b57cec5SDimitry Andric void collectRequiredAndUsedAnalyses( 3470b57cec5SDimitry Andric SmallVectorImpl<Pass *> &UsedPasses, 3480b57cec5SDimitry Andric SmallVectorImpl<AnalysisID> &ReqPassNotAvailable, Pass *P); 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric /// All Required analyses should be available to the pass as it runs! Here 3510b57cec5SDimitry Andric /// we fill in the AnalysisImpls member of the pass so that it can 3520b57cec5SDimitry Andric /// successfully use the getAnalysis() method to retrieve the 3530b57cec5SDimitry Andric /// implementations it needs. 3540b57cec5SDimitry Andric void initializeAnalysisImpl(Pass *P); 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric /// Find the pass that implements Analysis AID. If desired pass is not found 3570b57cec5SDimitry Andric /// then return NULL. 3580b57cec5SDimitry Andric Pass *findAnalysisPass(AnalysisID AID, bool Direction); 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric // Access toplevel manager 3610b57cec5SDimitry Andric PMTopLevelManager *getTopLevelManager() { return TPM; } 3620b57cec5SDimitry Andric void setTopLevelManager(PMTopLevelManager *T) { TPM = T; } 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric unsigned getDepth() const { return Depth; } 3650b57cec5SDimitry Andric void setDepth(unsigned newDepth) { Depth = newDepth; } 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric // Print routines used by debug-pass 3680b57cec5SDimitry Andric void dumpLastUses(Pass *P, unsigned Offset) const; 3690b57cec5SDimitry Andric void dumpPassArguments() const; 3700b57cec5SDimitry Andric void dumpPassInfo(Pass *P, enum PassDebuggingString S1, 3710b57cec5SDimitry Andric enum PassDebuggingString S2, StringRef Msg); 3720b57cec5SDimitry Andric void dumpRequiredSet(const Pass *P) const; 3730b57cec5SDimitry Andric void dumpPreservedSet(const Pass *P) const; 3740b57cec5SDimitry Andric void dumpUsedSet(const Pass *P) const; 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric unsigned getNumContainedPasses() const { 3770b57cec5SDimitry Andric return (unsigned)PassVector.size(); 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric virtual PassManagerType getPassManagerType() const { 3810b57cec5SDimitry Andric assert ( 0 && "Invalid use of getPassManagerType"); 3820b57cec5SDimitry Andric return PMT_Unknown; 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric DenseMap<AnalysisID, Pass*> *getAvailableAnalysis() { 3860b57cec5SDimitry Andric return &AvailableAnalysis; 3870b57cec5SDimitry Andric } 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric // Collect AvailableAnalysis from all the active Pass Managers. 3900b57cec5SDimitry Andric void populateInheritedAnalysis(PMStack &PMS) { 3910b57cec5SDimitry Andric unsigned Index = 0; 392fe6060f1SDimitry Andric for (PMDataManager *PMDM : PMS) 393fe6060f1SDimitry Andric InheritedAnalysis[Index++] = PMDM->getAvailableAnalysis(); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric /// Set the initial size of the module if the user has specified that they 3970b57cec5SDimitry Andric /// want remarks for size. 3980b57cec5SDimitry Andric /// Returns 0 if the remark was not requested. 3990b57cec5SDimitry Andric unsigned initSizeRemarkInfo( 4000b57cec5SDimitry Andric Module &M, 4010b57cec5SDimitry Andric StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount); 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric /// Emit a remark signifying that the number of IR instructions in the module 4040b57cec5SDimitry Andric /// changed. 4050b57cec5SDimitry Andric /// \p F is optionally passed by passes which run on Functions, and thus 4060b57cec5SDimitry Andric /// always know whether or not a non-empty function is available. 4070b57cec5SDimitry Andric /// 4080b57cec5SDimitry Andric /// \p FunctionToInstrCount maps the name of a \p Function to a pair. The 4090b57cec5SDimitry Andric /// first member of the pair is the IR count of the \p Function before running 4100b57cec5SDimitry Andric /// \p P, and the second member is the IR count of the \p Function after 4110b57cec5SDimitry Andric /// running \p P. 4120b57cec5SDimitry Andric void emitInstrCountChangedRemark( 4130b57cec5SDimitry Andric Pass *P, Module &M, int64_t Delta, unsigned CountBefore, 4140b57cec5SDimitry Andric StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount, 4150b57cec5SDimitry Andric Function *F = nullptr); 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric protected: 4180b57cec5SDimitry Andric // Top level manager. 41981ad6265SDimitry Andric PMTopLevelManager *TPM = nullptr; 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric // Collection of pass that are managed by this manager 4220b57cec5SDimitry Andric SmallVector<Pass *, 16> PassVector; 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric // Collection of Analysis provided by Parent pass manager and 425*5f757f3fSDimitry Andric // used by current pass manager. At any time there can not be more 426*5f757f3fSDimitry Andric // then PMT_Last active pass managers. 4270b57cec5SDimitry Andric DenseMap<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last]; 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions 4300b57cec5SDimitry Andric /// or higher is specified. 4310b57cec5SDimitry Andric bool isPassDebuggingExecutionsOrMore() const; 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric private: 4340b57cec5SDimitry Andric void dumpAnalysisUsage(StringRef Msg, const Pass *P, 4350b57cec5SDimitry Andric const AnalysisUsage::VectorType &Set) const; 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric // Set of available Analysis. This information is used while scheduling 4380b57cec5SDimitry Andric // pass. If a pass requires an analysis which is not available then 4390b57cec5SDimitry Andric // the required analysis pass is scheduled to run before the pass itself is 4400b57cec5SDimitry Andric // scheduled to run. 4410b57cec5SDimitry Andric DenseMap<AnalysisID, Pass*> AvailableAnalysis; 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric // Collection of higher level analysis used by the pass managed by 4440b57cec5SDimitry Andric // this manager. 4450b57cec5SDimitry Andric SmallVector<Pass *, 16> HigherLevelAnalysis; 4460b57cec5SDimitry Andric 44781ad6265SDimitry Andric unsigned Depth = 0; 4480b57cec5SDimitry Andric }; 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4510b57cec5SDimitry Andric // FPPassManager 4520b57cec5SDimitry Andric // 4530b57cec5SDimitry Andric /// FPPassManager manages BBPassManagers and FunctionPasses. 4540b57cec5SDimitry Andric /// It batches all function passes and basic block pass managers together and 4550b57cec5SDimitry Andric /// sequence them to process one function at a time before processing next 4560b57cec5SDimitry Andric /// function. 4570b57cec5SDimitry Andric class FPPassManager : public ModulePass, public PMDataManager { 4580b57cec5SDimitry Andric public: 4590b57cec5SDimitry Andric static char ID; 46004eeddc0SDimitry Andric explicit FPPassManager() : ModulePass(ID) {} 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric /// run - Execute all of the passes scheduled for execution. Keep track of 4630b57cec5SDimitry Andric /// whether any of the passes modifies the module, and if so, return true. 4640b57cec5SDimitry Andric bool runOnFunction(Function &F); 4650b57cec5SDimitry Andric bool runOnModule(Module &M) override; 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric /// cleanup - After running all passes, clean up pass manager cache. 4680b57cec5SDimitry Andric void cleanup(); 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric /// doInitialization - Overrides ModulePass doInitialization for global 4710b57cec5SDimitry Andric /// initialization tasks 4720b57cec5SDimitry Andric /// 4730b57cec5SDimitry Andric using ModulePass::doInitialization; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric /// doInitialization - Run all of the initializers for the function passes. 4760b57cec5SDimitry Andric /// 4770b57cec5SDimitry Andric bool doInitialization(Module &M) override; 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric /// doFinalization - Overrides ModulePass doFinalization for global 4800b57cec5SDimitry Andric /// finalization tasks 4810b57cec5SDimitry Andric /// 4820b57cec5SDimitry Andric using ModulePass::doFinalization; 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric /// doFinalization - Run all of the finalizers for the function passes. 4850b57cec5SDimitry Andric /// 4860b57cec5SDimitry Andric bool doFinalization(Module &M) override; 4870b57cec5SDimitry Andric 4880b57cec5SDimitry Andric PMDataManager *getAsPMDataManager() override { return this; } 4890b57cec5SDimitry Andric Pass *getAsPass() override { return this; } 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric /// Pass Manager itself does not invalidate any analysis info. 4920b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &Info) const override { 4930b57cec5SDimitry Andric Info.setPreservesAll(); 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric // Print passes managed by this manager 4970b57cec5SDimitry Andric void dumpPassStructure(unsigned Offset) override; 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric StringRef getPassName() const override { return "Function Pass Manager"; } 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric FunctionPass *getContainedPass(unsigned N) { 5020b57cec5SDimitry Andric assert ( N < PassVector.size() && "Pass number out of range!"); 5030b57cec5SDimitry Andric FunctionPass *FP = static_cast<FunctionPass *>(PassVector[N]); 5040b57cec5SDimitry Andric return FP; 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric PassManagerType getPassManagerType() const override { 5080b57cec5SDimitry Andric return PMT_FunctionPassManager; 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric }; 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric #endif 515