X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FPassManagers.h;h=1aa0d3a6fa427cc64114ea9d4db5ac428d06cff8;hb=47128fe2969b90880c5ffdbeb8c699a06bbaa9f9;hp=e4ae30a15cb005778a1152b304629a552f8b89ff;hpb=b05ef6a8eb4e06a4c3addb74d7d30eb2150049ea;p=oota-llvm.git diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h index e4ae30a15cb..1aa0d3a6fa4 100644 --- a/include/llvm/PassManagers.h +++ b/include/llvm/PassManagers.h @@ -1,9 +1,9 @@ -//===- llvm/PassManager.h - Pass Inftrastructre classes --------*- C++ -*-===// +//===- llvm/PassManagers.h - Pass Infrastructure classes -------*- C++ -*-===// // // 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 is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -11,12 +11,15 @@ // //===----------------------------------------------------------------------===// -#include "llvm/PassManager.h" -#include "llvm/Support/Timer.h" +#ifndef LLVM_PASSMANAGERS_H +#define LLVM_PASSMANAGERS_H -using namespace llvm; -class llvm::PMDataManager; -class llvm::PMStack; +#include "llvm/PassManager.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/DenseMap.h" +#include +#include //===----------------------------------------------------------------------===// // Overview: @@ -30,8 +33,8 @@ class llvm::PMStack; // // 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. +// This class hierarchy 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. @@ -85,7 +88,12 @@ class llvm::PMStack; // MPPassManagers. //===----------------------------------------------------------------------===// +#include "llvm/Support/PrettyStackTrace.h" + namespace llvm { + class Pass; + class Value; + class Module; /// FunctionPassManager and PassManager, two top level managers, serve /// as the public interface of pass manager infrastructure. @@ -94,6 +102,67 @@ enum TopLevelManagerType { TLM_Pass // PassManager }; +// enums for debugging strings +enum PassDebuggingString { + EXECUTION_MSG, // "Executing Pass '" + MODIFICATION_MSG, // "' Made Modification '" + FREEING_MSG, // " Freeing Pass '" + ON_BASICBLOCK_MSG, // "' on BasicBlock '" + PassName + "'...\n" + ON_FUNCTION_MSG, // "' on Function '" + FunctionName + "'...\n" + ON_MODULE_MSG, // "' on Module '" + ModuleName + "'...\n" + ON_LOOP_MSG, // " 'on Loop ...\n'" + ON_CG_MSG // "' on Call Graph ...\n'" +}; + +/// PassManagerPrettyStackEntry - This is used to print informative information +/// about what pass is running when/if a stack trace is generated. +class PassManagerPrettyStackEntry : public PrettyStackTraceEntry { + Pass *P; + Value *V; + Module *M; +public: + PassManagerPrettyStackEntry(Pass *p) + : P(p), V(0), M(0) {} // When P is releaseMemory'd. + PassManagerPrettyStackEntry(Pass *p, Value &v) + : P(p), V(&v), M(0) {} // When P is run on V + PassManagerPrettyStackEntry(Pass *p, Module &m) + : P(p), V(0), M(&m) {} // When P is run on M + + /// print - Emit information about this stack frame to OS. + virtual void print(raw_ostream &OS) const; +}; + + +//===----------------------------------------------------------------------===// +// PMStack +// +/// PMStack +/// Top level pass managers (see PassManager.cpp) maintain active Pass Managers +/// using PMStack. Each Pass implements assignPassManager() to connect itself +/// with appropriate manager. assignPassManager() walks PMStack to find +/// suitable manager. +/// +/// PMStack is just a wrapper around standard deque that overrides pop() and +/// push() methods. +class PMStack { +public: + typedef std::deque::reverse_iterator iterator; + iterator begin() { return S.rbegin(); } + iterator end() { return S.rend(); } + + void handleLastUserOverflow(); + + void pop(); + inline PMDataManager *top() { return S.back(); } + void push(PMDataManager *PM); + inline bool empty() { return S.empty(); } + + void dump(); +private: + std::deque S; +}; + + //===----------------------------------------------------------------------===// // PMTopLevelManager // @@ -102,8 +171,8 @@ enum TopLevelManagerType { class PMTopLevelManager { public: - virtual unsigned getNumContainedManagers() { - return PassManagers.size(); + virtual unsigned getNumContainedManagers() const { + return (unsigned)PassManagers.size(); } /// Schedule pass P for execution. Make sure that passes required by @@ -116,17 +185,20 @@ public: 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); + void setLastUser(SmallVector &AnalysisPasses, Pass *P); /// Collect passes whose last user is P - void collectLastUses(std::vector &LastUses, Pass *P); + void collectLastUses(SmallVector &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); - PMTopLevelManager(enum TopLevelManagerType t); + /// Find analysis usage information for the pass P. + AnalysisUsage *findAnalysisUsage(Pass *P); + + explicit PMTopLevelManager(enum TopLevelManagerType t); virtual ~PMTopLevelManager(); /// Add immutable pass and initialize it. @@ -135,11 +207,11 @@ public: ImmutablePasses.push_back(P); } - inline std::vector& getImmutablePasses() { + inline SmallVector& getImmutablePasses() { return ImmutablePasses; } - void addPassManager(Pass *Manager) { + void addPassManager(PMDataManager *Manager) { PassManagers.push_back(Manager); } @@ -161,20 +233,27 @@ public: protected: /// Collection of pass managers - std::vector PassManagers; + SmallVector PassManagers; private: /// Collection of pass managers that are not directly maintained /// by this pass manager - std::vector IndirectPassManagers; + SmallVector IndirectPassManagers; // Map to keep track of last user of the analysis pass. // LastUser->second is the last user of Lastuser->first. - std::map LastUser; + DenseMap LastUser; + + // Map to keep track of passes that are last used by a pass. + // This inverse map is initialized at PM->run() based on + // LastUser map. + DenseMap > InversedLastUser; /// Immutable passes are managed by top level manager. - std::vector ImmutablePasses; + SmallVector ImmutablePasses; + + DenseMap AnUsageMap; }; @@ -186,39 +265,60 @@ private: /// used by pass managers. class PMDataManager { public: - PMDataManager(int Depth) : TPM(NULL), Depth(Depth) { + + explicit 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); + /// verifyPreservedAnalysis -- Verify analysis presreved by pass P. + void verifyPreservedAnalysis(Pass *P); + + /// verifyDomInfo -- Verify dominator information if it is available. + void verifyDomInfo(Pass &P, Function &F); + /// Remove Analysis that is not preserved by the pass void removeNotPreservedAnalysis(Pass *P); /// Remove dead passes - void removeDeadPasses(Pass *P, std::string &Msg); + void removeDeadPasses(Pass *P, const char *Msg, enum PassDebuggingString); /// Add pass P into the PassVector. Update /// AvailableAnalysis appropriately if ProcessAnalysis is true. void add(Pass *P, bool ProcessAnalysis = true); + /// Add RequiredPass into list of lower level passes required by pass P. + /// RequiredPass is run on the fly by Pass Manager when P requests it + /// through getAnalysis interface. + virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass); + + virtual Pass * getOnTheFlyPass(Pass *P, const PassInfo *PI, Function &F) { + assert (0 && "Unable to find on the fly pass"); + return NULL; + } + /// Initialize available analysis information. void initializeAnalysisInfo() { - TransferLastUses.clear(); AvailableAnalysis.clear(); + for (unsigned i = 0; i < PMT_Last; ++i) + InheritedAnalysis[i] = NULL; } - /// Populate RequiredPasses with the analysis pass that are required by - /// pass P. - void collectRequiredAnalysisPasses(std::vector &RequiredPasses, - Pass *P); + // Return true if P preserves high level analysis used by other + // passes that are managed by this manager. + bool preserveHigherLevelAnalysis(Pass *P); + + + /// Populate RequiredPasses with analysis pass that are required by + /// pass P and are available. Populate ReqPassNotAvailable with analysis + /// pass that are required by pass P but are not available. + void collectRequiredAnalysis(SmallVector &RequiredPasses, + SmallVector &ReqPassNotAvailable, + 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 @@ -239,43 +339,59 @@ public: // 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; - } + void dumpPassInfo(Pass *P, enum PassDebuggingString S1, + enum PassDebuggingString S2, const char *Msg); + void dumpRequiredSet(const Pass *P) const; + void dumpPreservedSet(const Pass *P) const; - virtual unsigned getNumContainedPasses() { - return PassVector.size(); + virtual unsigned getNumContainedPasses() const { + return (unsigned)PassVector.size(); } - virtual PassManagerType getPassManagerType() { + virtual PassManagerType getPassManagerType() const { 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; + std::map *getAvailableAnalysis() { + return &AvailableAnalysis; + } + + // Collect AvailableAnalysis from all the active Pass Managers. + void populateInheritedAnalysis(PMStack &PMS) { + unsigned Index = 0; + for (PMStack::iterator I = PMS.begin(), E = PMS.end(); + I != E; ++I) + InheritedAnalysis[Index++] = (*I)->getAvailableAnalysis(); + } + +protected: // Top level manager. PMTopLevelManager *TPM; // Collection of pass that are managed by this manager - std::vector PassVector; + SmallVector PassVector; + + // Collection of Analysis provided by Parent pass manager and + // used by current pass manager. At at time there can not be more + // then PMT_Last active pass mangers. + std::map *InheritedAnalysis[PMT_Last]; private: + void dumpAnalysisUsage(const char *Msg, const Pass *P, + const AnalysisUsage::VectorType &Set) const; + // 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; + // Collection of higher level analysis used by the pass managed by + // this manager. + SmallVector HigherLevelAnalysis; + unsigned Depth; }; @@ -290,18 +406,23 @@ private: class FPPassManager : public ModulePass, public PMDataManager { public: - FPPassManager(int Depth) : PMDataManager(Depth) { } + static char ID; + explicit FPPassManager(int Depth) + : ModulePass(&ID), 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); + + /// cleanup - After running all passes, clean up pass manager cache. + void cleanup(); /// doInitialization - Run all of the initializers for the function passes. /// bool doInitialization(Module &M); - /// doFinalization - Run all of the initializers for the function passes. + /// doFinalization - Run all of the finalizers for the function passes. /// bool doFinalization(Module &M); @@ -313,64 +434,24 @@ public: // Print passes managed by this manager void dumpPassStructure(unsigned Offset); + virtual const char *getPassName() const { + return "Function Pass Manager"; + } + FunctionPass *getContainedPass(unsigned N) { assert ( N < PassVector.size() && "Pass number out of range!"); FunctionPass *FP = static_cast(PassVector[N]); return FP; } - virtual PassManagerType getPassManagerType() { + virtual PassManagerType getPassManagerType() const { return PMT_FunctionPassManager; } }; -//===----------------------------------------------------------------------===// -// TimingInfo Class - This class is used to calculate information about the -// amount of time each pass takes to execute. This only happens when -// -time-passes is enabled on the command line. -// - -class TimingInfo { - std::map TimingData; - TimerGroup TG; - -public: - // Use 'create' member to get this. - TimingInfo() : TG("... Pass execution timing report ...") {} - - // TimingDtor - Print out information about timing information - ~TimingInfo() { - // Delete all of the timers... - TimingData.clear(); - // TimerGroup is deleted next, printing the report. - } - - // createTheTimeInfo - This method either initializes the TheTimeInfo pointer - // to a non null value (if the -time-passes option is enabled) or it leaves it - // null. It may be called multiple times. - static void createTheTimeInfo(); - - void passStarted(Pass *P) { - - if (dynamic_cast(P)) - return; - - std::map::iterator I = TimingData.find(P); - if (I == TimingData.end()) - I=TimingData.insert(std::make_pair(P, Timer(P->getPassName(), TG))).first; - I->second.startTimer(); - } - void passEnded(Pass *P) { - - if (dynamic_cast(P)) - return; - - std::map::iterator I = TimingData.find(P); - assert (I != TimingData.end() && "passStarted/passEnded not nested right!"); - I->second.stopTimer(); - } -}; - -extern TimingInfo *getTheTimeInfo(); } +extern void StartPassTimer(llvm::Pass *); +extern void StopPassTimer(llvm::Pass *); + +#endif