From ab7752c1496c2913793305ba4b989a551c5617e1 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 12 Jan 2007 18:52:44 +0000 Subject: [PATCH] Move PMTopLevelManager, PMDataManager and FPPassManger classes into new PassManagers.h header. This opens door for implementing CGPassManager in IPA library. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33135 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/PassManagers.h | 319 +++++++++++++++++++++++++++++++ lib/VMCore/PassManager.cpp | 361 ++++-------------------------------- 2 files changed, 357 insertions(+), 323 deletions(-) create mode 100644 include/llvm/PassManagers.h diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h new file mode 100644 index 00000000000..5de9565a29b --- /dev/null +++ b/include/llvm/PassManagers.h @@ -0,0 +1,319 @@ +//===- PassManager.cpp - LLVM Pass Infrastructure Implementation ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Devang Patel and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the LLVM Pass Manager infrastructure. +// +//===----------------------------------------------------------------------===// + +#include "llvm/PassManager.h" + +using namespace llvm; +class llvm::PMDataManager; +class llvm::PMStack; + +//===----------------------------------------------------------------------===// +// Overview: +// The Pass Manager Infrastructure manages passes. It's responsibilities are: +// +// o Manage optimization pass execution order +// o Make required Analysis information available before pass P is run +// o Release memory occupied by dead passes +// o If Analysis information is dirtied by a pass then regenerate Analysis +// information before it is consumed by another pass. +// +// Pass Manager Infrastructure uses multiple pass managers. They are +// PassManager, FunctionPassManager, MPPassManager, FPPassManager, BBPassManager. +// This class hierarcy uses multiple inheritance but pass managers do not derive +// from another pass manager. +// +// PassManager and FunctionPassManager are two top-level pass manager that +// represents the external interface of this entire pass manager infrastucture. +// +// Important classes : +// +// [o] class PMTopLevelManager; +// +// Two top level managers, PassManager and FunctionPassManager, derive from +// PMTopLevelManager. PMTopLevelManager manages information used by top level +// managers such as last user info. +// +// [o] class PMDataManager; +// +// PMDataManager manages information, e.g. list of available analysis info, +// used by a pass manager to manage execution order of passes. It also provides +// a place to implement common pass manager APIs. All pass managers derive from +// PMDataManager. +// +// [o] class BBPassManager : public FunctionPass, public PMDataManager; +// +// BBPassManager manages BasicBlockPasses. +// +// [o] class FunctionPassManager; +// +// This is a external interface used by JIT to manage FunctionPasses. This +// interface relies on FunctionPassManagerImpl to do all the tasks. +// +// [o] class FunctionPassManagerImpl : public ModulePass, PMDataManager, +// public PMTopLevelManager; +// +// FunctionPassManagerImpl is a top level manager. It manages FPPassManagers +// +// [o] class FPPassManager : public ModulePass, public PMDataManager; +// +// FPPassManager manages FunctionPasses and BBPassManagers +// +// [o] class MPPassManager : public Pass, public PMDataManager; +// +// MPPassManager manages ModulePasses and FPPassManagers +// +// [o] class PassManager; +// +// This is a external interface used by various tools to manages passes. It +// relies on PassManagerImpl to do all the tasks. +// +// [o] class PassManagerImpl : public Pass, public PMDataManager, +// public PMDTopLevelManager +// +// PassManagerImpl is a top level pass manager responsible for managing +// MPPassManagers. +//===----------------------------------------------------------------------===// + +namespace llvm { + +//===----------------------------------------------------------------------===// +// PMTopLevelManager +// +/// PMTopLevelManager manages LastUser info and collects common APIs used by +/// top level pass managers. +class PMTopLevelManager { +public: + + virtual unsigned getNumContainedManagers() { + return PassManagers.size(); + } + + /// Schedule pass P for execution. Make sure that passes required by + /// P are run before P is run. Update analysis info maintained by + /// the manager. Remove dead passes. This is a recursive function. + void schedulePass(Pass *P); + + /// This is implemented by top level pass manager and used by + /// schedulePass() to add analysis info passes that are not available. + virtual void addTopLevelPass(Pass *P) = 0; + + /// Set pass P as the last user of the given analysis passes. + void setLastUser(std::vector &AnalysisPasses, Pass *P); + + /// Collect passes whose last user is P + void collectLastUses(std::vector &LastUses, Pass *P); + + /// Find the pass that implements Analysis AID. Search immutable + /// passes and all pass managers. If desired pass is not found + /// then return NULL. + Pass *findAnalysisPass(AnalysisID AID); + + virtual ~PMTopLevelManager(); + + /// Add immutable pass and initialize it. + inline void addImmutablePass(ImmutablePass *P) { + P->initializePass(); + ImmutablePasses.push_back(P); + } + + inline std::vector& getImmutablePasses() { + return ImmutablePasses; + } + + void addPassManager(Pass *Manager) { + PassManagers.push_back(Manager); + } + + // Add Manager into the list of managers that are not directly + // maintained by this top level pass manager + inline void addIndirectPassManager(PMDataManager *Manager) { + IndirectPassManagers.push_back(Manager); + } + + // Print passes managed by this top level manager. + void dumpPasses() const; + void dumpArguments() const; + + void initializeAllAnalysisInfo(); + + // Active Pass Managers + PMStack activeStack; + +protected: + + /// Collection of pass managers + std::vector PassManagers; + +private: + + /// Collection of pass managers that are not directly maintained + /// by this pass manager + std::vector IndirectPassManagers; + + // Map to keep track of last user of the analysis pass. + // LastUser->second is the last user of Lastuser->first. + std::map LastUser; + + /// Immutable passes are managed by top level manager. + std::vector ImmutablePasses; +}; + + + +//===----------------------------------------------------------------------===// +// PMDataManager + +/// PMDataManager provides the common place to manage the analysis data +/// used by pass managers. +class PMDataManager { +public: + PMDataManager(int Depth) : TPM(NULL), Depth(Depth) { + initializeAnalysisInfo(); + } + + virtual ~PMDataManager(); + + /// Return true IFF pass P's required analysis set does not required new + /// manager. + bool manageablePass(Pass *P); + + /// Augment AvailableAnalysis by adding analysis made available by pass P. + void recordAvailableAnalysis(Pass *P); + + /// Remove Analysis that is not preserved by the pass + void removeNotPreservedAnalysis(Pass *P); + + /// Remove dead passes + void removeDeadPasses(Pass *P, std::string &Msg); + + /// Add pass P into the PassVector. Update + /// AvailableAnalysis appropriately if ProcessAnalysis is true. + void addPassToManager(Pass *P, bool ProcessAnalysis = true); + + /// Initialize available analysis information. + void initializeAnalysisInfo() { + TransferLastUses.clear(); + AvailableAnalysis.clear(); + } + + /// Populate RequiredPasses with the analysis pass that are required by + /// pass P. + void collectRequiredAnalysisPasses(std::vector &RequiredPasses, + Pass *P); + + /// All Required analyses should be available to the pass as it runs! Here + /// we fill in the AnalysisImpls member of the pass so that it can + /// successfully use the getAnalysis() method to retrieve the + /// implementations it needs. + void initializeAnalysisImpl(Pass *P); + + /// Find the pass that implements Analysis AID. If desired pass is not found + /// then return NULL. + Pass *findAnalysisPass(AnalysisID AID, bool Direction); + + // Access toplevel manager + PMTopLevelManager *getTopLevelManager() { return TPM; } + void setTopLevelManager(PMTopLevelManager *T) { TPM = T; } + + unsigned getDepth() const { return Depth; } + + // Print routines used by debug-pass + void dumpLastUses(Pass *P, unsigned Offset) const; + void dumpPassArguments() const; + void dumpPassInfo(Pass *P, std::string &Msg1, std::string &Msg2) const; + void dumpAnalysisSetInfo(const char *Msg, Pass *P, + const std::vector &Set) const; + + std::vector& getTransferredLastUses() { + return TransferLastUses; + } + + virtual unsigned getNumContainedPasses() { + return PassVector.size(); + } + + virtual PassManagerType getPassManagerType() { + assert ( 0 && "Invalid use of getPassManagerType"); + return PMT_Unknown; + } +protected: + + // If a FunctionPass F is the last user of ModulePass info M + // then the F's manager, not F, records itself as a last user of M. + // Current pass manage is requesting parent manager to record parent + // manager as the last user of these TrransferLastUses passes. + std::vector TransferLastUses; + + // Top level manager. + PMTopLevelManager *TPM; + + // Collection of pass that are managed by this manager + std::vector PassVector; + +private: + // Set of available Analysis. This information is used while scheduling + // pass. If a pass requires an analysis which is not not available then + // equired analysis pass is scheduled to run before the pass itself is + // scheduled to run. + std::map AvailableAnalysis; + + unsigned Depth; +}; + +//===----------------------------------------------------------------------===// +// FPPassManager +// +/// FPPassManager manages BBPassManagers and FunctionPasses. +/// It batches all function passes and basic block pass managers together and +/// sequence them to process one function at a time before processing next +/// function. + +class FPPassManager : public ModulePass, public PMDataManager { + +public: + FPPassManager(int Depth) : PMDataManager(Depth) { } + + /// run - Execute all of the passes scheduled for execution. Keep track of + /// whether any of the passes modifies the module, and if so, return true. + bool runOnFunction(Function &F); + bool runOnModule(Module &M); + + /// doInitialization - Run all of the initializers for the function passes. + /// + bool doInitialization(Module &M); + + /// doFinalization - Run all of the initializers for the function passes. + /// + bool doFinalization(Module &M); + + /// Pass Manager itself does not invalidate any analysis info. + void getAnalysisUsage(AnalysisUsage &Info) const { + Info.setPreservesAll(); + } + + // Print passes managed by this manager + void dumpPassStructure(unsigned Offset); + + FunctionPass *getContainedPass(unsigned N) { + assert ( N < PassVector.size() && "Pass number out of range!"); + FunctionPass *FP = static_cast(PassVector[N]); + return FP; + } + + virtual PassManagerType getPassManagerType() { + return PMT_FunctionPassManager; + } +}; + +} + diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index a45b8f8e4cd..28b0b89bba8 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// -#include "llvm/PassManager.h" +#include "llvm/PassManagers.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Timer.h" #include "llvm/Module.h" @@ -22,76 +22,7 @@ #include #include -using namespace llvm; -class llvm::PMDataManager; -class llvm::PMStack; - -//===----------------------------------------------------------------------===// -// Overview: -// The Pass Manager Infrastructure manages passes. It's responsibilities are: -// -// o Manage optimization pass execution order -// o Make required Analysis information available before pass P is run -// o Release memory occupied by dead passes -// o If Analysis information is dirtied by a pass then regenerate Analysis -// information before it is consumed by another pass. -// -// Pass Manager Infrastructure uses multiple pass managers. They are -// PassManager, FunctionPassManager, MPPassManager, FPPassManager, BBPassManager. -// This class hierarcy uses multiple inheritance but pass managers do not derive -// from another pass manager. -// -// PassManager and FunctionPassManager are two top-level pass manager that -// represents the external interface of this entire pass manager infrastucture. -// -// Important classes : -// -// [o] class PMTopLevelManager; -// -// Two top level managers, PassManager and FunctionPassManager, derive from -// PMTopLevelManager. PMTopLevelManager manages information used by top level -// managers such as last user info. -// -// [o] class PMDataManager; -// -// PMDataManager manages information, e.g. list of available analysis info, -// used by a pass manager to manage execution order of passes. It also provides -// a place to implement common pass manager APIs. All pass managers derive from -// PMDataManager. -// -// [o] class BBPassManager : public FunctionPass, public PMDataManager; -// -// BBPassManager manages BasicBlockPasses. -// -// [o] class FunctionPassManager; -// -// This is a external interface used by JIT to manage FunctionPasses. This -// interface relies on FunctionPassManagerImpl to do all the tasks. -// -// [o] class FunctionPassManagerImpl : public ModulePass, PMDataManager, -// public PMTopLevelManager; -// -// FunctionPassManagerImpl is a top level manager. It manages FPPassManagers -// -// [o] class FPPassManager : public ModulePass, public PMDataManager; -// -// FPPassManager manages FunctionPasses and BBPassManagers -// -// [o] class MPPassManager : public Pass, public PMDataManager; -// -// MPPassManager manages ModulePasses and FPPassManagers -// -// [o] class PassManager; -// -// This is a external interface used by various tools to manages passes. It -// relies on PassManagerImpl to do all the tasks. -// -// [o] class PassManagerImpl : public Pass, public PMDataManager, -// public PMDTopLevelManager -// -// PassManagerImpl is a top level pass manager responsible for managing -// MPPassManagers. -//===----------------------------------------------------------------------===// +// See PassManagers.h for Pass Manager infrastructure overview. namespace llvm { @@ -121,208 +52,6 @@ PassDebugging_New("debug-pass", cl::Hidden, namespace { -//===----------------------------------------------------------------------===// -// PMTopLevelManager -// -/// PMTopLevelManager manages LastUser info and collects common APIs used by -/// top level pass managers. -class VISIBILITY_HIDDEN PMTopLevelManager { -public: - - virtual unsigned getNumContainedManagers() { - return PassManagers.size(); - } - - /// Schedule pass P for execution. Make sure that passes required by - /// P are run before P is run. Update analysis info maintained by - /// the manager. Remove dead passes. This is a recursive function. - void schedulePass(Pass *P); - - /// This is implemented by top level pass manager and used by - /// schedulePass() to add analysis info passes that are not available. - virtual void addTopLevelPass(Pass *P) = 0; - - /// Set pass P as the last user of the given analysis passes. - void setLastUser(std::vector &AnalysisPasses, Pass *P); - - /// Collect passes whose last user is P - void collectLastUses(std::vector &LastUses, Pass *P); - - /// Find the pass that implements Analysis AID. Search immutable - /// passes and all pass managers. If desired pass is not found - /// then return NULL. - Pass *findAnalysisPass(AnalysisID AID); - - virtual ~PMTopLevelManager() { - for (std::vector::iterator I = PassManagers.begin(), - E = PassManagers.end(); I != E; ++I) - delete *I; - - for (std::vector::iterator - I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) - delete *I; - - PassManagers.clear(); - } - - /// Add immutable pass and initialize it. - inline void addImmutablePass(ImmutablePass *P) { - P->initializePass(); - ImmutablePasses.push_back(P); - } - - inline std::vector& getImmutablePasses() { - return ImmutablePasses; - } - - void addPassManager(Pass *Manager) { - PassManagers.push_back(Manager); - } - - // Add Manager into the list of managers that are not directly - // maintained by this top level pass manager - inline void addIndirectPassManager(PMDataManager *Manager) { - IndirectPassManagers.push_back(Manager); - } - - // Print passes managed by this top level manager. - void dumpPasses() const; - void dumpArguments() const; - - void initializeAllAnalysisInfo(); - - // Active Pass Managers - PMStack activeStack; - -protected: - - /// Collection of pass managers - std::vector PassManagers; - -private: - - /// Collection of pass managers that are not directly maintained - /// by this pass manager - std::vector IndirectPassManagers; - - // Map to keep track of last user of the analysis pass. - // LastUser->second is the last user of Lastuser->first. - std::map LastUser; - - /// Immutable passes are managed by top level manager. - std::vector ImmutablePasses; -}; - -} // End of anon namespace - -//===----------------------------------------------------------------------===// -// PMDataManager - -namespace llvm { -/// PMDataManager provides the common place to manage the analysis data -/// used by pass managers. -class PMDataManager { -public: - PMDataManager(int Depth) : TPM(NULL), Depth(Depth) { - initializeAnalysisInfo(); - } - - virtual ~PMDataManager() { - - for (std::vector::iterator I = PassVector.begin(), - E = PassVector.end(); I != E; ++I) - delete *I; - - PassVector.clear(); - } - - /// Return true IFF pass P's required analysis set does not required new - /// manager. - bool manageablePass(Pass *P); - - /// Augment AvailableAnalysis by adding analysis made available by pass P. - void recordAvailableAnalysis(Pass *P); - - /// Remove Analysis that is not preserved by the pass - void removeNotPreservedAnalysis(Pass *P); - - /// Remove dead passes - void removeDeadPasses(Pass *P, std::string &Msg); - - /// Add pass P into the PassVector. Update - /// AvailableAnalysis appropriately if ProcessAnalysis is true. - void addPassToManager(Pass *P, bool ProcessAnalysis = true); - - /// Initialize available analysis information. - void initializeAnalysisInfo() { - TransferLastUses.clear(); - AvailableAnalysis.clear(); - } - - /// Populate RequiredPasses with the analysis pass that are required by - /// pass P. - void collectRequiredAnalysisPasses(std::vector &RequiredPasses, - Pass *P); - - /// All Required analyses should be available to the pass as it runs! Here - /// we fill in the AnalysisImpls member of the pass so that it can - /// successfully use the getAnalysis() method to retrieve the - /// implementations it needs. - void initializeAnalysisImpl(Pass *P); - - /// Find the pass that implements Analysis AID. If desired pass is not found - /// then return NULL. - Pass *findAnalysisPass(AnalysisID AID, bool Direction); - - // Access toplevel manager - PMTopLevelManager *getTopLevelManager() { return TPM; } - void setTopLevelManager(PMTopLevelManager *T) { TPM = T; } - - unsigned getDepth() const { return Depth; } - - // Print routines used by debug-pass - void dumpLastUses(Pass *P, unsigned Offset) const; - void dumpPassArguments() const; - void dumpPassInfo(Pass *P, std::string &Msg1, std::string &Msg2) const; - void dumpAnalysisSetInfo(const char *Msg, Pass *P, - const std::vector &Set) const; - - std::vector& getTransferredLastUses() { - return TransferLastUses; - } - - virtual unsigned getNumContainedPasses() { - return PassVector.size(); - } - - virtual PassManagerType getPassManagerType() { - assert ( 0 && "Invalid use of getPassManagerType"); - return PMT_Unknown; - } -protected: - - // If a FunctionPass F is the last user of ModulePass info M - // then the F's manager, not F, records itself as a last user of M. - // Current pass manage is requesting parent manager to record parent - // manager as the last user of these TrransferLastUses passes. - std::vector TransferLastUses; - - // Top level manager. - PMTopLevelManager *TPM; - - // Collection of pass that are managed by this manager - std::vector PassVector; - -private: - // Set of available Analysis. This information is used while scheduling - // pass. If a pass requires an analysis which is not not available then - // equired analysis pass is scheduled to run before the pass itself is - // scheduled to run. - std::map AvailableAnalysis; - - unsigned Depth; -}; - //===----------------------------------------------------------------------===// // BBPassManager // @@ -370,57 +99,9 @@ public: } }; -//===----------------------------------------------------------------------===// -// FPPassManager -// -/// FPPassManager manages BBPassManagers and FunctionPasses. -/// It batches all function passes and basic block pass managers together and -/// sequence them to process one function at a time before processing next -/// function. - -class FPPassManager : public ModulePass, public PMDataManager { - -public: - FPPassManager(int Depth) : PMDataManager(Depth) { } - - /// run - Execute all of the passes scheduled for execution. Keep track of - /// whether any of the passes modifies the module, and if so, return true. - bool runOnFunction(Function &F); - bool runOnModule(Module &M); - - /// doInitialization - Run all of the initializers for the function passes. - /// - bool doInitialization(Module &M); - - /// doFinalization - Run all of the initializers for the function passes. - /// - bool doFinalization(Module &M); - - /// Pass Manager itself does not invalidate any analysis info. - void getAnalysisUsage(AnalysisUsage &Info) const { - Info.setPreservesAll(); - } - - // Print passes managed by this manager - void dumpPassStructure(unsigned Offset) { - llvm::cerr << std::string(Offset*2, ' ') << "FunctionPass Manager\n"; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - FunctionPass *FP = getContainedPass(Index); - FP->dumpPassStructure(Offset + 1); - dumpLastUses(FP, Offset+1); - } - } - - FunctionPass *getContainedPass(unsigned N) { - assert ( N < PassVector.size() && "Pass number out of range!"); - FunctionPass *FP = static_cast(PassVector[N]); - return FP; - } +} - virtual PassManagerType getPassManagerType() { - return PMT_FunctionPassManager; - } -}; +namespace llvm { //===----------------------------------------------------------------------===// // FunctionPassManagerImpl @@ -785,6 +466,19 @@ void PMTopLevelManager::initializeAllAnalysisInfo() { (*I)->initializeAnalysisInfo(); } +/// Destructor +PMTopLevelManager::~PMTopLevelManager() { + for (std::vector::iterator I = PassManagers.begin(), + E = PassManagers.end(); I != E; ++I) + delete *I; + + for (std::vector::iterator + I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) + delete *I; + + PassManagers.clear(); +} + //===----------------------------------------------------------------------===// // PMDataManager implementation @@ -1024,6 +718,16 @@ void PMDataManager::dumpAnalysisSetInfo(const char *Msg, Pass *P, } } +// Destructor +PMDataManager::~PMDataManager() { + + for (std::vector::iterator I = PassVector.begin(), + E = PassVector.end(); I != E; ++I) + delete *I; + + PassVector.clear(); +} + //===----------------------------------------------------------------------===// // NOTE: Is this the right place to define this method ? // getAnalysisToUpdate - Return an analysis result or null if it doesn't exist @@ -1223,6 +927,17 @@ bool FunctionPassManagerImpl::run(Function &F) { //===----------------------------------------------------------------------===// // FPPassManager implementation +/// Print passes managed by this manager +void FPPassManager::dumpPassStructure(unsigned Offset) { + llvm::cerr << std::string(Offset*2, ' ') << "FunctionPass Manager\n"; + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + FunctionPass *FP = getContainedPass(Index); + FP->dumpPassStructure(Offset + 1); + dumpLastUses(FP, Offset+1); + } +} + + /// Execute all of the passes scheduled for execution by invoking /// runOnFunction method. Keep track of whether any of the passes modifies /// the function, and if so, return true. -- 2.34.1