#define LLVM_ANALYSIS_LOOPPASS_H
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/LegacyPassManagers.h"
#include "llvm/Pass.h"
-#include "llvm/PassManagers.h"
#include <deque>
namespace llvm {
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/LegacyPassManagers.h"
#include "llvm/Pass.h"
-#include "llvm/PassManagers.h"
#include <deque>
namespace llvm {
class MachineFunctionPass;
class PassConfigImpl;
class PassInfo;
-class PassManagerBase;
class ScheduleDAGInstrs;
class TargetLowering;
class TargetLoweringBase;
class raw_ostream;
struct MachineSchedContext;
+// The old pass manager infrastructure is hidden in a legacy namespace now.
+namespace legacy {
+class PassManagerBase;
+}
+using legacy::PassManagerBase;
+
/// Discriminated union of Pass ID types.
///
/// The PassConfig API prefers dealing with IDs because they are safer and more
--- /dev/null
+//===- LegacyPassManager.h - Legacy Container for Passes --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the legacy PassManager class. This class is used to hold,
+// maintain, and optimize execution of Passes. The PassManager class ensures
+// that analysis results are available before a pass runs, and that Pass's are
+// destroyed when the PassManager is destroyed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_LEGACYPASSMANAGER_H
+#define LLVM_IR_LEGACYPASSMANAGER_H
+
+#include "llvm/Pass.h"
+#include "llvm/Support/CBindingWrapping.h"
+
+namespace llvm {
+
+class Pass;
+class Module;
+
+namespace legacy {
+
+class PassManagerImpl;
+class FunctionPassManagerImpl;
+
+/// PassManagerBase - An abstract interface to allow code to add passes to
+/// a pass manager without having to hard-code what kind of pass manager
+/// it is.
+class PassManagerBase {
+public:
+ virtual ~PassManagerBase();
+
+ /// add - Add a pass to the queue of passes to run. This passes ownership of
+ /// the Pass to the PassManager. When the PassManager is destroyed, the pass
+ /// will be destroyed as well, so there is no need to delete the pass. This
+ /// implies that all passes MUST be allocated with 'new'.
+ virtual void add(Pass *P) = 0;
+};
+
+/// PassManager manages ModulePassManagers
+class PassManager : public PassManagerBase {
+public:
+
+ PassManager();
+ ~PassManager();
+
+ /// add - Add a pass to the queue of passes to run. This passes ownership of
+ /// the Pass to the PassManager. When the PassManager is destroyed, the pass
+ /// will be destroyed as well, so there is no need to delete the pass. This
+ /// implies that all passes MUST be allocated with 'new'.
+ void add(Pass *P);
+
+ /// 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 run(Module &M);
+
+private:
+ /// PassManagerImpl_New is the actual class. PassManager is just the
+ /// wraper to publish simple pass manager interface
+ PassManagerImpl *PM;
+};
+
+/// FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
+class FunctionPassManager : public PassManagerBase {
+public:
+ /// FunctionPassManager ctor - This initializes the pass manager. It needs,
+ /// but does not take ownership of, the specified Module.
+ explicit FunctionPassManager(Module *M);
+ ~FunctionPassManager();
+
+ /// add - Add a pass to the queue of passes to run. This passes
+ /// ownership of the Pass to the PassManager. When the
+ /// PassManager_X is destroyed, the pass will be destroyed as well, so
+ /// there is no need to delete the pass.
+ /// This implies that all passes MUST be allocated with 'new'.
+ void add(Pass *P);
+
+ /// run - Execute all of the passes scheduled for execution. Keep
+ /// track of whether any of the passes modifies the function, and if
+ /// so, return true.
+ ///
+ bool run(Function &F);
+
+ /// doInitialization - Run all of the initializers for the function passes.
+ ///
+ bool doInitialization();
+
+ /// doFinalization - Run all of the finalizers for the function passes.
+ ///
+ bool doFinalization();
+
+private:
+ FunctionPassManagerImpl *FPM;
+ Module *M;
+};
+
+} // End legacy namespace
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_STDCXX_CONVERSION_FUNCTIONS(legacy::PassManagerBase, LLVMPassManagerRef)
+
+} // End llvm namespace
+
+#endif
--- /dev/null
+//===- LegacyPassManagers.h - Legacy Pass Infrastructure --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the LLVM Pass Manager infrastructure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSMANAGERS_H
+#define LLVM_PASSMANAGERS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Pass.h"
+#include <map>
+#include <vector>
+
+//===----------------------------------------------------------------------===//
+// 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 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.
+//
+// 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 PMTopLevelManager
+//
+// PassManagerImpl is a top level pass manager responsible for managing
+// MPPassManagers.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/PrettyStackTrace.h"
+
+namespace llvm {
+ class Module;
+ class Pass;
+ class StringRef;
+ class Value;
+ class Timer;
+ class PMDataManager;
+
+// 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_REGION_MSG, // " 'on Region ...\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:
+ explicit 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 - This class implements a stack data structure of PMDataManager
+/// pointers.
+///
+/// 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.
+class PMStack {
+public:
+ typedef std::vector<PMDataManager *>::const_reverse_iterator iterator;
+ iterator begin() const { return S.rbegin(); }
+ iterator end() const { return S.rend(); }
+
+ void pop();
+ PMDataManager *top() const { return S.back(); }
+ void push(PMDataManager *PM);
+ bool empty() const { return S.empty(); }
+
+ void dump() const;
+
+private:
+ std::vector<PMDataManager *> S;
+};
+
+
+//===----------------------------------------------------------------------===//
+// PMTopLevelManager
+//
+/// PMTopLevelManager manages LastUser info and collects common APIs used by
+/// top level pass managers.
+class PMTopLevelManager {
+protected:
+ explicit PMTopLevelManager(PMDataManager *PMDM);
+
+ unsigned getNumContainedManagers() const {
+ return (unsigned)PassManagers.size();
+ }
+
+ void initializeAllAnalysisInfo();
+
+private:
+ virtual PMDataManager *getAsPMDataManager() = 0;
+ virtual PassManagerType getTopLevelPassManagerType() = 0;
+
+public:
+ /// 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);
+
+ /// Set pass P as the last user of the given analysis passes.
+ void setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P);
+
+ /// Collect passes whose last user is P
+ void collectLastUses(SmallVectorImpl<Pass *> &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);
+
+ /// Find analysis usage information for the pass P.
+ AnalysisUsage *findAnalysisUsage(Pass *P);
+
+ virtual ~PMTopLevelManager();
+
+ /// Add immutable pass and initialize it.
+ inline void addImmutablePass(ImmutablePass *P) {
+ P->initializePass();
+ ImmutablePasses.push_back(P);
+ }
+
+ inline SmallVectorImpl<ImmutablePass *>& getImmutablePasses() {
+ return ImmutablePasses;
+ }
+
+ void addPassManager(PMDataManager *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;
+
+ // Active Pass Managers
+ PMStack activeStack;
+
+protected:
+
+ /// Collection of pass managers
+ SmallVector<PMDataManager *, 8> PassManagers;
+
+private:
+
+ /// Collection of pass managers that are not directly maintained
+ /// by this pass manager
+ SmallVector<PMDataManager *, 8> IndirectPassManagers;
+
+ // Map to keep track of last user of the analysis pass.
+ // LastUser->second is the last user of Lastuser->first.
+ DenseMap<Pass *, Pass *> 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<Pass *, SmallPtrSet<Pass *, 8> > InversedLastUser;
+
+ /// Immutable passes are managed by top level manager.
+ SmallVector<ImmutablePass *, 8> ImmutablePasses;
+
+ DenseMap<Pass *, AnalysisUsage *> AnUsageMap;
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// PMDataManager
+
+/// PMDataManager provides the common place to manage the analysis data
+/// used by pass managers.
+class PMDataManager {
+public:
+
+ explicit PMDataManager() : TPM(NULL), Depth(0) {
+ initializeAnalysisInfo();
+ }
+
+ virtual ~PMDataManager();
+
+ virtual Pass *getAsPass() = 0;
+
+ /// 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);
+
+ /// Remove Analysis that is not preserved by the pass
+ void removeNotPreservedAnalysis(Pass *P);
+
+ /// Remove dead passes used by P.
+ void removeDeadPasses(Pass *P, StringRef Msg,
+ enum PassDebuggingString);
+
+ /// Remove P.
+ void freePass(Pass *P, StringRef 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, AnalysisID PI, Function &F);
+
+ /// Initialize available analysis information.
+ void initializeAnalysisInfo() {
+ AvailableAnalysis.clear();
+ for (unsigned i = 0; i < PMT_Last; ++i)
+ InheritedAnalysis[i] = NULL;
+ }
+
+ // 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(SmallVectorImpl<Pass *> &RequiredPasses,
+ SmallVectorImpl<AnalysisID> &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
+ /// 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; }
+ void setDepth(unsigned newDepth) { Depth = newDepth; }
+
+ // Print routines used by debug-pass
+ void dumpLastUses(Pass *P, unsigned Offset) const;
+ void dumpPassArguments() const;
+ void dumpPassInfo(Pass *P, enum PassDebuggingString S1,
+ enum PassDebuggingString S2, StringRef Msg);
+ void dumpRequiredSet(const Pass *P) const;
+ void dumpPreservedSet(const Pass *P) const;
+
+ unsigned getNumContainedPasses() const {
+ return (unsigned)PassVector.size();
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ assert ( 0 && "Invalid use of getPassManagerType");
+ return PMT_Unknown;
+ }
+
+ DenseMap<AnalysisID, Pass*> *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
+ SmallVector<Pass *, 16> 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.
+ DenseMap<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last];
+
+ /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
+ /// or higher is specified.
+ bool isPassDebuggingExecutionsOrMore() const;
+
+private:
+ void dumpAnalysisUsage(StringRef 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 available then
+ // the required analysis pass is scheduled to run before the pass itself is
+ // scheduled to run.
+ DenseMap<AnalysisID, Pass*> AvailableAnalysis;
+
+ // Collection of higher level analysis used by the pass managed by
+ // this manager.
+ SmallVector<Pass *, 8> HigherLevelAnalysis;
+
+ 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:
+ static char ID;
+ explicit FPPassManager()
+ : ModulePass(ID), PMDataManager() { }
+
+ /// 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 - Overrides ModulePass doInitialization for global
+ /// initialization tasks
+ ///
+ using ModulePass::doInitialization;
+
+ /// doInitialization - Run all of the initializers for the function passes.
+ ///
+ bool doInitialization(Module &M);
+
+ /// doFinalization - Overrides ModulePass doFinalization for global
+ /// finalization tasks
+ ///
+ using ModulePass::doFinalization;
+
+ /// doFinalization - Run all of the finalizers for the function passes.
+ ///
+ bool doFinalization(Module &M);
+
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
+ /// 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);
+
+ 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<FunctionPass *>(PassVector[N]);
+ return FP;
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_FunctionPassManager;
+ }
+};
+
+Timer *getPassTimer(Pass *);
+
+}
+
+#endif
//
//===----------------------------------------------------------------------===//
//
-// This file defines the PassManager class. This class is used to hold,
-// maintain, and optimize execution of Passes. The PassManager class ensures
-// that analysis results are available before a pass runs, and that Pass's are
-// destroyed when the PassManager is destroyed.
+// This is a legacy redirect header for the old PassManager. It is intended to
+// be used by clients that have not been converted to be aware of the new pass
+// management infrastructure being built for LLVM, which is every client
+// initially. Eventually this header (and the legacy management layer) will go
+// away, but we want to minimize changes to out-of-tree users of LLVM in the
+// interim.
+//
+// Note that this header *must not* be included into the same file as the new
+// pass management infrastructure is included. Things will break spectacularly.
+// If you are starting that conversion, you should switch to explicitly
+// including LegacyPassManager.h and using the legacy namespace.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_PASSMANAGER_H
#define LLVM_PASSMANAGER_H
-#include "llvm/Pass.h"
-#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/IR/LegacyPassManager.h"
namespace llvm {
-class Pass;
-class Module;
-
-class PassManagerImpl;
-class FunctionPassManagerImpl;
-
-/// PassManagerBase - An abstract interface to allow code to add passes to
-/// a pass manager without having to hard-code what kind of pass manager
-/// it is.
-class PassManagerBase {
-public:
- virtual ~PassManagerBase();
-
- /// add - Add a pass to the queue of passes to run. This passes ownership of
- /// the Pass to the PassManager. When the PassManager is destroyed, the pass
- /// will be destroyed as well, so there is no need to delete the pass. This
- /// implies that all passes MUST be allocated with 'new'.
- virtual void add(Pass *P) = 0;
-};
-
-/// PassManager manages ModulePassManagers
-class PassManager : public PassManagerBase {
-public:
-
- PassManager();
- ~PassManager();
-
- /// add - Add a pass to the queue of passes to run. This passes ownership of
- /// the Pass to the PassManager. When the PassManager is destroyed, the pass
- /// will be destroyed as well, so there is no need to delete the pass. This
- /// implies that all passes MUST be allocated with 'new'.
- void add(Pass *P);
-
- /// 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 run(Module &M);
-
-private:
- /// PassManagerImpl_New is the actual class. PassManager is just the
- /// wraper to publish simple pass manager interface
- PassManagerImpl *PM;
-};
-
-/// FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
-class FunctionPassManager : public PassManagerBase {
-public:
- /// FunctionPassManager ctor - This initializes the pass manager. It needs,
- /// but does not take ownership of, the specified Module.
- explicit FunctionPassManager(Module *M);
- ~FunctionPassManager();
-
- /// add - Add a pass to the queue of passes to run. This passes
- /// ownership of the Pass to the PassManager. When the
- /// PassManager_X is destroyed, the pass will be destroyed as well, so
- /// there is no need to delete the pass.
- /// This implies that all passes MUST be allocated with 'new'.
- void add(Pass *P);
-
- /// run - Execute all of the passes scheduled for execution. Keep
- /// track of whether any of the passes modifies the function, and if
- /// so, return true.
- ///
- bool run(Function &F);
-
- /// doInitialization - Run all of the initializers for the function passes.
- ///
- bool doInitialization();
-
- /// doFinalization - Run all of the finalizers for the function passes.
- ///
- bool doFinalization();
-
-private:
- FunctionPassManagerImpl *FPM;
- Module *M;
-};
-
-// Create wrappers for C Binding types (see CBindingWrapping.h).
-DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef)
+// Pull these into the llvm namespace so that existing code that expects it
+// there can find it.
+using legacy::PassManagerBase;
+using legacy::PassManager;
+using legacy::FunctionPassManager;
-} // End llvm namespace
+}
#endif
+++ /dev/null
-//===- llvm/PassManagers.h - Pass Infrastructure classes -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the LLVM Pass Manager infrastructure.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_PASSMANAGERS_H
-#define LLVM_PASSMANAGERS_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Pass.h"
-#include <map>
-#include <vector>
-
-//===----------------------------------------------------------------------===//
-// 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 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.
-//
-// 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 PMTopLevelManager
-//
-// PassManagerImpl is a top level pass manager responsible for managing
-// MPPassManagers.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/PrettyStackTrace.h"
-
-namespace llvm {
- class Module;
- class Pass;
- class StringRef;
- class Value;
- class Timer;
- class PMDataManager;
-
-// 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_REGION_MSG, // " 'on Region ...\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:
- explicit 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 - This class implements a stack data structure of PMDataManager
-/// pointers.
-///
-/// 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.
-class PMStack {
-public:
- typedef std::vector<PMDataManager *>::const_reverse_iterator iterator;
- iterator begin() const { return S.rbegin(); }
- iterator end() const { return S.rend(); }
-
- void pop();
- PMDataManager *top() const { return S.back(); }
- void push(PMDataManager *PM);
- bool empty() const { return S.empty(); }
-
- void dump() const;
-
-private:
- std::vector<PMDataManager *> S;
-};
-
-
-//===----------------------------------------------------------------------===//
-// PMTopLevelManager
-//
-/// PMTopLevelManager manages LastUser info and collects common APIs used by
-/// top level pass managers.
-class PMTopLevelManager {
-protected:
- explicit PMTopLevelManager(PMDataManager *PMDM);
-
- unsigned getNumContainedManagers() const {
- return (unsigned)PassManagers.size();
- }
-
- void initializeAllAnalysisInfo();
-
-private:
- virtual PMDataManager *getAsPMDataManager() = 0;
- virtual PassManagerType getTopLevelPassManagerType() = 0;
-
-public:
- /// 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);
-
- /// Set pass P as the last user of the given analysis passes.
- void setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P);
-
- /// Collect passes whose last user is P
- void collectLastUses(SmallVectorImpl<Pass *> &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);
-
- /// Find analysis usage information for the pass P.
- AnalysisUsage *findAnalysisUsage(Pass *P);
-
- virtual ~PMTopLevelManager();
-
- /// Add immutable pass and initialize it.
- inline void addImmutablePass(ImmutablePass *P) {
- P->initializePass();
- ImmutablePasses.push_back(P);
- }
-
- inline SmallVectorImpl<ImmutablePass *>& getImmutablePasses() {
- return ImmutablePasses;
- }
-
- void addPassManager(PMDataManager *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;
-
- // Active Pass Managers
- PMStack activeStack;
-
-protected:
-
- /// Collection of pass managers
- SmallVector<PMDataManager *, 8> PassManagers;
-
-private:
-
- /// Collection of pass managers that are not directly maintained
- /// by this pass manager
- SmallVector<PMDataManager *, 8> IndirectPassManagers;
-
- // Map to keep track of last user of the analysis pass.
- // LastUser->second is the last user of Lastuser->first.
- DenseMap<Pass *, Pass *> 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<Pass *, SmallPtrSet<Pass *, 8> > InversedLastUser;
-
- /// Immutable passes are managed by top level manager.
- SmallVector<ImmutablePass *, 8> ImmutablePasses;
-
- DenseMap<Pass *, AnalysisUsage *> AnUsageMap;
-};
-
-
-
-//===----------------------------------------------------------------------===//
-// PMDataManager
-
-/// PMDataManager provides the common place to manage the analysis data
-/// used by pass managers.
-class PMDataManager {
-public:
-
- explicit PMDataManager() : TPM(NULL), Depth(0) {
- initializeAnalysisInfo();
- }
-
- virtual ~PMDataManager();
-
- virtual Pass *getAsPass() = 0;
-
- /// 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);
-
- /// Remove Analysis that is not preserved by the pass
- void removeNotPreservedAnalysis(Pass *P);
-
- /// Remove dead passes used by P.
- void removeDeadPasses(Pass *P, StringRef Msg,
- enum PassDebuggingString);
-
- /// Remove P.
- void freePass(Pass *P, StringRef 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, AnalysisID PI, Function &F);
-
- /// Initialize available analysis information.
- void initializeAnalysisInfo() {
- AvailableAnalysis.clear();
- for (unsigned i = 0; i < PMT_Last; ++i)
- InheritedAnalysis[i] = NULL;
- }
-
- // 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(SmallVectorImpl<Pass *> &RequiredPasses,
- SmallVectorImpl<AnalysisID> &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
- /// 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; }
- void setDepth(unsigned newDepth) { Depth = newDepth; }
-
- // Print routines used by debug-pass
- void dumpLastUses(Pass *P, unsigned Offset) const;
- void dumpPassArguments() const;
- void dumpPassInfo(Pass *P, enum PassDebuggingString S1,
- enum PassDebuggingString S2, StringRef Msg);
- void dumpRequiredSet(const Pass *P) const;
- void dumpPreservedSet(const Pass *P) const;
-
- unsigned getNumContainedPasses() const {
- return (unsigned)PassVector.size();
- }
-
- virtual PassManagerType getPassManagerType() const {
- assert ( 0 && "Invalid use of getPassManagerType");
- return PMT_Unknown;
- }
-
- DenseMap<AnalysisID, Pass*> *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
- SmallVector<Pass *, 16> 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.
- DenseMap<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last];
-
- /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
- /// or higher is specified.
- bool isPassDebuggingExecutionsOrMore() const;
-
-private:
- void dumpAnalysisUsage(StringRef 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 available then
- // the required analysis pass is scheduled to run before the pass itself is
- // scheduled to run.
- DenseMap<AnalysisID, Pass*> AvailableAnalysis;
-
- // Collection of higher level analysis used by the pass managed by
- // this manager.
- SmallVector<Pass *, 8> HigherLevelAnalysis;
-
- 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:
- static char ID;
- explicit FPPassManager()
- : ModulePass(ID), PMDataManager() { }
-
- /// 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 - Overrides ModulePass doInitialization for global
- /// initialization tasks
- ///
- using ModulePass::doInitialization;
-
- /// doInitialization - Run all of the initializers for the function passes.
- ///
- bool doInitialization(Module &M);
-
- /// doFinalization - Overrides ModulePass doFinalization for global
- /// finalization tasks
- ///
- using ModulePass::doFinalization;
-
- /// doFinalization - Run all of the finalizers for the function passes.
- ///
- bool doFinalization(Module &M);
-
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
-
- /// 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);
-
- 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<FunctionPass *>(PassVector[N]);
- return FP;
- }
-
- virtual PassManagerType getPassManagerType() const {
- return PMT_FunctionPassManager;
- }
-};
-
-Timer *getPassTimer(Pass *);
-
-}
-
-#endif
class MCAsmInfo;
class MCCodeGenInfo;
class MCContext;
-class PassManagerBase;
class Target;
class DataLayout;
class TargetLibraryInfo;
class formatted_raw_ostream;
class raw_ostream;
+// The old pass manager infrastructure is hidden in a legacy namespace now.
+namespace legacy {
+class PassManagerBase;
+}
+using legacy::PassManagerBase;
+
//===----------------------------------------------------------------------===//
///
/// TargetMachine - Primary interface to the complete machine description for
#include <vector>
namespace llvm {
- class TargetLibraryInfo;
- class PassManagerBase;
- class Pass;
- class FunctionPassManager;
+class TargetLibraryInfo;
+class Pass;
+
+// The old pass manager infrastructure is hidden in a legacy namespace now.
+namespace legacy {
+class PassManagerBase;
+class FunctionPassManager;
+}
+using legacy::PassManagerBase;
+using legacy::FunctionPassManager;
/// PassManagerBuilder - This class is used to set up a standard optimization
/// sequence for languages like C and C++, allowing some APIs to customize the
#include "llvm/Analysis/CallGraph.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/PassManagers.h"
+#include "llvm/IR/LegacyPassManagers.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Timer.h"
ConstantFold.cpp
Constants.cpp
Core.cpp
+ DIBuilder.cpp
DataLayout.cpp
DebugInfo.cpp
DebugLoc.cpp
- DIBuilder.cpp
Dominators.cpp
Function.cpp
GCOV.cpp
LLVMContext.cpp
LLVMContextImpl.cpp
LeakDetector.cpp
+ LegacyPassManager.cpp
Metadata.cpp
Module.cpp
Pass.cpp
- PassManager.cpp
PassRegistry.cpp
PrintModulePass.cpp
Type.cpp
--- /dev/null
+//===- LegacyPassManager.cpp - LLVM Pass Infrastructure Implementation ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the legacy LLVM Pass Manager infrastructure.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/LegacyPassManagers.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/PassNameParser.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <map>
+using namespace llvm;
+using namespace llvm::legacy;
+
+// See PassManagers.h for Pass Manager infrastructure overview.
+
+//===----------------------------------------------------------------------===//
+// Pass debugging information. Often it is useful to find out what pass is
+// running when a crash occurs in a utility. When this library is compiled with
+// debugging on, a command line option (--debug-pass) is enabled that causes the
+// pass name to be printed before it executes.
+//
+
+namespace {
+// Different debug levels that can be enabled...
+enum PassDebugLevel {
+ Disabled, Arguments, Structure, Executions, Details
+};
+}
+
+static cl::opt<enum PassDebugLevel>
+PassDebugging("debug-pass", cl::Hidden,
+ cl::desc("Print PassManager debugging information"),
+ cl::values(
+ clEnumVal(Disabled , "disable debug output"),
+ clEnumVal(Arguments , "print pass arguments to pass to 'opt'"),
+ clEnumVal(Structure , "print pass structure before run()"),
+ clEnumVal(Executions, "print pass name before it is executed"),
+ clEnumVal(Details , "print pass details when it is executed"),
+ clEnumValEnd));
+
+namespace {
+typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser>
+PassOptionList;
+}
+
+// Print IR out before/after specified passes.
+static PassOptionList
+PrintBefore("print-before",
+ llvm::cl::desc("Print IR before specified passes"),
+ cl::Hidden);
+
+static PassOptionList
+PrintAfter("print-after",
+ llvm::cl::desc("Print IR after specified passes"),
+ cl::Hidden);
+
+static cl::opt<bool>
+PrintBeforeAll("print-before-all",
+ llvm::cl::desc("Print IR before each pass"),
+ cl::init(false));
+static cl::opt<bool>
+PrintAfterAll("print-after-all",
+ llvm::cl::desc("Print IR after each pass"),
+ cl::init(false));
+
+/// This is a helper to determine whether to print IR before or
+/// after a pass.
+
+static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI,
+ PassOptionList &PassesToPrint) {
+ for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) {
+ const llvm::PassInfo *PassInf = PassesToPrint[i];
+ if (PassInf)
+ if (PassInf->getPassArgument() == PI->getPassArgument()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/// This is a utility to check whether a pass should have IR dumped
+/// before it.
+static bool ShouldPrintBeforePass(const PassInfo *PI) {
+ return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore);
+}
+
+/// This is a utility to check whether a pass should have IR dumped
+/// after it.
+static bool ShouldPrintAfterPass(const PassInfo *PI) {
+ return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter);
+}
+
+/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
+/// or higher is specified.
+bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
+ return PassDebugging >= Executions;
+}
+
+
+
+
+void PassManagerPrettyStackEntry::print(raw_ostream &OS) const {
+ if (V == 0 && M == 0)
+ OS << "Releasing pass '";
+ else
+ OS << "Running pass '";
+
+ OS << P->getPassName() << "'";
+
+ if (M) {
+ OS << " on module '" << M->getModuleIdentifier() << "'.\n";
+ return;
+ }
+ if (V == 0) {
+ OS << '\n';
+ return;
+ }
+
+ OS << " on ";
+ if (isa<Function>(V))
+ OS << "function";
+ else if (isa<BasicBlock>(V))
+ OS << "basic block";
+ else
+ OS << "value";
+
+ OS << " '";
+ WriteAsOperand(OS, V, /*PrintTy=*/false, M);
+ OS << "'\n";
+}
+
+
+namespace {
+//===----------------------------------------------------------------------===//
+// BBPassManager
+//
+/// BBPassManager manages BasicBlockPass. It batches all the
+/// pass together and sequence them to process one basic block before
+/// processing next basic block.
+class BBPassManager : public PMDataManager, public FunctionPass {
+
+public:
+ static char ID;
+ explicit BBPassManager()
+ : PMDataManager(), FunctionPass(ID) {}
+
+ /// Execute all of the passes scheduled for execution. Keep track of
+ /// whether any of the passes modifies the function, and if so, return true.
+ bool runOnFunction(Function &F);
+
+ /// Pass Manager itself does not invalidate any analysis info.
+ void getAnalysisUsage(AnalysisUsage &Info) const {
+ Info.setPreservesAll();
+ }
+
+ bool doInitialization(Module &M);
+ bool doInitialization(Function &F);
+ bool doFinalization(Module &M);
+ bool doFinalization(Function &F);
+
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
+ virtual const char *getPassName() const {
+ return "BasicBlock Pass Manager";
+ }
+
+ // Print passes managed by this manager
+ void dumpPassStructure(unsigned Offset) {
+ llvm::dbgs().indent(Offset*2) << "BasicBlockPass Manager\n";
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ BasicBlockPass *BP = getContainedPass(Index);
+ BP->dumpPassStructure(Offset + 1);
+ dumpLastUses(BP, Offset+1);
+ }
+ }
+
+ BasicBlockPass *getContainedPass(unsigned N) {
+ assert(N < PassVector.size() && "Pass number out of range!");
+ BasicBlockPass *BP = static_cast<BasicBlockPass *>(PassVector[N]);
+ return BP;
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_BasicBlockPassManager;
+ }
+};
+
+char BBPassManager::ID = 0;
+} // End anonymous namespace
+
+namespace llvm {
+namespace legacy {
+//===----------------------------------------------------------------------===//
+// FunctionPassManagerImpl
+//
+/// FunctionPassManagerImpl manages FPPassManagers
+class FunctionPassManagerImpl : public Pass,
+ public PMDataManager,
+ public PMTopLevelManager {
+ virtual void anchor();
+private:
+ bool wasRun;
+public:
+ static char ID;
+ explicit FunctionPassManagerImpl() :
+ Pass(PT_PassManager, ID), PMDataManager(),
+ PMTopLevelManager(new FPPassManager()), wasRun(false) {}
+
+ /// add - Add a pass to the queue of passes to run. This passes ownership of
+ /// the Pass to the PassManager. When the PassManager is destroyed, the pass
+ /// will be destroyed as well, so there is no need to delete the pass. This
+ /// implies that all passes MUST be allocated with 'new'.
+ void add(Pass *P) {
+ schedulePass(P);
+ }
+
+ /// createPrinterPass - Get a function printer pass.
+ Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
+ return createPrintFunctionPass(Banner, &O);
+ }
+
+ // Prepare for running an on the fly pass, freeing memory if needed
+ // from a previous run.
+ void releaseMemoryOnTheFly();
+
+ /// 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 run(Function &F);
+
+ /// doInitialization - Run all of the initializers for the function passes.
+ ///
+ bool doInitialization(Module &M);
+
+ /// doFinalization - Run all of the finalizers for the function passes.
+ ///
+ bool doFinalization(Module &M);
+
+
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+ virtual PassManagerType getTopLevelPassManagerType() {
+ return PMT_FunctionPassManager;
+ }
+
+ /// Pass Manager itself does not invalidate any analysis info.
+ void getAnalysisUsage(AnalysisUsage &Info) const {
+ Info.setPreservesAll();
+ }
+
+ FPPassManager *getContainedManager(unsigned N) {
+ assert(N < PassManagers.size() && "Pass number out of range!");
+ FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]);
+ return FP;
+ }
+};
+
+void FunctionPassManagerImpl::anchor() {}
+
+char FunctionPassManagerImpl::ID = 0;
+} // End of legacy namespace
+} // End of llvm namespace
+
+namespace {
+//===----------------------------------------------------------------------===//
+// MPPassManager
+//
+/// MPPassManager manages ModulePasses and function pass managers.
+/// It batches all Module passes and function pass managers together and
+/// sequences them to process one module.
+class MPPassManager : public Pass, public PMDataManager {
+public:
+ static char ID;
+ explicit MPPassManager() :
+ Pass(PT_PassManager, ID), PMDataManager() { }
+
+ // Delete on the fly managers.
+ virtual ~MPPassManager() {
+ for (std::map<Pass *, FunctionPassManagerImpl *>::iterator
+ I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end();
+ I != E; ++I) {
+ FunctionPassManagerImpl *FPP = I->second;
+ delete FPP;
+ }
+ }
+
+ /// createPrinterPass - Get a module printer pass.
+ Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
+ return createPrintModulePass(&O, false, Banner);
+ }
+
+ /// 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 runOnModule(Module &M);
+
+ using llvm::Pass::doInitialization;
+ using llvm::Pass::doFinalization;
+
+ /// doInitialization - Run all of the initializers for the module passes.
+ ///
+ bool doInitialization();
+
+ /// doFinalization - Run all of the finalizers for the module passes.
+ ///
+ bool doFinalization();
+
+ /// Pass Manager itself does not invalidate any analysis info.
+ void getAnalysisUsage(AnalysisUsage &Info) const {
+ Info.setPreservesAll();
+ }
+
+ /// 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);
+
+ /// Return function pass corresponding to PassInfo PI, that is
+ /// required by module pass MP. Instantiate analysis pass, by using
+ /// its runOnFunction() for function F.
+ virtual Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F);
+
+ virtual const char *getPassName() const {
+ return "Module Pass Manager";
+ }
+
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
+ // Print passes managed by this manager
+ void dumpPassStructure(unsigned Offset) {
+ llvm::dbgs().indent(Offset*2) << "ModulePass Manager\n";
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ ModulePass *MP = getContainedPass(Index);
+ MP->dumpPassStructure(Offset + 1);
+ std::map<Pass *, FunctionPassManagerImpl *>::const_iterator I =
+ OnTheFlyManagers.find(MP);
+ if (I != OnTheFlyManagers.end())
+ I->second->dumpPassStructure(Offset + 2);
+ dumpLastUses(MP, Offset+1);
+ }
+ }
+
+ ModulePass *getContainedPass(unsigned N) {
+ assert(N < PassVector.size() && "Pass number out of range!");
+ return static_cast<ModulePass *>(PassVector[N]);
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_ModulePassManager;
+ }
+
+ private:
+ /// Collection of on the fly FPPassManagers. These managers manage
+ /// function passes that are required by module passes.
+ std::map<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers;
+};
+
+char MPPassManager::ID = 0;
+} // End anonymous namespace
+
+namespace llvm {
+namespace legacy {
+//===----------------------------------------------------------------------===//
+// PassManagerImpl
+//
+
+/// PassManagerImpl manages MPPassManagers
+class PassManagerImpl : public Pass,
+ public PMDataManager,
+ public PMTopLevelManager {
+ virtual void anchor();
+
+public:
+ static char ID;
+ explicit PassManagerImpl() :
+ Pass(PT_PassManager, ID), PMDataManager(),
+ PMTopLevelManager(new MPPassManager()) {}
+
+ /// add - Add a pass to the queue of passes to run. This passes ownership of
+ /// the Pass to the PassManager. When the PassManager is destroyed, the pass
+ /// will be destroyed as well, so there is no need to delete the pass. This
+ /// implies that all passes MUST be allocated with 'new'.
+ void add(Pass *P) {
+ schedulePass(P);
+ }
+
+ /// createPrinterPass - Get a module printer pass.
+ Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
+ return createPrintModulePass(&O, false, Banner);
+ }
+
+ /// 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 run(Module &M);
+
+ using llvm::Pass::doInitialization;
+ using llvm::Pass::doFinalization;
+
+ /// doInitialization - Run all of the initializers for the module passes.
+ ///
+ bool doInitialization();
+
+ /// doFinalization - Run all of the finalizers for the module passes.
+ ///
+ bool doFinalization();
+
+ /// Pass Manager itself does not invalidate any analysis info.
+ void getAnalysisUsage(AnalysisUsage &Info) const {
+ Info.setPreservesAll();
+ }
+
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+ virtual PassManagerType getTopLevelPassManagerType() {
+ return PMT_ModulePassManager;
+ }
+
+ MPPassManager *getContainedManager(unsigned N) {
+ assert(N < PassManagers.size() && "Pass number out of range!");
+ MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]);
+ return MP;
+ }
+};
+
+void PassManagerImpl::anchor() {}
+
+char PassManagerImpl::ID = 0;
+} // End of legacy namespace
+} // End of llvm namespace
+
+namespace {
+
+//===----------------------------------------------------------------------===//
+/// 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.
+///
+
+static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex;
+
+class TimingInfo {
+ DenseMap<Pass*, Timer*> 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, which accumulate their info into the
+ // TimerGroup.
+ for (DenseMap<Pass*, Timer*>::iterator I = TimingData.begin(),
+ E = TimingData.end(); I != E; ++I)
+ delete I->second;
+ // 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();
+
+ /// getPassTimer - Return the timer for the specified pass if it exists.
+ Timer *getPassTimer(Pass *P) {
+ if (P->getAsPMDataManager())
+ return 0;
+
+ sys::SmartScopedLock<true> Lock(*TimingInfoMutex);
+ Timer *&T = TimingData[P];
+ if (T == 0)
+ T = new Timer(P->getPassName(), TG);
+ return T;
+ }
+};
+
+} // End of anon namespace
+
+static TimingInfo *TheTimeInfo;
+
+//===----------------------------------------------------------------------===//
+// PMTopLevelManager implementation
+
+/// Initialize top level manager. Create first pass manager.
+PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) {
+ PMDM->setTopLevelManager(this);
+ addPassManager(PMDM);
+ activeStack.push(PMDM);
+}
+
+/// Set pass P as the last user of the given analysis passes.
+void
+PMTopLevelManager::setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P) {
+ unsigned PDepth = 0;
+ if (P->getResolver())
+ PDepth = P->getResolver()->getPMDataManager().getDepth();
+
+ for (SmallVectorImpl<Pass *>::const_iterator I = AnalysisPasses.begin(),
+ E = AnalysisPasses.end(); I != E; ++I) {
+ Pass *AP = *I;
+ LastUser[AP] = P;
+
+ if (P == AP)
+ continue;
+
+ // Update the last users of passes that are required transitive by AP.
+ AnalysisUsage *AnUsage = findAnalysisUsage(AP);
+ const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet();
+ SmallVector<Pass *, 12> LastUses;
+ SmallVector<Pass *, 12> LastPMUses;
+ for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(),
+ E = IDs.end(); I != E; ++I) {
+ Pass *AnalysisPass = findAnalysisPass(*I);
+ assert(AnalysisPass && "Expected analysis pass to exist.");
+ AnalysisResolver *AR = AnalysisPass->getResolver();
+ assert(AR && "Expected analysis resolver to exist.");
+ unsigned APDepth = AR->getPMDataManager().getDepth();
+
+ if (PDepth == APDepth)
+ LastUses.push_back(AnalysisPass);
+ else if (PDepth > APDepth)
+ LastPMUses.push_back(AnalysisPass);
+ }
+
+ setLastUser(LastUses, P);
+
+ // If this pass has a corresponding pass manager, push higher level
+ // analysis to this pass manager.
+ if (P->getResolver())
+ setLastUser(LastPMUses, P->getResolver()->getPMDataManager().getAsPass());
+
+
+ // If AP is the last user of other passes then make P last user of
+ // such passes.
+ for (DenseMap<Pass *, Pass *>::iterator LUI = LastUser.begin(),
+ LUE = LastUser.end(); LUI != LUE; ++LUI) {
+ if (LUI->second == AP)
+ // DenseMap iterator is not invalidated here because
+ // this is just updating existing entries.
+ LastUser[LUI->first] = P;
+ }
+ }
+}
+
+/// Collect passes whose last user is P
+void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses,
+ Pass *P) {
+ DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator DMI =
+ InversedLastUser.find(P);
+ if (DMI == InversedLastUser.end())
+ return;
+
+ SmallPtrSet<Pass *, 8> &LU = DMI->second;
+ for (SmallPtrSet<Pass *, 8>::iterator I = LU.begin(),
+ E = LU.end(); I != E; ++I) {
+ LastUses.push_back(*I);
+ }
+
+}
+
+AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) {
+ AnalysisUsage *AnUsage = NULL;
+ DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P);
+ if (DMI != AnUsageMap.end())
+ AnUsage = DMI->second;
+ else {
+ AnUsage = new AnalysisUsage();
+ P->getAnalysisUsage(*AnUsage);
+ AnUsageMap[P] = AnUsage;
+ }
+ return AnUsage;
+}
+
+/// 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 PMTopLevelManager::schedulePass(Pass *P) {
+
+ // TODO : Allocate function manager for this pass, other wise required set
+ // may be inserted into previous function manager
+
+ // Give pass a chance to prepare the stage.
+ P->preparePassManager(activeStack);
+
+ // If P is an analysis pass and it is available then do not
+ // generate the analysis again. Stale analysis info should not be
+ // available at this point.
+ const PassInfo *PI =
+ PassRegistry::getPassRegistry()->getPassInfo(P->getPassID());
+ if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) {
+ delete P;
+ return;
+ }
+
+ AnalysisUsage *AnUsage = findAnalysisUsage(P);
+
+ bool checkAnalysis = true;
+ while (checkAnalysis) {
+ checkAnalysis = false;
+
+ const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
+ for (AnalysisUsage::VectorType::const_iterator I = RequiredSet.begin(),
+ E = RequiredSet.end(); I != E; ++I) {
+
+ Pass *AnalysisPass = findAnalysisPass(*I);
+ if (!AnalysisPass) {
+ const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
+
+ if (PI == NULL) {
+ // Pass P is not in the global PassRegistry
+ dbgs() << "Pass '" << P->getPassName() << "' is not initialized." << "\n";
+ dbgs() << "Verify if there is a pass dependency cycle." << "\n";
+ dbgs() << "Required Passes:" << "\n";
+ for (AnalysisUsage::VectorType::const_iterator I2 = RequiredSet.begin(),
+ E = RequiredSet.end(); I2 != E && I2 != I; ++I2) {
+ Pass *AnalysisPass2 = findAnalysisPass(*I2);
+ if (AnalysisPass2) {
+ dbgs() << "\t" << AnalysisPass2->getPassName() << "\n";
+ } else {
+ dbgs() << "\t" << "Error: Required pass not found! Possible causes:" << "\n";
+ dbgs() << "\t\t" << "- Pass misconfiguration (e.g.: missing macros)" << "\n";
+ dbgs() << "\t\t" << "- Corruption of the global PassRegistry" << "\n";
+ }
+ }
+ }
+
+ assert(PI && "Expected required passes to be initialized");
+ AnalysisPass = PI->createPass();
+ if (P->getPotentialPassManagerType () ==
+ AnalysisPass->getPotentialPassManagerType())
+ // Schedule analysis pass that is managed by the same pass manager.
+ schedulePass(AnalysisPass);
+ else if (P->getPotentialPassManagerType () >
+ AnalysisPass->getPotentialPassManagerType()) {
+ // Schedule analysis pass that is managed by a new manager.
+ schedulePass(AnalysisPass);
+ // Recheck analysis passes to ensure that required analyses that
+ // are already checked are still available.
+ checkAnalysis = true;
+ } else
+ // Do not schedule this analysis. Lower level analsyis
+ // passes are run on the fly.
+ delete AnalysisPass;
+ }
+ }
+ }
+
+ // Now all required passes are available.
+ if (ImmutablePass *IP = P->getAsImmutablePass()) {
+ // P is a immutable pass and it will be managed by this
+ // top level manager. Set up analysis resolver to connect them.
+ PMDataManager *DM = getAsPMDataManager();
+ AnalysisResolver *AR = new AnalysisResolver(*DM);
+ P->setResolver(AR);
+ DM->initializeAnalysisImpl(P);
+ addImmutablePass(IP);
+ DM->recordAvailableAnalysis(IP);
+ return;
+ }
+
+ if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) {
+ Pass *PP = P->createPrinterPass(
+ dbgs(), std::string("*** IR Dump Before ") + P->getPassName() + " ***");
+ PP->assignPassManager(activeStack, getTopLevelPassManagerType());
+ }
+
+ // Add the requested pass to the best available pass manager.
+ P->assignPassManager(activeStack, getTopLevelPassManagerType());
+
+ if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) {
+ Pass *PP = P->createPrinterPass(
+ dbgs(), std::string("*** IR Dump After ") + P->getPassName() + " ***");
+ PP->assignPassManager(activeStack, getTopLevelPassManagerType());
+ }
+}
+
+/// Find the pass that implements Analysis AID. Search immutable
+/// passes and all pass managers. If desired pass is not found
+/// then return NULL.
+Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
+
+ // Check pass managers
+ for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(),
+ E = PassManagers.end(); I != E; ++I)
+ if (Pass *P = (*I)->findAnalysisPass(AID, false))
+ return P;
+
+ // Check other pass managers
+ for (SmallVectorImpl<PMDataManager *>::iterator
+ I = IndirectPassManagers.begin(),
+ E = IndirectPassManagers.end(); I != E; ++I)
+ if (Pass *P = (*I)->findAnalysisPass(AID, false))
+ return P;
+
+ // Check the immutable passes. Iterate in reverse order so that we find
+ // the most recently registered passes first.
+ for (SmallVectorImpl<ImmutablePass *>::reverse_iterator I =
+ ImmutablePasses.rbegin(), E = ImmutablePasses.rend(); I != E; ++I) {
+ AnalysisID PI = (*I)->getPassID();
+ if (PI == AID)
+ return *I;
+
+ // If Pass not found then check the interfaces implemented by Immutable Pass
+ const PassInfo *PassInf =
+ PassRegistry::getPassRegistry()->getPassInfo(PI);
+ assert(PassInf && "Expected all immutable passes to be initialized");
+ const std::vector<const PassInfo*> &ImmPI =
+ PassInf->getInterfacesImplemented();
+ for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(),
+ EE = ImmPI.end(); II != EE; ++II) {
+ if ((*II)->getTypeInfo() == AID)
+ return *I;
+ }
+ }
+
+ return 0;
+}
+
+// Print passes managed by this top level manager.
+void PMTopLevelManager::dumpPasses() const {
+
+ if (PassDebugging < Structure)
+ return;
+
+ // Print out the immutable passes
+ for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) {
+ ImmutablePasses[i]->dumpPassStructure(0);
+ }
+
+ // Every class that derives from PMDataManager also derives from Pass
+ // (sometimes indirectly), but there's no inheritance relationship
+ // between PMDataManager and Pass, so we have to getAsPass to get
+ // from a PMDataManager* to a Pass*.
+ for (SmallVectorImpl<PMDataManager *>::const_iterator I =
+ PassManagers.begin(), E = PassManagers.end(); I != E; ++I)
+ (*I)->getAsPass()->dumpPassStructure(1);
+}
+
+void PMTopLevelManager::dumpArguments() const {
+
+ if (PassDebugging < Arguments)
+ return;
+
+ dbgs() << "Pass Arguments: ";
+ for (SmallVectorImpl<ImmutablePass *>::const_iterator I =
+ ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
+ if (const PassInfo *PI =
+ PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) {
+ assert(PI && "Expected all immutable passes to be initialized");
+ if (!PI->isAnalysisGroup())
+ dbgs() << " -" << PI->getPassArgument();
+ }
+ for (SmallVectorImpl<PMDataManager *>::const_iterator I =
+ PassManagers.begin(), E = PassManagers.end(); I != E; ++I)
+ (*I)->dumpPassArguments();
+ dbgs() << "\n";
+}
+
+void PMTopLevelManager::initializeAllAnalysisInfo() {
+ for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(),
+ E = PassManagers.end(); I != E; ++I)
+ (*I)->initializeAnalysisInfo();
+
+ // Initailize other pass managers
+ for (SmallVectorImpl<PMDataManager *>::iterator
+ I = IndirectPassManagers.begin(), E = IndirectPassManagers.end();
+ I != E; ++I)
+ (*I)->initializeAnalysisInfo();
+
+ for (DenseMap<Pass *, Pass *>::iterator DMI = LastUser.begin(),
+ DME = LastUser.end(); DMI != DME; ++DMI) {
+ DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator InvDMI =
+ InversedLastUser.find(DMI->second);
+ if (InvDMI != InversedLastUser.end()) {
+ SmallPtrSet<Pass *, 8> &L = InvDMI->second;
+ L.insert(DMI->first);
+ } else {
+ SmallPtrSet<Pass *, 8> L; L.insert(DMI->first);
+ InversedLastUser[DMI->second] = L;
+ }
+ }
+}
+
+/// Destructor
+PMTopLevelManager::~PMTopLevelManager() {
+ for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(),
+ E = PassManagers.end(); I != E; ++I)
+ delete *I;
+
+ for (SmallVectorImpl<ImmutablePass *>::iterator
+ I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
+ delete *I;
+
+ for (DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.begin(),
+ DME = AnUsageMap.end(); DMI != DME; ++DMI)
+ delete DMI->second;
+}
+
+//===----------------------------------------------------------------------===//
+// PMDataManager implementation
+
+/// Augement AvailableAnalysis by adding analysis made available by pass P.
+void PMDataManager::recordAvailableAnalysis(Pass *P) {
+ AnalysisID PI = P->getPassID();
+
+ AvailableAnalysis[PI] = P;
+
+ assert(!AvailableAnalysis.empty());
+
+ // This pass is the current implementation of all of the interfaces it
+ // implements as well.
+ const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI);
+ if (PInf == 0) return;
+ const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented();
+ for (unsigned i = 0, e = II.size(); i != e; ++i)
+ AvailableAnalysis[II[i]->getTypeInfo()] = P;
+}
+
+// Return true if P preserves high level analysis used by other
+// passes managed by this manager
+bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) {
+ AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
+ if (AnUsage->getPreservesAll())
+ return true;
+
+ const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
+ for (SmallVectorImpl<Pass *>::iterator I = HigherLevelAnalysis.begin(),
+ E = HigherLevelAnalysis.end(); I != E; ++I) {
+ Pass *P1 = *I;
+ if (P1->getAsImmutablePass() == 0 &&
+ std::find(PreservedSet.begin(), PreservedSet.end(),
+ P1->getPassID()) ==
+ PreservedSet.end())
+ return false;
+ }
+
+ return true;
+}
+
+/// verifyPreservedAnalysis -- Verify analysis preserved by pass P.
+void PMDataManager::verifyPreservedAnalysis(Pass *P) {
+ // Don't do this unless assertions are enabled.
+#ifdef NDEBUG
+ return;
+#endif
+ AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
+ const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
+
+ // Verify preserved analysis
+ for (AnalysisUsage::VectorType::const_iterator I = PreservedSet.begin(),
+ E = PreservedSet.end(); I != E; ++I) {
+ AnalysisID AID = *I;
+ if (Pass *AP = findAnalysisPass(AID, true)) {
+ TimeRegion PassTimer(getPassTimer(AP));
+ AP->verifyAnalysis();
+ }
+ }
+}
+
+/// Remove Analysis not preserved by Pass P
+void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
+ AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
+ if (AnUsage->getPreservesAll())
+ return;
+
+ const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
+ for (DenseMap<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(),
+ E = AvailableAnalysis.end(); I != E; ) {
+ DenseMap<AnalysisID, Pass*>::iterator Info = I++;
+ if (Info->second->getAsImmutablePass() == 0 &&
+ std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
+ PreservedSet.end()) {
+ // Remove this analysis
+ if (PassDebugging >= Details) {
+ Pass *S = Info->second;
+ dbgs() << " -- '" << P->getPassName() << "' is not preserving '";
+ dbgs() << S->getPassName() << "'\n";
+ }
+ AvailableAnalysis.erase(Info);
+ }
+ }
+
+ // Check inherited analysis also. If P is not preserving analysis
+ // provided by parent manager then remove it here.
+ for (unsigned Index = 0; Index < PMT_Last; ++Index) {
+
+ if (!InheritedAnalysis[Index])
+ continue;
+
+ for (DenseMap<AnalysisID, Pass*>::iterator
+ I = InheritedAnalysis[Index]->begin(),
+ E = InheritedAnalysis[Index]->end(); I != E; ) {
+ DenseMap<AnalysisID, Pass *>::iterator Info = I++;
+ if (Info->second->getAsImmutablePass() == 0 &&
+ std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
+ PreservedSet.end()) {
+ // Remove this analysis
+ if (PassDebugging >= Details) {
+ Pass *S = Info->second;
+ dbgs() << " -- '" << P->getPassName() << "' is not preserving '";
+ dbgs() << S->getPassName() << "'\n";
+ }
+ InheritedAnalysis[Index]->erase(Info);
+ }
+ }
+ }
+}
+
+/// Remove analysis passes that are not used any longer
+void PMDataManager::removeDeadPasses(Pass *P, StringRef Msg,
+ enum PassDebuggingString DBG_STR) {
+
+ SmallVector<Pass *, 12> DeadPasses;
+
+ // If this is a on the fly manager then it does not have TPM.
+ if (!TPM)
+ return;
+
+ TPM->collectLastUses(DeadPasses, P);
+
+ if (PassDebugging >= Details && !DeadPasses.empty()) {
+ dbgs() << " -*- '" << P->getPassName();
+ dbgs() << "' is the last user of following pass instances.";
+ dbgs() << " Free these instances\n";
+ }
+
+ for (SmallVectorImpl<Pass *>::iterator I = DeadPasses.begin(),
+ E = DeadPasses.end(); I != E; ++I)
+ freePass(*I, Msg, DBG_STR);
+}
+
+void PMDataManager::freePass(Pass *P, StringRef Msg,
+ enum PassDebuggingString DBG_STR) {
+ dumpPassInfo(P, FREEING_MSG, DBG_STR, Msg);
+
+ {
+ // If the pass crashes releasing memory, remember this.
+ PassManagerPrettyStackEntry X(P);
+ TimeRegion PassTimer(getPassTimer(P));
+
+ P->releaseMemory();
+ }
+
+ AnalysisID PI = P->getPassID();
+ if (const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI)) {
+ // Remove the pass itself (if it is not already removed).
+ AvailableAnalysis.erase(PI);
+
+ // Remove all interfaces this pass implements, for which it is also
+ // listed as the available implementation.
+ const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented();
+ for (unsigned i = 0, e = II.size(); i != e; ++i) {
+ DenseMap<AnalysisID, Pass*>::iterator Pos =
+ AvailableAnalysis.find(II[i]->getTypeInfo());
+ if (Pos != AvailableAnalysis.end() && Pos->second == P)
+ AvailableAnalysis.erase(Pos);
+ }
+ }
+}
+
+/// Add pass P into the PassVector. Update
+/// AvailableAnalysis appropriately if ProcessAnalysis is true.
+void PMDataManager::add(Pass *P, bool ProcessAnalysis) {
+ // This manager is going to manage pass P. Set up analysis resolver
+ // to connect them.
+ AnalysisResolver *AR = new AnalysisResolver(*this);
+ P->setResolver(AR);
+
+ // 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.
+ SmallVector<Pass *, 12> TransferLastUses;
+
+ if (!ProcessAnalysis) {
+ // Add pass
+ PassVector.push_back(P);
+ return;
+ }
+
+ // At the moment, this pass is the last user of all required passes.
+ SmallVector<Pass *, 12> LastUses;
+ SmallVector<Pass *, 8> RequiredPasses;
+ SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable;
+
+ unsigned PDepth = this->getDepth();
+
+ collectRequiredAnalysis(RequiredPasses,
+ ReqAnalysisNotAvailable, P);
+ for (SmallVectorImpl<Pass *>::iterator I = RequiredPasses.begin(),
+ E = RequiredPasses.end(); I != E; ++I) {
+ Pass *PRequired = *I;
+ unsigned RDepth = 0;
+
+ assert(PRequired->getResolver() && "Analysis Resolver is not set");
+ PMDataManager &DM = PRequired->getResolver()->getPMDataManager();
+ RDepth = DM.getDepth();
+
+ if (PDepth == RDepth)
+ LastUses.push_back(PRequired);
+ else if (PDepth > RDepth) {
+ // Let the parent claim responsibility of last use
+ TransferLastUses.push_back(PRequired);
+ // Keep track of higher level analysis used by this manager.
+ HigherLevelAnalysis.push_back(PRequired);
+ } else
+ llvm_unreachable("Unable to accommodate Required Pass");
+ }
+
+ // Set P as P's last user until someone starts using P.
+ // However, if P is a Pass Manager then it does not need
+ // to record its last user.
+ if (P->getAsPMDataManager() == 0)
+ LastUses.push_back(P);
+ TPM->setLastUser(LastUses, P);
+
+ if (!TransferLastUses.empty()) {
+ Pass *My_PM = getAsPass();
+ TPM->setLastUser(TransferLastUses, My_PM);
+ TransferLastUses.clear();
+ }
+
+ // Now, take care of required analyses that are not available.
+ for (SmallVectorImpl<AnalysisID>::iterator
+ I = ReqAnalysisNotAvailable.begin(),
+ E = ReqAnalysisNotAvailable.end() ;I != E; ++I) {
+ const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
+ Pass *AnalysisPass = PI->createPass();
+ this->addLowerLevelRequiredPass(P, AnalysisPass);
+ }
+
+ // Take a note of analysis required and made available by this pass.
+ // Remove the analysis not preserved by this pass
+ removeNotPreservedAnalysis(P);
+ recordAvailableAnalysis(P);
+
+ // Add pass
+ PassVector.push_back(P);
+}
+
+
+/// Populate RP with analysis pass that are required by
+/// pass P and are available. Populate RP_NotAvail with analysis
+/// pass that are required by pass P but are not available.
+void PMDataManager::collectRequiredAnalysis(SmallVectorImpl<Pass *> &RP,
+ SmallVectorImpl<AnalysisID> &RP_NotAvail,
+ Pass *P) {
+ AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
+ const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
+ for (AnalysisUsage::VectorType::const_iterator
+ I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) {
+ if (Pass *AnalysisPass = findAnalysisPass(*I, true))
+ RP.push_back(AnalysisPass);
+ else
+ RP_NotAvail.push_back(*I);
+ }
+
+ const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet();
+ for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(),
+ E = IDs.end(); I != E; ++I) {
+ if (Pass *AnalysisPass = findAnalysisPass(*I, true))
+ RP.push_back(AnalysisPass);
+ else
+ RP_NotAvail.push_back(*I);
+ }
+}
+
+// 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 PMDataManager::initializeAnalysisImpl(Pass *P) {
+ AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
+
+ for (AnalysisUsage::VectorType::const_iterator
+ I = AnUsage->getRequiredSet().begin(),
+ E = AnUsage->getRequiredSet().end(); I != E; ++I) {
+ Pass *Impl = findAnalysisPass(*I, true);
+ if (Impl == 0)
+ // This may be analysis pass that is initialized on the fly.
+ // If that is not the case then it will raise an assert when it is used.
+ continue;
+ AnalysisResolver *AR = P->getResolver();
+ assert(AR && "Analysis Resolver is not set");
+ AR->addAnalysisImplsPair(*I, Impl);
+ }
+}
+
+/// Find the pass that implements Analysis AID. If desired pass is not found
+/// then return NULL.
+Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) {
+
+ // Check if AvailableAnalysis map has one entry.
+ DenseMap<AnalysisID, Pass*>::const_iterator I = AvailableAnalysis.find(AID);
+
+ if (I != AvailableAnalysis.end())
+ return I->second;
+
+ // Search Parents through TopLevelManager
+ if (SearchParent)
+ return TPM->findAnalysisPass(AID);
+
+ return NULL;
+}
+
+// Print list of passes that are last used by P.
+void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{
+
+ SmallVector<Pass *, 12> LUses;
+
+ // If this is a on the fly manager then it does not have TPM.
+ if (!TPM)
+ return;
+
+ TPM->collectLastUses(LUses, P);
+
+ for (SmallVectorImpl<Pass *>::iterator I = LUses.begin(),
+ E = LUses.end(); I != E; ++I) {
+ llvm::dbgs() << "--" << std::string(Offset*2, ' ');
+ (*I)->dumpPassStructure(0);
+ }
+}
+
+void PMDataManager::dumpPassArguments() const {
+ for (SmallVectorImpl<Pass *>::const_iterator I = PassVector.begin(),
+ E = PassVector.end(); I != E; ++I) {
+ if (PMDataManager *PMD = (*I)->getAsPMDataManager())
+ PMD->dumpPassArguments();
+ else
+ if (const PassInfo *PI =
+ PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID()))
+ if (!PI->isAnalysisGroup())
+ dbgs() << " -" << PI->getPassArgument();
+ }
+}
+
+void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1,
+ enum PassDebuggingString S2,
+ StringRef Msg) {
+ if (PassDebugging < Executions)
+ return;
+ dbgs() << (void*)this << std::string(getDepth()*2+1, ' ');
+ switch (S1) {
+ case EXECUTION_MSG:
+ dbgs() << "Executing Pass '" << P->getPassName();
+ break;
+ case MODIFICATION_MSG:
+ dbgs() << "Made Modification '" << P->getPassName();
+ break;
+ case FREEING_MSG:
+ dbgs() << " Freeing Pass '" << P->getPassName();
+ break;
+ default:
+ break;
+ }
+ switch (S2) {
+ case ON_BASICBLOCK_MSG:
+ dbgs() << "' on BasicBlock '" << Msg << "'...\n";
+ break;
+ case ON_FUNCTION_MSG:
+ dbgs() << "' on Function '" << Msg << "'...\n";
+ break;
+ case ON_MODULE_MSG:
+ dbgs() << "' on Module '" << Msg << "'...\n";
+ break;
+ case ON_REGION_MSG:
+ dbgs() << "' on Region '" << Msg << "'...\n";
+ break;
+ case ON_LOOP_MSG:
+ dbgs() << "' on Loop '" << Msg << "'...\n";
+ break;
+ case ON_CG_MSG:
+ dbgs() << "' on Call Graph Nodes '" << Msg << "'...\n";
+ break;
+ default:
+ break;
+ }
+}
+
+void PMDataManager::dumpRequiredSet(const Pass *P) const {
+ if (PassDebugging < Details)
+ return;
+
+ AnalysisUsage analysisUsage;
+ P->getAnalysisUsage(analysisUsage);
+ dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet());
+}
+
+void PMDataManager::dumpPreservedSet(const Pass *P) const {
+ if (PassDebugging < Details)
+ return;
+
+ AnalysisUsage analysisUsage;
+ P->getAnalysisUsage(analysisUsage);
+ dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet());
+}
+
+void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
+ const AnalysisUsage::VectorType &Set) const {
+ assert(PassDebugging >= Details);
+ if (Set.empty())
+ return;
+ dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:";
+ for (unsigned i = 0; i != Set.size(); ++i) {
+ if (i) dbgs() << ',';
+ const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(Set[i]);
+ if (!PInf) {
+ // Some preserved passes, such as AliasAnalysis, may not be initialized by
+ // all drivers.
+ dbgs() << " Uninitialized Pass";
+ continue;
+ }
+ dbgs() << ' ' << PInf->getPassName();
+ }
+ dbgs() << '\n';
+}
+
+/// 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.
+/// This should be handled by specific pass manager.
+void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
+ if (TPM) {
+ TPM->dumpArguments();
+ TPM->dumpPasses();
+ }
+
+ // Module Level pass may required Function Level analysis info
+ // (e.g. dominator info). Pass manager uses on the fly function pass manager
+ // to provide this on demand. In that case, in Pass manager terminology,
+ // module level pass is requiring lower level analysis info managed by
+ // lower level pass manager.
+
+ // When Pass manager is not able to order required analysis info, Pass manager
+ // checks whether any lower level manager will be able to provide this
+ // analysis info on demand or not.
+#ifndef NDEBUG
+ dbgs() << "Unable to schedule '" << RequiredPass->getPassName();
+ dbgs() << "' required by '" << P->getPassName() << "'\n";
+#endif
+ llvm_unreachable("Unable to schedule pass");
+}
+
+Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) {
+ llvm_unreachable("Unable to find on the fly pass");
+}
+
+// Destructor
+PMDataManager::~PMDataManager() {
+ for (SmallVectorImpl<Pass *>::iterator I = PassVector.begin(),
+ E = PassVector.end(); I != E; ++I)
+ delete *I;
+}
+
+//===----------------------------------------------------------------------===//
+// NOTE: Is this the right place to define this method ?
+// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist.
+Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const {
+ return PM.findAnalysisPass(ID, dir);
+}
+
+Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI,
+ Function &F) {
+ return PM.getOnTheFlyPass(P, AnalysisPI, F);
+}
+
+//===----------------------------------------------------------------------===//
+// BBPassManager implementation
+
+/// Execute all of the passes scheduled for execution by invoking
+/// runOnBasicBlock method. Keep track of whether any of the passes modifies
+/// the function, and if so, return true.
+bool BBPassManager::runOnFunction(Function &F) {
+ if (F.isDeclaration())
+ return false;
+
+ bool Changed = doInitialization(F);
+
+ for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ BasicBlockPass *BP = getContainedPass(Index);
+ bool LocalChanged = false;
+
+ dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName());
+ dumpRequiredSet(BP);
+
+ initializeAnalysisImpl(BP);
+
+ {
+ // If the pass crashes, remember this.
+ PassManagerPrettyStackEntry X(BP, *I);
+ TimeRegion PassTimer(getPassTimer(BP));
+
+ LocalChanged |= BP->runOnBasicBlock(*I);
+ }
+
+ Changed |= LocalChanged;
+ if (LocalChanged)
+ dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
+ I->getName());
+ dumpPreservedSet(BP);
+
+ verifyPreservedAnalysis(BP);
+ removeNotPreservedAnalysis(BP);
+ recordAvailableAnalysis(BP);
+ removeDeadPasses(BP, I->getName(), ON_BASICBLOCK_MSG);
+ }
+
+ return doFinalization(F) || Changed;
+}
+
+// Implement doInitialization and doFinalization
+bool BBPassManager::doInitialization(Module &M) {
+ bool Changed = false;
+
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
+ Changed |= getContainedPass(Index)->doInitialization(M);
+
+ return Changed;
+}
+
+bool BBPassManager::doFinalization(Module &M) {
+ bool Changed = false;
+
+ for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
+ Changed |= getContainedPass(Index)->doFinalization(M);
+
+ return Changed;
+}
+
+bool BBPassManager::doInitialization(Function &F) {
+ bool Changed = false;
+
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ BasicBlockPass *BP = getContainedPass(Index);
+ Changed |= BP->doInitialization(F);
+ }
+
+ return Changed;
+}
+
+bool BBPassManager::doFinalization(Function &F) {
+ bool Changed = false;
+
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ BasicBlockPass *BP = getContainedPass(Index);
+ Changed |= BP->doFinalization(F);
+ }
+
+ return Changed;
+}
+
+
+//===----------------------------------------------------------------------===//
+// FunctionPassManager implementation
+
+/// Create new Function pass manager
+FunctionPassManager::FunctionPassManager(Module *m) : M(m) {
+ FPM = new FunctionPassManagerImpl();
+ // FPM is the top level manager.
+ FPM->setTopLevelManager(FPM);
+
+ AnalysisResolver *AR = new AnalysisResolver(*FPM);
+ FPM->setResolver(AR);
+}
+
+FunctionPassManager::~FunctionPassManager() {
+ delete FPM;
+}
+
+/// add - Add a pass to the queue of passes to run. This passes
+/// ownership of the Pass to the PassManager. When the
+/// PassManager_X is destroyed, the pass will be destroyed as well, so
+/// there is no need to delete the pass. (TODO delete passes.)
+/// This implies that all passes MUST be allocated with 'new'.
+void FunctionPassManager::add(Pass *P) {
+ FPM->add(P);
+}
+
+/// run - Execute all of the passes scheduled for execution. Keep
+/// track of whether any of the passes modifies the function, and if
+/// so, return true.
+///
+bool FunctionPassManager::run(Function &F) {
+ if (F.isMaterializable()) {
+ std::string errstr;
+ if (F.Materialize(&errstr))
+ report_fatal_error("Error reading bitcode file: " + Twine(errstr));
+ }
+ return FPM->run(F);
+}
+
+
+/// doInitialization - Run all of the initializers for the function passes.
+///
+bool FunctionPassManager::doInitialization() {
+ return FPM->doInitialization(*M);
+}
+
+/// doFinalization - Run all of the finalizers for the function passes.
+///
+bool FunctionPassManager::doFinalization() {
+ return FPM->doFinalization(*M);
+}
+
+//===----------------------------------------------------------------------===//
+// FunctionPassManagerImpl implementation
+//
+bool FunctionPassManagerImpl::doInitialization(Module &M) {
+ bool Changed = false;
+
+ dumpArguments();
+ dumpPasses();
+
+ SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
+ for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
+ E = IPV.end(); I != E; ++I) {
+ Changed |= (*I)->doInitialization(M);
+ }
+
+ for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
+ Changed |= getContainedManager(Index)->doInitialization(M);
+
+ return Changed;
+}
+
+bool FunctionPassManagerImpl::doFinalization(Module &M) {
+ bool Changed = false;
+
+ for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index)
+ Changed |= getContainedManager(Index)->doFinalization(M);
+
+ SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
+ for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
+ E = IPV.end(); I != E; ++I) {
+ Changed |= (*I)->doFinalization(M);
+ }
+
+ return Changed;
+}
+
+/// cleanup - After running all passes, clean up pass manager cache.
+void FPPassManager::cleanup() {
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ FunctionPass *FP = getContainedPass(Index);
+ AnalysisResolver *AR = FP->getResolver();
+ assert(AR && "Analysis Resolver is not set");
+ AR->clearAnalysisImpls();
+ }
+}
+
+void FunctionPassManagerImpl::releaseMemoryOnTheFly() {
+ if (!wasRun)
+ return;
+ for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
+ FPPassManager *FPPM = getContainedManager(Index);
+ for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) {
+ FPPM->getContainedPass(Index)->releaseMemory();
+ }
+ }
+ wasRun = false;
+}
+
+// Execute all the passes managed by this top level manager.
+// Return true if any function is modified by a pass.
+bool FunctionPassManagerImpl::run(Function &F) {
+ bool Changed = false;
+ TimingInfo::createTheTimeInfo();
+
+ initializeAllAnalysisInfo();
+ for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
+ Changed |= getContainedManager(Index)->runOnFunction(F);
+
+ for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
+ getContainedManager(Index)->cleanup();
+
+ wasRun = true;
+ return Changed;
+}
+
+//===----------------------------------------------------------------------===//
+// FPPassManager implementation
+
+char FPPassManager::ID = 0;
+/// Print passes managed by this manager
+void FPPassManager::dumpPassStructure(unsigned Offset) {
+ dbgs().indent(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.
+bool FPPassManager::runOnFunction(Function &F) {
+ if (F.isDeclaration())
+ return false;
+
+ bool Changed = false;
+
+ // Collect inherited analysis from Module level pass manager.
+ populateInheritedAnalysis(TPM->activeStack);
+
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ FunctionPass *FP = getContainedPass(Index);
+ bool LocalChanged = false;
+
+ dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName());
+ dumpRequiredSet(FP);
+
+ initializeAnalysisImpl(FP);
+
+ {
+ PassManagerPrettyStackEntry X(FP, F);
+ TimeRegion PassTimer(getPassTimer(FP));
+
+ LocalChanged |= FP->runOnFunction(F);
+ }
+
+ Changed |= LocalChanged;
+ if (LocalChanged)
+ dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName());
+ dumpPreservedSet(FP);
+
+ verifyPreservedAnalysis(FP);
+ removeNotPreservedAnalysis(FP);
+ recordAvailableAnalysis(FP);
+ removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG);
+ }
+ return Changed;
+}
+
+bool FPPassManager::runOnModule(Module &M) {
+ bool Changed = false;
+
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ Changed |= runOnFunction(*I);
+
+ return Changed;
+}
+
+bool FPPassManager::doInitialization(Module &M) {
+ bool Changed = false;
+
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
+ Changed |= getContainedPass(Index)->doInitialization(M);
+
+ return Changed;
+}
+
+bool FPPassManager::doFinalization(Module &M) {
+ bool Changed = false;
+
+ for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
+ Changed |= getContainedPass(Index)->doFinalization(M);
+
+ return Changed;
+}
+
+//===----------------------------------------------------------------------===//
+// MPPassManager implementation
+
+/// Execute all of the passes scheduled for execution by invoking
+/// runOnModule method. Keep track of whether any of the passes modifies
+/// the module, and if so, return true.
+bool
+MPPassManager::runOnModule(Module &M) {
+ bool Changed = false;
+
+ // Initialize on-the-fly passes
+ for (std::map<Pass *, FunctionPassManagerImpl *>::iterator
+ I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end();
+ I != E; ++I) {
+ FunctionPassManagerImpl *FPP = I->second;
+ Changed |= FPP->doInitialization(M);
+ }
+
+ // Initialize module passes
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
+ Changed |= getContainedPass(Index)->doInitialization(M);
+
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ ModulePass *MP = getContainedPass(Index);
+ bool LocalChanged = false;
+
+ dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier());
+ dumpRequiredSet(MP);
+
+ initializeAnalysisImpl(MP);
+
+ {
+ PassManagerPrettyStackEntry X(MP, M);
+ TimeRegion PassTimer(getPassTimer(MP));
+
+ LocalChanged |= MP->runOnModule(M);
+ }
+
+ Changed |= LocalChanged;
+ if (LocalChanged)
+ dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
+ M.getModuleIdentifier());
+ dumpPreservedSet(MP);
+
+ verifyPreservedAnalysis(MP);
+ removeNotPreservedAnalysis(MP);
+ recordAvailableAnalysis(MP);
+ removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG);
+ }
+
+ // Finalize module passes
+ for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
+ Changed |= getContainedPass(Index)->doFinalization(M);
+
+ // Finalize on-the-fly passes
+ for (std::map<Pass *, FunctionPassManagerImpl *>::iterator
+ I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end();
+ I != E; ++I) {
+ FunctionPassManagerImpl *FPP = I->second;
+ // We don't know when is the last time an on-the-fly pass is run,
+ // so we need to releaseMemory / finalize here
+ FPP->releaseMemoryOnTheFly();
+ Changed |= FPP->doFinalization(M);
+ }
+
+ return Changed;
+}
+
+/// 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.
+void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
+ assert(P->getPotentialPassManagerType() == PMT_ModulePassManager &&
+ "Unable to handle Pass that requires lower level Analysis pass");
+ assert((P->getPotentialPassManagerType() <
+ RequiredPass->getPotentialPassManagerType()) &&
+ "Unable to handle Pass that requires lower level Analysis pass");
+
+ FunctionPassManagerImpl *FPP = OnTheFlyManagers[P];
+ if (!FPP) {
+ FPP = new FunctionPassManagerImpl();
+ // FPP is the top level manager.
+ FPP->setTopLevelManager(FPP);
+
+ OnTheFlyManagers[P] = FPP;
+ }
+ FPP->add(RequiredPass);
+
+ // Register P as the last user of RequiredPass.
+ if (RequiredPass) {
+ SmallVector<Pass *, 1> LU;
+ LU.push_back(RequiredPass);
+ FPP->setLastUser(LU, P);
+ }
+}
+
+/// Return function pass corresponding to PassInfo PI, that is
+/// required by module pass MP. Instantiate analysis pass, by using
+/// its runOnFunction() for function F.
+Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){
+ FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP];
+ assert(FPP && "Unable to find on the fly pass");
+
+ FPP->releaseMemoryOnTheFly();
+ FPP->run(F);
+ return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI);
+}
+
+
+//===----------------------------------------------------------------------===//
+// PassManagerImpl implementation
+
+//
+/// 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 PassManagerImpl::run(Module &M) {
+ bool Changed = false;
+ TimingInfo::createTheTimeInfo();
+
+ dumpArguments();
+ dumpPasses();
+
+ SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
+ for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
+ E = IPV.end(); I != E; ++I) {
+ Changed |= (*I)->doInitialization(M);
+ }
+
+ initializeAllAnalysisInfo();
+ for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
+ Changed |= getContainedManager(Index)->runOnModule(M);
+
+ for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
+ E = IPV.end(); I != E; ++I) {
+ Changed |= (*I)->doFinalization(M);
+ }
+
+ return Changed;
+}
+
+//===----------------------------------------------------------------------===//
+// PassManager implementation
+
+/// Create new pass manager
+PassManager::PassManager() {
+ PM = new PassManagerImpl();
+ // PM is the top level manager
+ PM->setTopLevelManager(PM);
+}
+
+PassManager::~PassManager() {
+ delete PM;
+}
+
+/// add - Add a pass to the queue of passes to run. This passes ownership of
+/// the Pass to the PassManager. When the PassManager is destroyed, the pass
+/// will be destroyed as well, so there is no need to delete the pass. This
+/// implies that all passes MUST be allocated with 'new'.
+void PassManager::add(Pass *P) {
+ PM->add(P);
+}
+
+/// 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 PassManager::run(Module &M) {
+ return PM->run(M);
+}
+
+//===----------------------------------------------------------------------===//
+// TimingInfo implementation
+
+bool llvm::TimePassesIsEnabled = false;
+static cl::opt<bool,true>
+EnableTiming("time-passes", cl::location(TimePassesIsEnabled),
+ cl::desc("Time each pass, printing elapsed time for each on exit"));
+
+// 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.
+void TimingInfo::createTheTimeInfo() {
+ if (!TimePassesIsEnabled || TheTimeInfo) return;
+
+ // Constructed the first time this is called, iff -time-passes is enabled.
+ // This guarantees that the object will be constructed before static globals,
+ // thus it will be destroyed before them.
+ static ManagedStatic<TimingInfo> TTI;
+ TheTimeInfo = &*TTI;
+}
+
+/// If TimingInfo is enabled then start pass timer.
+Timer *llvm::getPassTimer(Pass *P) {
+ if (TheTimeInfo)
+ return TheTimeInfo->getPassTimer(P);
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// PMStack implementation
+//
+
+// Pop Pass Manager from the stack and clear its analysis info.
+void PMStack::pop() {
+
+ PMDataManager *Top = this->top();
+ Top->initializeAnalysisInfo();
+
+ S.pop_back();
+}
+
+// Push PM on the stack and set its top level manager.
+void PMStack::push(PMDataManager *PM) {
+ assert(PM && "Unable to push. Pass Manager expected");
+ assert(PM->getDepth()==0 && "Pass Manager depth set too early");
+
+ if (!this->empty()) {
+ assert(PM->getPassManagerType() > this->top()->getPassManagerType()
+ && "pushing bad pass manager to PMStack");
+ PMTopLevelManager *TPM = this->top()->getTopLevelManager();
+
+ assert(TPM && "Unable to find top level manager");
+ TPM->addIndirectPassManager(PM);
+ PM->setTopLevelManager(TPM);
+ PM->setDepth(this->top()->getDepth()+1);
+ } else {
+ assert((PM->getPassManagerType() == PMT_ModulePassManager
+ || PM->getPassManagerType() == PMT_FunctionPassManager)
+ && "pushing bad pass manager to PMStack");
+ PM->setDepth(1);
+ }
+
+ S.push_back(PM);
+}
+
+// Dump content of the pass manager stack.
+void PMStack::dump() const {
+ for (std::vector<PMDataManager *>::const_iterator I = S.begin(),
+ E = S.end(); I != E; ++I)
+ dbgs() << (*I)->getAsPass()->getPassName() << ' ';
+
+ if (!S.empty())
+ dbgs() << '\n';
+}
+
+/// Find appropriate Module Pass Manager in the PM Stack and
+/// add self into that manager.
+void ModulePass::assignPassManager(PMStack &PMS,
+ PassManagerType PreferredType) {
+ // Find Module Pass Manager
+ while (!PMS.empty()) {
+ PassManagerType TopPMType = PMS.top()->getPassManagerType();
+ if (TopPMType == PreferredType)
+ break; // We found desired pass manager
+ else if (TopPMType > PMT_ModulePassManager)
+ PMS.pop(); // Pop children pass managers
+ else
+ break;
+ }
+ assert(!PMS.empty() && "Unable to find appropriate Pass Manager");
+ PMS.top()->add(this);
+}
+
+/// Find appropriate Function Pass Manager or Call Graph Pass Manager
+/// in the PM Stack and add self into that manager.
+void FunctionPass::assignPassManager(PMStack &PMS,
+ PassManagerType PreferredType) {
+
+ // Find Function Pass Manager
+ while (!PMS.empty()) {
+ if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager)
+ PMS.pop();
+ else
+ break;
+ }
+
+ // Create new Function Pass Manager if needed.
+ FPPassManager *FPP;
+ if (PMS.top()->getPassManagerType() == PMT_FunctionPassManager) {
+ FPP = (FPPassManager *)PMS.top();
+ } else {
+ assert(!PMS.empty() && "Unable to create Function Pass Manager");
+ PMDataManager *PMD = PMS.top();
+
+ // [1] Create new Function Pass Manager
+ FPP = new FPPassManager();
+ FPP->populateInheritedAnalysis(PMS);
+
+ // [2] Set up new manager's top level manager
+ PMTopLevelManager *TPM = PMD->getTopLevelManager();
+ TPM->addIndirectPassManager(FPP);
+
+ // [3] Assign manager to manage this new manager. This may create
+ // and push new managers into PMS
+ FPP->assignPassManager(PMS, PMD->getPassManagerType());
+
+ // [4] Push new manager into PMS
+ PMS.push(FPP);
+ }
+
+ // Assign FPP as the manager of this pass.
+ FPP->add(this);
+}
+
+/// Find appropriate Basic Pass Manager or Call Graph Pass Manager
+/// in the PM Stack and add self into that manager.
+void BasicBlockPass::assignPassManager(PMStack &PMS,
+ PassManagerType PreferredType) {
+ BBPassManager *BBP;
+
+ // Basic Pass Manager is a leaf pass manager. It does not handle
+ // any other pass manager.
+ if (!PMS.empty() &&
+ PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager) {
+ BBP = (BBPassManager *)PMS.top();
+ } else {
+ // If leaf manager is not Basic Block Pass manager then create new
+ // basic Block Pass manager.
+ assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager");
+ PMDataManager *PMD = PMS.top();
+
+ // [1] Create new Basic Block Manager
+ BBP = new BBPassManager();
+
+ // [2] Set up new manager's top level manager
+ // Basic Block Pass Manager does not live by itself
+ PMTopLevelManager *TPM = PMD->getTopLevelManager();
+ TPM->addIndirectPassManager(BBP);
+
+ // [3] Assign manager to manage this new manager. This may create
+ // and push new managers into PMS
+ BBP->assignPassManager(PMS, PreferredType);
+
+ // [4] Push new manager into PMS
+ PMS.push(BBP);
+ }
+
+ // Assign BBP as the manager of this pass.
+ BBP->add(this);
+}
+
+PassManagerBase::~PassManagerBase() {}
+++ /dev/null
-//===- PassManager.cpp - LLVM Pass Infrastructure Implementation ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file 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/PassManagers.h"
-#include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/IR/Module.h"
-#include "llvm/PassManager.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/Mutex.h"
-#include "llvm/Support/PassNameParser.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <map>
-using namespace llvm;
-
-// See PassManagers.h for Pass Manager infrastructure overview.
-
-namespace llvm {
-
-//===----------------------------------------------------------------------===//
-// Pass debugging information. Often it is useful to find out what pass is
-// running when a crash occurs in a utility. When this library is compiled with
-// debugging on, a command line option (--debug-pass) is enabled that causes the
-// pass name to be printed before it executes.
-//
-
-// Different debug levels that can be enabled...
-enum PassDebugLevel {
- Disabled, Arguments, Structure, Executions, Details
-};
-
-static cl::opt<enum PassDebugLevel>
-PassDebugging("debug-pass", cl::Hidden,
- cl::desc("Print PassManager debugging information"),
- cl::values(
- clEnumVal(Disabled , "disable debug output"),
- clEnumVal(Arguments , "print pass arguments to pass to 'opt'"),
- clEnumVal(Structure , "print pass structure before run()"),
- clEnumVal(Executions, "print pass name before it is executed"),
- clEnumVal(Details , "print pass details when it is executed"),
- clEnumValEnd));
-
-typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser>
-PassOptionList;
-
-// Print IR out before/after specified passes.
-static PassOptionList
-PrintBefore("print-before",
- llvm::cl::desc("Print IR before specified passes"),
- cl::Hidden);
-
-static PassOptionList
-PrintAfter("print-after",
- llvm::cl::desc("Print IR after specified passes"),
- cl::Hidden);
-
-static cl::opt<bool>
-PrintBeforeAll("print-before-all",
- llvm::cl::desc("Print IR before each pass"),
- cl::init(false));
-static cl::opt<bool>
-PrintAfterAll("print-after-all",
- llvm::cl::desc("Print IR after each pass"),
- cl::init(false));
-
-/// This is a helper to determine whether to print IR before or
-/// after a pass.
-
-static bool ShouldPrintBeforeOrAfterPass(const PassInfo *PI,
- PassOptionList &PassesToPrint) {
- for (unsigned i = 0, ie = PassesToPrint.size(); i < ie; ++i) {
- const llvm::PassInfo *PassInf = PassesToPrint[i];
- if (PassInf)
- if (PassInf->getPassArgument() == PI->getPassArgument()) {
- return true;
- }
- }
- return false;
-}
-
-/// This is a utility to check whether a pass should have IR dumped
-/// before it.
-static bool ShouldPrintBeforePass(const PassInfo *PI) {
- return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PI, PrintBefore);
-}
-
-/// This is a utility to check whether a pass should have IR dumped
-/// after it.
-static bool ShouldPrintAfterPass(const PassInfo *PI) {
- return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter);
-}
-
-} // End of llvm namespace
-
-/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
-/// or higher is specified.
-bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
- return PassDebugging >= Executions;
-}
-
-
-
-
-void PassManagerPrettyStackEntry::print(raw_ostream &OS) const {
- if (V == 0 && M == 0)
- OS << "Releasing pass '";
- else
- OS << "Running pass '";
-
- OS << P->getPassName() << "'";
-
- if (M) {
- OS << " on module '" << M->getModuleIdentifier() << "'.\n";
- return;
- }
- if (V == 0) {
- OS << '\n';
- return;
- }
-
- OS << " on ";
- if (isa<Function>(V))
- OS << "function";
- else if (isa<BasicBlock>(V))
- OS << "basic block";
- else
- OS << "value";
-
- OS << " '";
- WriteAsOperand(OS, V, /*PrintTy=*/false, M);
- OS << "'\n";
-}
-
-
-namespace {
-
-//===----------------------------------------------------------------------===//
-// BBPassManager
-//
-/// BBPassManager manages BasicBlockPass. It batches all the
-/// pass together and sequence them to process one basic block before
-/// processing next basic block.
-class BBPassManager : public PMDataManager, public FunctionPass {
-
-public:
- static char ID;
- explicit BBPassManager()
- : PMDataManager(), FunctionPass(ID) {}
-
- /// Execute all of the passes scheduled for execution. Keep track of
- /// whether any of the passes modifies the function, and if so, return true.
- bool runOnFunction(Function &F);
-
- /// Pass Manager itself does not invalidate any analysis info.
- void getAnalysisUsage(AnalysisUsage &Info) const {
- Info.setPreservesAll();
- }
-
- bool doInitialization(Module &M);
- bool doInitialization(Function &F);
- bool doFinalization(Module &M);
- bool doFinalization(Function &F);
-
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
-
- virtual const char *getPassName() const {
- return "BasicBlock Pass Manager";
- }
-
- // Print passes managed by this manager
- void dumpPassStructure(unsigned Offset) {
- llvm::dbgs().indent(Offset*2) << "BasicBlockPass Manager\n";
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- BasicBlockPass *BP = getContainedPass(Index);
- BP->dumpPassStructure(Offset + 1);
- dumpLastUses(BP, Offset+1);
- }
- }
-
- BasicBlockPass *getContainedPass(unsigned N) {
- assert(N < PassVector.size() && "Pass number out of range!");
- BasicBlockPass *BP = static_cast<BasicBlockPass *>(PassVector[N]);
- return BP;
- }
-
- virtual PassManagerType getPassManagerType() const {
- return PMT_BasicBlockPassManager;
- }
-};
-
-char BBPassManager::ID = 0;
-}
-
-namespace llvm {
-
-//===----------------------------------------------------------------------===//
-// FunctionPassManagerImpl
-//
-/// FunctionPassManagerImpl manages FPPassManagers
-class FunctionPassManagerImpl : public Pass,
- public PMDataManager,
- public PMTopLevelManager {
- virtual void anchor();
-private:
- bool wasRun;
-public:
- static char ID;
- explicit FunctionPassManagerImpl() :
- Pass(PT_PassManager, ID), PMDataManager(),
- PMTopLevelManager(new FPPassManager()), wasRun(false) {}
-
- /// add - Add a pass to the queue of passes to run. This passes ownership of
- /// the Pass to the PassManager. When the PassManager is destroyed, the pass
- /// will be destroyed as well, so there is no need to delete the pass. This
- /// implies that all passes MUST be allocated with 'new'.
- void add(Pass *P) {
- schedulePass(P);
- }
-
- /// createPrinterPass - Get a function printer pass.
- Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
- return createPrintFunctionPass(Banner, &O);
- }
-
- // Prepare for running an on the fly pass, freeing memory if needed
- // from a previous run.
- void releaseMemoryOnTheFly();
-
- /// 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 run(Function &F);
-
- /// doInitialization - Run all of the initializers for the function passes.
- ///
- bool doInitialization(Module &M);
-
- /// doFinalization - Run all of the finalizers for the function passes.
- ///
- bool doFinalization(Module &M);
-
-
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
- virtual PassManagerType getTopLevelPassManagerType() {
- return PMT_FunctionPassManager;
- }
-
- /// Pass Manager itself does not invalidate any analysis info.
- void getAnalysisUsage(AnalysisUsage &Info) const {
- Info.setPreservesAll();
- }
-
- FPPassManager *getContainedManager(unsigned N) {
- assert(N < PassManagers.size() && "Pass number out of range!");
- FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]);
- return FP;
- }
-};
-
-void FunctionPassManagerImpl::anchor() {}
-
-char FunctionPassManagerImpl::ID = 0;
-
-//===----------------------------------------------------------------------===//
-// MPPassManager
-//
-/// MPPassManager manages ModulePasses and function pass managers.
-/// It batches all Module passes and function pass managers together and
-/// sequences them to process one module.
-class MPPassManager : public Pass, public PMDataManager {
-public:
- static char ID;
- explicit MPPassManager() :
- Pass(PT_PassManager, ID), PMDataManager() { }
-
- // Delete on the fly managers.
- virtual ~MPPassManager() {
- for (std::map<Pass *, FunctionPassManagerImpl *>::iterator
- I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end();
- I != E; ++I) {
- FunctionPassManagerImpl *FPP = I->second;
- delete FPP;
- }
- }
-
- /// createPrinterPass - Get a module printer pass.
- Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
- return createPrintModulePass(&O, false, Banner);
- }
-
- /// 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 runOnModule(Module &M);
-
- using llvm::Pass::doInitialization;
- using llvm::Pass::doFinalization;
-
- /// doInitialization - Run all of the initializers for the module passes.
- ///
- bool doInitialization();
-
- /// doFinalization - Run all of the finalizers for the module passes.
- ///
- bool doFinalization();
-
- /// Pass Manager itself does not invalidate any analysis info.
- void getAnalysisUsage(AnalysisUsage &Info) const {
- Info.setPreservesAll();
- }
-
- /// 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);
-
- /// Return function pass corresponding to PassInfo PI, that is
- /// required by module pass MP. Instantiate analysis pass, by using
- /// its runOnFunction() for function F.
- virtual Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F);
-
- virtual const char *getPassName() const {
- return "Module Pass Manager";
- }
-
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
-
- // Print passes managed by this manager
- void dumpPassStructure(unsigned Offset) {
- llvm::dbgs().indent(Offset*2) << "ModulePass Manager\n";
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- ModulePass *MP = getContainedPass(Index);
- MP->dumpPassStructure(Offset + 1);
- std::map<Pass *, FunctionPassManagerImpl *>::const_iterator I =
- OnTheFlyManagers.find(MP);
- if (I != OnTheFlyManagers.end())
- I->second->dumpPassStructure(Offset + 2);
- dumpLastUses(MP, Offset+1);
- }
- }
-
- ModulePass *getContainedPass(unsigned N) {
- assert(N < PassVector.size() && "Pass number out of range!");
- return static_cast<ModulePass *>(PassVector[N]);
- }
-
- virtual PassManagerType getPassManagerType() const {
- return PMT_ModulePassManager;
- }
-
- private:
- /// Collection of on the fly FPPassManagers. These managers manage
- /// function passes that are required by module passes.
- std::map<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers;
-};
-
-char MPPassManager::ID = 0;
-//===----------------------------------------------------------------------===//
-// PassManagerImpl
-//
-
-/// PassManagerImpl manages MPPassManagers
-class PassManagerImpl : public Pass,
- public PMDataManager,
- public PMTopLevelManager {
- virtual void anchor();
-
-public:
- static char ID;
- explicit PassManagerImpl() :
- Pass(PT_PassManager, ID), PMDataManager(),
- PMTopLevelManager(new MPPassManager()) {}
-
- /// add - Add a pass to the queue of passes to run. This passes ownership of
- /// the Pass to the PassManager. When the PassManager is destroyed, the pass
- /// will be destroyed as well, so there is no need to delete the pass. This
- /// implies that all passes MUST be allocated with 'new'.
- void add(Pass *P) {
- schedulePass(P);
- }
-
- /// createPrinterPass - Get a module printer pass.
- Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const {
- return createPrintModulePass(&O, false, Banner);
- }
-
- /// 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 run(Module &M);
-
- using llvm::Pass::doInitialization;
- using llvm::Pass::doFinalization;
-
- /// doInitialization - Run all of the initializers for the module passes.
- ///
- bool doInitialization();
-
- /// doFinalization - Run all of the finalizers for the module passes.
- ///
- bool doFinalization();
-
- /// Pass Manager itself does not invalidate any analysis info.
- void getAnalysisUsage(AnalysisUsage &Info) const {
- Info.setPreservesAll();
- }
-
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
- virtual PassManagerType getTopLevelPassManagerType() {
- return PMT_ModulePassManager;
- }
-
- MPPassManager *getContainedManager(unsigned N) {
- assert(N < PassManagers.size() && "Pass number out of range!");
- MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]);
- return MP;
- }
-};
-
-void PassManagerImpl::anchor() {}
-
-char PassManagerImpl::ID = 0;
-} // End of llvm namespace
-
-namespace {
-
-//===----------------------------------------------------------------------===//
-/// 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.
-///
-
-static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex;
-
-class TimingInfo {
- DenseMap<Pass*, Timer*> 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, which accumulate their info into the
- // TimerGroup.
- for (DenseMap<Pass*, Timer*>::iterator I = TimingData.begin(),
- E = TimingData.end(); I != E; ++I)
- delete I->second;
- // 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();
-
- /// getPassTimer - Return the timer for the specified pass if it exists.
- Timer *getPassTimer(Pass *P) {
- if (P->getAsPMDataManager())
- return 0;
-
- sys::SmartScopedLock<true> Lock(*TimingInfoMutex);
- Timer *&T = TimingData[P];
- if (T == 0)
- T = new Timer(P->getPassName(), TG);
- return T;
- }
-};
-
-} // End of anon namespace
-
-static TimingInfo *TheTimeInfo;
-
-//===----------------------------------------------------------------------===//
-// PMTopLevelManager implementation
-
-/// Initialize top level manager. Create first pass manager.
-PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) {
- PMDM->setTopLevelManager(this);
- addPassManager(PMDM);
- activeStack.push(PMDM);
-}
-
-/// Set pass P as the last user of the given analysis passes.
-void
-PMTopLevelManager::setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P) {
- unsigned PDepth = 0;
- if (P->getResolver())
- PDepth = P->getResolver()->getPMDataManager().getDepth();
-
- for (SmallVectorImpl<Pass *>::const_iterator I = AnalysisPasses.begin(),
- E = AnalysisPasses.end(); I != E; ++I) {
- Pass *AP = *I;
- LastUser[AP] = P;
-
- if (P == AP)
- continue;
-
- // Update the last users of passes that are required transitive by AP.
- AnalysisUsage *AnUsage = findAnalysisUsage(AP);
- const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet();
- SmallVector<Pass *, 12> LastUses;
- SmallVector<Pass *, 12> LastPMUses;
- for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(),
- E = IDs.end(); I != E; ++I) {
- Pass *AnalysisPass = findAnalysisPass(*I);
- assert(AnalysisPass && "Expected analysis pass to exist.");
- AnalysisResolver *AR = AnalysisPass->getResolver();
- assert(AR && "Expected analysis resolver to exist.");
- unsigned APDepth = AR->getPMDataManager().getDepth();
-
- if (PDepth == APDepth)
- LastUses.push_back(AnalysisPass);
- else if (PDepth > APDepth)
- LastPMUses.push_back(AnalysisPass);
- }
-
- setLastUser(LastUses, P);
-
- // If this pass has a corresponding pass manager, push higher level
- // analysis to this pass manager.
- if (P->getResolver())
- setLastUser(LastPMUses, P->getResolver()->getPMDataManager().getAsPass());
-
-
- // If AP is the last user of other passes then make P last user of
- // such passes.
- for (DenseMap<Pass *, Pass *>::iterator LUI = LastUser.begin(),
- LUE = LastUser.end(); LUI != LUE; ++LUI) {
- if (LUI->second == AP)
- // DenseMap iterator is not invalidated here because
- // this is just updating existing entries.
- LastUser[LUI->first] = P;
- }
- }
-}
-
-/// Collect passes whose last user is P
-void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses,
- Pass *P) {
- DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator DMI =
- InversedLastUser.find(P);
- if (DMI == InversedLastUser.end())
- return;
-
- SmallPtrSet<Pass *, 8> &LU = DMI->second;
- for (SmallPtrSet<Pass *, 8>::iterator I = LU.begin(),
- E = LU.end(); I != E; ++I) {
- LastUses.push_back(*I);
- }
-
-}
-
-AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) {
- AnalysisUsage *AnUsage = NULL;
- DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P);
- if (DMI != AnUsageMap.end())
- AnUsage = DMI->second;
- else {
- AnUsage = new AnalysisUsage();
- P->getAnalysisUsage(*AnUsage);
- AnUsageMap[P] = AnUsage;
- }
- return AnUsage;
-}
-
-/// 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 PMTopLevelManager::schedulePass(Pass *P) {
-
- // TODO : Allocate function manager for this pass, other wise required set
- // may be inserted into previous function manager
-
- // Give pass a chance to prepare the stage.
- P->preparePassManager(activeStack);
-
- // If P is an analysis pass and it is available then do not
- // generate the analysis again. Stale analysis info should not be
- // available at this point.
- const PassInfo *PI =
- PassRegistry::getPassRegistry()->getPassInfo(P->getPassID());
- if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) {
- delete P;
- return;
- }
-
- AnalysisUsage *AnUsage = findAnalysisUsage(P);
-
- bool checkAnalysis = true;
- while (checkAnalysis) {
- checkAnalysis = false;
-
- const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
- for (AnalysisUsage::VectorType::const_iterator I = RequiredSet.begin(),
- E = RequiredSet.end(); I != E; ++I) {
-
- Pass *AnalysisPass = findAnalysisPass(*I);
- if (!AnalysisPass) {
- const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
-
- if (PI == NULL) {
- // Pass P is not in the global PassRegistry
- dbgs() << "Pass '" << P->getPassName() << "' is not initialized." << "\n";
- dbgs() << "Verify if there is a pass dependency cycle." << "\n";
- dbgs() << "Required Passes:" << "\n";
- for (AnalysisUsage::VectorType::const_iterator I2 = RequiredSet.begin(),
- E = RequiredSet.end(); I2 != E && I2 != I; ++I2) {
- Pass *AnalysisPass2 = findAnalysisPass(*I2);
- if (AnalysisPass2) {
- dbgs() << "\t" << AnalysisPass2->getPassName() << "\n";
- } else {
- dbgs() << "\t" << "Error: Required pass not found! Possible causes:" << "\n";
- dbgs() << "\t\t" << "- Pass misconfiguration (e.g.: missing macros)" << "\n";
- dbgs() << "\t\t" << "- Corruption of the global PassRegistry" << "\n";
- }
- }
- }
-
- assert(PI && "Expected required passes to be initialized");
- AnalysisPass = PI->createPass();
- if (P->getPotentialPassManagerType () ==
- AnalysisPass->getPotentialPassManagerType())
- // Schedule analysis pass that is managed by the same pass manager.
- schedulePass(AnalysisPass);
- else if (P->getPotentialPassManagerType () >
- AnalysisPass->getPotentialPassManagerType()) {
- // Schedule analysis pass that is managed by a new manager.
- schedulePass(AnalysisPass);
- // Recheck analysis passes to ensure that required analyses that
- // are already checked are still available.
- checkAnalysis = true;
- } else
- // Do not schedule this analysis. Lower level analsyis
- // passes are run on the fly.
- delete AnalysisPass;
- }
- }
- }
-
- // Now all required passes are available.
- if (ImmutablePass *IP = P->getAsImmutablePass()) {
- // P is a immutable pass and it will be managed by this
- // top level manager. Set up analysis resolver to connect them.
- PMDataManager *DM = getAsPMDataManager();
- AnalysisResolver *AR = new AnalysisResolver(*DM);
- P->setResolver(AR);
- DM->initializeAnalysisImpl(P);
- addImmutablePass(IP);
- DM->recordAvailableAnalysis(IP);
- return;
- }
-
- if (PI && !PI->isAnalysis() && ShouldPrintBeforePass(PI)) {
- Pass *PP = P->createPrinterPass(
- dbgs(), std::string("*** IR Dump Before ") + P->getPassName() + " ***");
- PP->assignPassManager(activeStack, getTopLevelPassManagerType());
- }
-
- // Add the requested pass to the best available pass manager.
- P->assignPassManager(activeStack, getTopLevelPassManagerType());
-
- if (PI && !PI->isAnalysis() && ShouldPrintAfterPass(PI)) {
- Pass *PP = P->createPrinterPass(
- dbgs(), std::string("*** IR Dump After ") + P->getPassName() + " ***");
- PP->assignPassManager(activeStack, getTopLevelPassManagerType());
- }
-}
-
-/// Find the pass that implements Analysis AID. Search immutable
-/// passes and all pass managers. If desired pass is not found
-/// then return NULL.
-Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
-
- // Check pass managers
- for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(),
- E = PassManagers.end(); I != E; ++I)
- if (Pass *P = (*I)->findAnalysisPass(AID, false))
- return P;
-
- // Check other pass managers
- for (SmallVectorImpl<PMDataManager *>::iterator
- I = IndirectPassManagers.begin(),
- E = IndirectPassManagers.end(); I != E; ++I)
- if (Pass *P = (*I)->findAnalysisPass(AID, false))
- return P;
-
- // Check the immutable passes. Iterate in reverse order so that we find
- // the most recently registered passes first.
- for (SmallVectorImpl<ImmutablePass *>::reverse_iterator I =
- ImmutablePasses.rbegin(), E = ImmutablePasses.rend(); I != E; ++I) {
- AnalysisID PI = (*I)->getPassID();
- if (PI == AID)
- return *I;
-
- // If Pass not found then check the interfaces implemented by Immutable Pass
- const PassInfo *PassInf =
- PassRegistry::getPassRegistry()->getPassInfo(PI);
- assert(PassInf && "Expected all immutable passes to be initialized");
- const std::vector<const PassInfo*> &ImmPI =
- PassInf->getInterfacesImplemented();
- for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(),
- EE = ImmPI.end(); II != EE; ++II) {
- if ((*II)->getTypeInfo() == AID)
- return *I;
- }
- }
-
- return 0;
-}
-
-// Print passes managed by this top level manager.
-void PMTopLevelManager::dumpPasses() const {
-
- if (PassDebugging < Structure)
- return;
-
- // Print out the immutable passes
- for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) {
- ImmutablePasses[i]->dumpPassStructure(0);
- }
-
- // Every class that derives from PMDataManager also derives from Pass
- // (sometimes indirectly), but there's no inheritance relationship
- // between PMDataManager and Pass, so we have to getAsPass to get
- // from a PMDataManager* to a Pass*.
- for (SmallVectorImpl<PMDataManager *>::const_iterator I =
- PassManagers.begin(), E = PassManagers.end(); I != E; ++I)
- (*I)->getAsPass()->dumpPassStructure(1);
-}
-
-void PMTopLevelManager::dumpArguments() const {
-
- if (PassDebugging < Arguments)
- return;
-
- dbgs() << "Pass Arguments: ";
- for (SmallVectorImpl<ImmutablePass *>::const_iterator I =
- ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
- if (const PassInfo *PI =
- PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) {
- assert(PI && "Expected all immutable passes to be initialized");
- if (!PI->isAnalysisGroup())
- dbgs() << " -" << PI->getPassArgument();
- }
- for (SmallVectorImpl<PMDataManager *>::const_iterator I =
- PassManagers.begin(), E = PassManagers.end(); I != E; ++I)
- (*I)->dumpPassArguments();
- dbgs() << "\n";
-}
-
-void PMTopLevelManager::initializeAllAnalysisInfo() {
- for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(),
- E = PassManagers.end(); I != E; ++I)
- (*I)->initializeAnalysisInfo();
-
- // Initailize other pass managers
- for (SmallVectorImpl<PMDataManager *>::iterator
- I = IndirectPassManagers.begin(), E = IndirectPassManagers.end();
- I != E; ++I)
- (*I)->initializeAnalysisInfo();
-
- for (DenseMap<Pass *, Pass *>::iterator DMI = LastUser.begin(),
- DME = LastUser.end(); DMI != DME; ++DMI) {
- DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator InvDMI =
- InversedLastUser.find(DMI->second);
- if (InvDMI != InversedLastUser.end()) {
- SmallPtrSet<Pass *, 8> &L = InvDMI->second;
- L.insert(DMI->first);
- } else {
- SmallPtrSet<Pass *, 8> L; L.insert(DMI->first);
- InversedLastUser[DMI->second] = L;
- }
- }
-}
-
-/// Destructor
-PMTopLevelManager::~PMTopLevelManager() {
- for (SmallVectorImpl<PMDataManager *>::iterator I = PassManagers.begin(),
- E = PassManagers.end(); I != E; ++I)
- delete *I;
-
- for (SmallVectorImpl<ImmutablePass *>::iterator
- I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
- delete *I;
-
- for (DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.begin(),
- DME = AnUsageMap.end(); DMI != DME; ++DMI)
- delete DMI->second;
-}
-
-//===----------------------------------------------------------------------===//
-// PMDataManager implementation
-
-/// Augement AvailableAnalysis by adding analysis made available by pass P.
-void PMDataManager::recordAvailableAnalysis(Pass *P) {
- AnalysisID PI = P->getPassID();
-
- AvailableAnalysis[PI] = P;
-
- assert(!AvailableAnalysis.empty());
-
- // This pass is the current implementation of all of the interfaces it
- // implements as well.
- const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI);
- if (PInf == 0) return;
- const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented();
- for (unsigned i = 0, e = II.size(); i != e; ++i)
- AvailableAnalysis[II[i]->getTypeInfo()] = P;
-}
-
-// Return true if P preserves high level analysis used by other
-// passes managed by this manager
-bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) {
- AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
- if (AnUsage->getPreservesAll())
- return true;
-
- const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
- for (SmallVectorImpl<Pass *>::iterator I = HigherLevelAnalysis.begin(),
- E = HigherLevelAnalysis.end(); I != E; ++I) {
- Pass *P1 = *I;
- if (P1->getAsImmutablePass() == 0 &&
- std::find(PreservedSet.begin(), PreservedSet.end(),
- P1->getPassID()) ==
- PreservedSet.end())
- return false;
- }
-
- return true;
-}
-
-/// verifyPreservedAnalysis -- Verify analysis preserved by pass P.
-void PMDataManager::verifyPreservedAnalysis(Pass *P) {
- // Don't do this unless assertions are enabled.
-#ifdef NDEBUG
- return;
-#endif
- AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
- const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
-
- // Verify preserved analysis
- for (AnalysisUsage::VectorType::const_iterator I = PreservedSet.begin(),
- E = PreservedSet.end(); I != E; ++I) {
- AnalysisID AID = *I;
- if (Pass *AP = findAnalysisPass(AID, true)) {
- TimeRegion PassTimer(getPassTimer(AP));
- AP->verifyAnalysis();
- }
- }
-}
-
-/// Remove Analysis not preserved by Pass P
-void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
- AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
- if (AnUsage->getPreservesAll())
- return;
-
- const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
- for (DenseMap<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(),
- E = AvailableAnalysis.end(); I != E; ) {
- DenseMap<AnalysisID, Pass*>::iterator Info = I++;
- if (Info->second->getAsImmutablePass() == 0 &&
- std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
- PreservedSet.end()) {
- // Remove this analysis
- if (PassDebugging >= Details) {
- Pass *S = Info->second;
- dbgs() << " -- '" << P->getPassName() << "' is not preserving '";
- dbgs() << S->getPassName() << "'\n";
- }
- AvailableAnalysis.erase(Info);
- }
- }
-
- // Check inherited analysis also. If P is not preserving analysis
- // provided by parent manager then remove it here.
- for (unsigned Index = 0; Index < PMT_Last; ++Index) {
-
- if (!InheritedAnalysis[Index])
- continue;
-
- for (DenseMap<AnalysisID, Pass*>::iterator
- I = InheritedAnalysis[Index]->begin(),
- E = InheritedAnalysis[Index]->end(); I != E; ) {
- DenseMap<AnalysisID, Pass *>::iterator Info = I++;
- if (Info->second->getAsImmutablePass() == 0 &&
- std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
- PreservedSet.end()) {
- // Remove this analysis
- if (PassDebugging >= Details) {
- Pass *S = Info->second;
- dbgs() << " -- '" << P->getPassName() << "' is not preserving '";
- dbgs() << S->getPassName() << "'\n";
- }
- InheritedAnalysis[Index]->erase(Info);
- }
- }
- }
-}
-
-/// Remove analysis passes that are not used any longer
-void PMDataManager::removeDeadPasses(Pass *P, StringRef Msg,
- enum PassDebuggingString DBG_STR) {
-
- SmallVector<Pass *, 12> DeadPasses;
-
- // If this is a on the fly manager then it does not have TPM.
- if (!TPM)
- return;
-
- TPM->collectLastUses(DeadPasses, P);
-
- if (PassDebugging >= Details && !DeadPasses.empty()) {
- dbgs() << " -*- '" << P->getPassName();
- dbgs() << "' is the last user of following pass instances.";
- dbgs() << " Free these instances\n";
- }
-
- for (SmallVectorImpl<Pass *>::iterator I = DeadPasses.begin(),
- E = DeadPasses.end(); I != E; ++I)
- freePass(*I, Msg, DBG_STR);
-}
-
-void PMDataManager::freePass(Pass *P, StringRef Msg,
- enum PassDebuggingString DBG_STR) {
- dumpPassInfo(P, FREEING_MSG, DBG_STR, Msg);
-
- {
- // If the pass crashes releasing memory, remember this.
- PassManagerPrettyStackEntry X(P);
- TimeRegion PassTimer(getPassTimer(P));
-
- P->releaseMemory();
- }
-
- AnalysisID PI = P->getPassID();
- if (const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(PI)) {
- // Remove the pass itself (if it is not already removed).
- AvailableAnalysis.erase(PI);
-
- // Remove all interfaces this pass implements, for which it is also
- // listed as the available implementation.
- const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented();
- for (unsigned i = 0, e = II.size(); i != e; ++i) {
- DenseMap<AnalysisID, Pass*>::iterator Pos =
- AvailableAnalysis.find(II[i]->getTypeInfo());
- if (Pos != AvailableAnalysis.end() && Pos->second == P)
- AvailableAnalysis.erase(Pos);
- }
- }
-}
-
-/// Add pass P into the PassVector. Update
-/// AvailableAnalysis appropriately if ProcessAnalysis is true.
-void PMDataManager::add(Pass *P, bool ProcessAnalysis) {
- // This manager is going to manage pass P. Set up analysis resolver
- // to connect them.
- AnalysisResolver *AR = new AnalysisResolver(*this);
- P->setResolver(AR);
-
- // 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.
- SmallVector<Pass *, 12> TransferLastUses;
-
- if (!ProcessAnalysis) {
- // Add pass
- PassVector.push_back(P);
- return;
- }
-
- // At the moment, this pass is the last user of all required passes.
- SmallVector<Pass *, 12> LastUses;
- SmallVector<Pass *, 8> RequiredPasses;
- SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable;
-
- unsigned PDepth = this->getDepth();
-
- collectRequiredAnalysis(RequiredPasses,
- ReqAnalysisNotAvailable, P);
- for (SmallVectorImpl<Pass *>::iterator I = RequiredPasses.begin(),
- E = RequiredPasses.end(); I != E; ++I) {
- Pass *PRequired = *I;
- unsigned RDepth = 0;
-
- assert(PRequired->getResolver() && "Analysis Resolver is not set");
- PMDataManager &DM = PRequired->getResolver()->getPMDataManager();
- RDepth = DM.getDepth();
-
- if (PDepth == RDepth)
- LastUses.push_back(PRequired);
- else if (PDepth > RDepth) {
- // Let the parent claim responsibility of last use
- TransferLastUses.push_back(PRequired);
- // Keep track of higher level analysis used by this manager.
- HigherLevelAnalysis.push_back(PRequired);
- } else
- llvm_unreachable("Unable to accommodate Required Pass");
- }
-
- // Set P as P's last user until someone starts using P.
- // However, if P is a Pass Manager then it does not need
- // to record its last user.
- if (P->getAsPMDataManager() == 0)
- LastUses.push_back(P);
- TPM->setLastUser(LastUses, P);
-
- if (!TransferLastUses.empty()) {
- Pass *My_PM = getAsPass();
- TPM->setLastUser(TransferLastUses, My_PM);
- TransferLastUses.clear();
- }
-
- // Now, take care of required analyses that are not available.
- for (SmallVectorImpl<AnalysisID>::iterator
- I = ReqAnalysisNotAvailable.begin(),
- E = ReqAnalysisNotAvailable.end() ;I != E; ++I) {
- const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
- Pass *AnalysisPass = PI->createPass();
- this->addLowerLevelRequiredPass(P, AnalysisPass);
- }
-
- // Take a note of analysis required and made available by this pass.
- // Remove the analysis not preserved by this pass
- removeNotPreservedAnalysis(P);
- recordAvailableAnalysis(P);
-
- // Add pass
- PassVector.push_back(P);
-}
-
-
-/// Populate RP with analysis pass that are required by
-/// pass P and are available. Populate RP_NotAvail with analysis
-/// pass that are required by pass P but are not available.
-void PMDataManager::collectRequiredAnalysis(SmallVectorImpl<Pass *> &RP,
- SmallVectorImpl<AnalysisID> &RP_NotAvail,
- Pass *P) {
- AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
- const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
- for (AnalysisUsage::VectorType::const_iterator
- I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) {
- if (Pass *AnalysisPass = findAnalysisPass(*I, true))
- RP.push_back(AnalysisPass);
- else
- RP_NotAvail.push_back(*I);
- }
-
- const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet();
- for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(),
- E = IDs.end(); I != E; ++I) {
- if (Pass *AnalysisPass = findAnalysisPass(*I, true))
- RP.push_back(AnalysisPass);
- else
- RP_NotAvail.push_back(*I);
- }
-}
-
-// 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 PMDataManager::initializeAnalysisImpl(Pass *P) {
- AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
-
- for (AnalysisUsage::VectorType::const_iterator
- I = AnUsage->getRequiredSet().begin(),
- E = AnUsage->getRequiredSet().end(); I != E; ++I) {
- Pass *Impl = findAnalysisPass(*I, true);
- if (Impl == 0)
- // This may be analysis pass that is initialized on the fly.
- // If that is not the case then it will raise an assert when it is used.
- continue;
- AnalysisResolver *AR = P->getResolver();
- assert(AR && "Analysis Resolver is not set");
- AR->addAnalysisImplsPair(*I, Impl);
- }
-}
-
-/// Find the pass that implements Analysis AID. If desired pass is not found
-/// then return NULL.
-Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) {
-
- // Check if AvailableAnalysis map has one entry.
- DenseMap<AnalysisID, Pass*>::const_iterator I = AvailableAnalysis.find(AID);
-
- if (I != AvailableAnalysis.end())
- return I->second;
-
- // Search Parents through TopLevelManager
- if (SearchParent)
- return TPM->findAnalysisPass(AID);
-
- return NULL;
-}
-
-// Print list of passes that are last used by P.
-void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{
-
- SmallVector<Pass *, 12> LUses;
-
- // If this is a on the fly manager then it does not have TPM.
- if (!TPM)
- return;
-
- TPM->collectLastUses(LUses, P);
-
- for (SmallVectorImpl<Pass *>::iterator I = LUses.begin(),
- E = LUses.end(); I != E; ++I) {
- llvm::dbgs() << "--" << std::string(Offset*2, ' ');
- (*I)->dumpPassStructure(0);
- }
-}
-
-void PMDataManager::dumpPassArguments() const {
- for (SmallVectorImpl<Pass *>::const_iterator I = PassVector.begin(),
- E = PassVector.end(); I != E; ++I) {
- if (PMDataManager *PMD = (*I)->getAsPMDataManager())
- PMD->dumpPassArguments();
- else
- if (const PassInfo *PI =
- PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID()))
- if (!PI->isAnalysisGroup())
- dbgs() << " -" << PI->getPassArgument();
- }
-}
-
-void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1,
- enum PassDebuggingString S2,
- StringRef Msg) {
- if (PassDebugging < Executions)
- return;
- dbgs() << (void*)this << std::string(getDepth()*2+1, ' ');
- switch (S1) {
- case EXECUTION_MSG:
- dbgs() << "Executing Pass '" << P->getPassName();
- break;
- case MODIFICATION_MSG:
- dbgs() << "Made Modification '" << P->getPassName();
- break;
- case FREEING_MSG:
- dbgs() << " Freeing Pass '" << P->getPassName();
- break;
- default:
- break;
- }
- switch (S2) {
- case ON_BASICBLOCK_MSG:
- dbgs() << "' on BasicBlock '" << Msg << "'...\n";
- break;
- case ON_FUNCTION_MSG:
- dbgs() << "' on Function '" << Msg << "'...\n";
- break;
- case ON_MODULE_MSG:
- dbgs() << "' on Module '" << Msg << "'...\n";
- break;
- case ON_REGION_MSG:
- dbgs() << "' on Region '" << Msg << "'...\n";
- break;
- case ON_LOOP_MSG:
- dbgs() << "' on Loop '" << Msg << "'...\n";
- break;
- case ON_CG_MSG:
- dbgs() << "' on Call Graph Nodes '" << Msg << "'...\n";
- break;
- default:
- break;
- }
-}
-
-void PMDataManager::dumpRequiredSet(const Pass *P) const {
- if (PassDebugging < Details)
- return;
-
- AnalysisUsage analysisUsage;
- P->getAnalysisUsage(analysisUsage);
- dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet());
-}
-
-void PMDataManager::dumpPreservedSet(const Pass *P) const {
- if (PassDebugging < Details)
- return;
-
- AnalysisUsage analysisUsage;
- P->getAnalysisUsage(analysisUsage);
- dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet());
-}
-
-void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
- const AnalysisUsage::VectorType &Set) const {
- assert(PassDebugging >= Details);
- if (Set.empty())
- return;
- dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:";
- for (unsigned i = 0; i != Set.size(); ++i) {
- if (i) dbgs() << ',';
- const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(Set[i]);
- if (!PInf) {
- // Some preserved passes, such as AliasAnalysis, may not be initialized by
- // all drivers.
- dbgs() << " Uninitialized Pass";
- continue;
- }
- dbgs() << ' ' << PInf->getPassName();
- }
- dbgs() << '\n';
-}
-
-/// 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.
-/// This should be handled by specific pass manager.
-void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
- if (TPM) {
- TPM->dumpArguments();
- TPM->dumpPasses();
- }
-
- // Module Level pass may required Function Level analysis info
- // (e.g. dominator info). Pass manager uses on the fly function pass manager
- // to provide this on demand. In that case, in Pass manager terminology,
- // module level pass is requiring lower level analysis info managed by
- // lower level pass manager.
-
- // When Pass manager is not able to order required analysis info, Pass manager
- // checks whether any lower level manager will be able to provide this
- // analysis info on demand or not.
-#ifndef NDEBUG
- dbgs() << "Unable to schedule '" << RequiredPass->getPassName();
- dbgs() << "' required by '" << P->getPassName() << "'\n";
-#endif
- llvm_unreachable("Unable to schedule pass");
-}
-
-Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) {
- llvm_unreachable("Unable to find on the fly pass");
-}
-
-// Destructor
-PMDataManager::~PMDataManager() {
- for (SmallVectorImpl<Pass *>::iterator I = PassVector.begin(),
- E = PassVector.end(); I != E; ++I)
- delete *I;
-}
-
-//===----------------------------------------------------------------------===//
-// NOTE: Is this the right place to define this method ?
-// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist.
-Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const {
- return PM.findAnalysisPass(ID, dir);
-}
-
-Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI,
- Function &F) {
- return PM.getOnTheFlyPass(P, AnalysisPI, F);
-}
-
-//===----------------------------------------------------------------------===//
-// BBPassManager implementation
-
-/// Execute all of the passes scheduled for execution by invoking
-/// runOnBasicBlock method. Keep track of whether any of the passes modifies
-/// the function, and if so, return true.
-bool BBPassManager::runOnFunction(Function &F) {
- if (F.isDeclaration())
- return false;
-
- bool Changed = doInitialization(F);
-
- for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- BasicBlockPass *BP = getContainedPass(Index);
- bool LocalChanged = false;
-
- dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName());
- dumpRequiredSet(BP);
-
- initializeAnalysisImpl(BP);
-
- {
- // If the pass crashes, remember this.
- PassManagerPrettyStackEntry X(BP, *I);
- TimeRegion PassTimer(getPassTimer(BP));
-
- LocalChanged |= BP->runOnBasicBlock(*I);
- }
-
- Changed |= LocalChanged;
- if (LocalChanged)
- dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
- I->getName());
- dumpPreservedSet(BP);
-
- verifyPreservedAnalysis(BP);
- removeNotPreservedAnalysis(BP);
- recordAvailableAnalysis(BP);
- removeDeadPasses(BP, I->getName(), ON_BASICBLOCK_MSG);
- }
-
- return doFinalization(F) || Changed;
-}
-
-// Implement doInitialization and doFinalization
-bool BBPassManager::doInitialization(Module &M) {
- bool Changed = false;
-
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
- Changed |= getContainedPass(Index)->doInitialization(M);
-
- return Changed;
-}
-
-bool BBPassManager::doFinalization(Module &M) {
- bool Changed = false;
-
- for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
- Changed |= getContainedPass(Index)->doFinalization(M);
-
- return Changed;
-}
-
-bool BBPassManager::doInitialization(Function &F) {
- bool Changed = false;
-
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- BasicBlockPass *BP = getContainedPass(Index);
- Changed |= BP->doInitialization(F);
- }
-
- return Changed;
-}
-
-bool BBPassManager::doFinalization(Function &F) {
- bool Changed = false;
-
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- BasicBlockPass *BP = getContainedPass(Index);
- Changed |= BP->doFinalization(F);
- }
-
- return Changed;
-}
-
-
-//===----------------------------------------------------------------------===//
-// FunctionPassManager implementation
-
-/// Create new Function pass manager
-FunctionPassManager::FunctionPassManager(Module *m) : M(m) {
- FPM = new FunctionPassManagerImpl();
- // FPM is the top level manager.
- FPM->setTopLevelManager(FPM);
-
- AnalysisResolver *AR = new AnalysisResolver(*FPM);
- FPM->setResolver(AR);
-}
-
-FunctionPassManager::~FunctionPassManager() {
- delete FPM;
-}
-
-/// add - Add a pass to the queue of passes to run. This passes
-/// ownership of the Pass to the PassManager. When the
-/// PassManager_X is destroyed, the pass will be destroyed as well, so
-/// there is no need to delete the pass. (TODO delete passes.)
-/// This implies that all passes MUST be allocated with 'new'.
-void FunctionPassManager::add(Pass *P) {
- FPM->add(P);
-}
-
-/// run - Execute all of the passes scheduled for execution. Keep
-/// track of whether any of the passes modifies the function, and if
-/// so, return true.
-///
-bool FunctionPassManager::run(Function &F) {
- if (F.isMaterializable()) {
- std::string errstr;
- if (F.Materialize(&errstr))
- report_fatal_error("Error reading bitcode file: " + Twine(errstr));
- }
- return FPM->run(F);
-}
-
-
-/// doInitialization - Run all of the initializers for the function passes.
-///
-bool FunctionPassManager::doInitialization() {
- return FPM->doInitialization(*M);
-}
-
-/// doFinalization - Run all of the finalizers for the function passes.
-///
-bool FunctionPassManager::doFinalization() {
- return FPM->doFinalization(*M);
-}
-
-//===----------------------------------------------------------------------===//
-// FunctionPassManagerImpl implementation
-//
-bool FunctionPassManagerImpl::doInitialization(Module &M) {
- bool Changed = false;
-
- dumpArguments();
- dumpPasses();
-
- SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
- for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
- E = IPV.end(); I != E; ++I) {
- Changed |= (*I)->doInitialization(M);
- }
-
- for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
- Changed |= getContainedManager(Index)->doInitialization(M);
-
- return Changed;
-}
-
-bool FunctionPassManagerImpl::doFinalization(Module &M) {
- bool Changed = false;
-
- for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index)
- Changed |= getContainedManager(Index)->doFinalization(M);
-
- SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
- for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
- E = IPV.end(); I != E; ++I) {
- Changed |= (*I)->doFinalization(M);
- }
-
- return Changed;
-}
-
-/// cleanup - After running all passes, clean up pass manager cache.
-void FPPassManager::cleanup() {
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- FunctionPass *FP = getContainedPass(Index);
- AnalysisResolver *AR = FP->getResolver();
- assert(AR && "Analysis Resolver is not set");
- AR->clearAnalysisImpls();
- }
-}
-
-void FunctionPassManagerImpl::releaseMemoryOnTheFly() {
- if (!wasRun)
- return;
- for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
- FPPassManager *FPPM = getContainedManager(Index);
- for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) {
- FPPM->getContainedPass(Index)->releaseMemory();
- }
- }
- wasRun = false;
-}
-
-// Execute all the passes managed by this top level manager.
-// Return true if any function is modified by a pass.
-bool FunctionPassManagerImpl::run(Function &F) {
- bool Changed = false;
- TimingInfo::createTheTimeInfo();
-
- initializeAllAnalysisInfo();
- for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
- Changed |= getContainedManager(Index)->runOnFunction(F);
-
- for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
- getContainedManager(Index)->cleanup();
-
- wasRun = true;
- return Changed;
-}
-
-//===----------------------------------------------------------------------===//
-// FPPassManager implementation
-
-char FPPassManager::ID = 0;
-/// Print passes managed by this manager
-void FPPassManager::dumpPassStructure(unsigned Offset) {
- dbgs().indent(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.
-bool FPPassManager::runOnFunction(Function &F) {
- if (F.isDeclaration())
- return false;
-
- bool Changed = false;
-
- // Collect inherited analysis from Module level pass manager.
- populateInheritedAnalysis(TPM->activeStack);
-
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- FunctionPass *FP = getContainedPass(Index);
- bool LocalChanged = false;
-
- dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName());
- dumpRequiredSet(FP);
-
- initializeAnalysisImpl(FP);
-
- {
- PassManagerPrettyStackEntry X(FP, F);
- TimeRegion PassTimer(getPassTimer(FP));
-
- LocalChanged |= FP->runOnFunction(F);
- }
-
- Changed |= LocalChanged;
- if (LocalChanged)
- dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName());
- dumpPreservedSet(FP);
-
- verifyPreservedAnalysis(FP);
- removeNotPreservedAnalysis(FP);
- recordAvailableAnalysis(FP);
- removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG);
- }
- return Changed;
-}
-
-bool FPPassManager::runOnModule(Module &M) {
- bool Changed = false;
-
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- Changed |= runOnFunction(*I);
-
- return Changed;
-}
-
-bool FPPassManager::doInitialization(Module &M) {
- bool Changed = false;
-
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
- Changed |= getContainedPass(Index)->doInitialization(M);
-
- return Changed;
-}
-
-bool FPPassManager::doFinalization(Module &M) {
- bool Changed = false;
-
- for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
- Changed |= getContainedPass(Index)->doFinalization(M);
-
- return Changed;
-}
-
-//===----------------------------------------------------------------------===//
-// MPPassManager implementation
-
-/// Execute all of the passes scheduled for execution by invoking
-/// runOnModule method. Keep track of whether any of the passes modifies
-/// the module, and if so, return true.
-bool
-MPPassManager::runOnModule(Module &M) {
- bool Changed = false;
-
- // Initialize on-the-fly passes
- for (std::map<Pass *, FunctionPassManagerImpl *>::iterator
- I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end();
- I != E; ++I) {
- FunctionPassManagerImpl *FPP = I->second;
- Changed |= FPP->doInitialization(M);
- }
-
- // Initialize module passes
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
- Changed |= getContainedPass(Index)->doInitialization(M);
-
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- ModulePass *MP = getContainedPass(Index);
- bool LocalChanged = false;
-
- dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier());
- dumpRequiredSet(MP);
-
- initializeAnalysisImpl(MP);
-
- {
- PassManagerPrettyStackEntry X(MP, M);
- TimeRegion PassTimer(getPassTimer(MP));
-
- LocalChanged |= MP->runOnModule(M);
- }
-
- Changed |= LocalChanged;
- if (LocalChanged)
- dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
- M.getModuleIdentifier());
- dumpPreservedSet(MP);
-
- verifyPreservedAnalysis(MP);
- removeNotPreservedAnalysis(MP);
- recordAvailableAnalysis(MP);
- removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG);
- }
-
- // Finalize module passes
- for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
- Changed |= getContainedPass(Index)->doFinalization(M);
-
- // Finalize on-the-fly passes
- for (std::map<Pass *, FunctionPassManagerImpl *>::iterator
- I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end();
- I != E; ++I) {
- FunctionPassManagerImpl *FPP = I->second;
- // We don't know when is the last time an on-the-fly pass is run,
- // so we need to releaseMemory / finalize here
- FPP->releaseMemoryOnTheFly();
- Changed |= FPP->doFinalization(M);
- }
-
- return Changed;
-}
-
-/// 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.
-void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
- assert(P->getPotentialPassManagerType() == PMT_ModulePassManager &&
- "Unable to handle Pass that requires lower level Analysis pass");
- assert((P->getPotentialPassManagerType() <
- RequiredPass->getPotentialPassManagerType()) &&
- "Unable to handle Pass that requires lower level Analysis pass");
-
- FunctionPassManagerImpl *FPP = OnTheFlyManagers[P];
- if (!FPP) {
- FPP = new FunctionPassManagerImpl();
- // FPP is the top level manager.
- FPP->setTopLevelManager(FPP);
-
- OnTheFlyManagers[P] = FPP;
- }
- FPP->add(RequiredPass);
-
- // Register P as the last user of RequiredPass.
- if (RequiredPass) {
- SmallVector<Pass *, 1> LU;
- LU.push_back(RequiredPass);
- FPP->setLastUser(LU, P);
- }
-}
-
-/// Return function pass corresponding to PassInfo PI, that is
-/// required by module pass MP. Instantiate analysis pass, by using
-/// its runOnFunction() for function F.
-Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){
- FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP];
- assert(FPP && "Unable to find on the fly pass");
-
- FPP->releaseMemoryOnTheFly();
- FPP->run(F);
- return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI);
-}
-
-
-//===----------------------------------------------------------------------===//
-// PassManagerImpl implementation
-
-//
-/// 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 PassManagerImpl::run(Module &M) {
- bool Changed = false;
- TimingInfo::createTheTimeInfo();
-
- dumpArguments();
- dumpPasses();
-
- SmallVectorImpl<ImmutablePass *>& IPV = getImmutablePasses();
- for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
- E = IPV.end(); I != E; ++I) {
- Changed |= (*I)->doInitialization(M);
- }
-
- initializeAllAnalysisInfo();
- for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
- Changed |= getContainedManager(Index)->runOnModule(M);
-
- for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(),
- E = IPV.end(); I != E; ++I) {
- Changed |= (*I)->doFinalization(M);
- }
-
- return Changed;
-}
-
-//===----------------------------------------------------------------------===//
-// PassManager implementation
-
-/// Create new pass manager
-PassManager::PassManager() {
- PM = new PassManagerImpl();
- // PM is the top level manager
- PM->setTopLevelManager(PM);
-}
-
-PassManager::~PassManager() {
- delete PM;
-}
-
-/// add - Add a pass to the queue of passes to run. This passes ownership of
-/// the Pass to the PassManager. When the PassManager is destroyed, the pass
-/// will be destroyed as well, so there is no need to delete the pass. This
-/// implies that all passes MUST be allocated with 'new'.
-void PassManager::add(Pass *P) {
- PM->add(P);
-}
-
-/// 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 PassManager::run(Module &M) {
- return PM->run(M);
-}
-
-//===----------------------------------------------------------------------===//
-// TimingInfo implementation
-
-bool llvm::TimePassesIsEnabled = false;
-static cl::opt<bool,true>
-EnableTiming("time-passes", cl::location(TimePassesIsEnabled),
- cl::desc("Time each pass, printing elapsed time for each on exit"));
-
-// 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.
-void TimingInfo::createTheTimeInfo() {
- if (!TimePassesIsEnabled || TheTimeInfo) return;
-
- // Constructed the first time this is called, iff -time-passes is enabled.
- // This guarantees that the object will be constructed before static globals,
- // thus it will be destroyed before them.
- static ManagedStatic<TimingInfo> TTI;
- TheTimeInfo = &*TTI;
-}
-
-/// If TimingInfo is enabled then start pass timer.
-Timer *llvm::getPassTimer(Pass *P) {
- if (TheTimeInfo)
- return TheTimeInfo->getPassTimer(P);
- return 0;
-}
-
-//===----------------------------------------------------------------------===//
-// PMStack implementation
-//
-
-// Pop Pass Manager from the stack and clear its analysis info.
-void PMStack::pop() {
-
- PMDataManager *Top = this->top();
- Top->initializeAnalysisInfo();
-
- S.pop_back();
-}
-
-// Push PM on the stack and set its top level manager.
-void PMStack::push(PMDataManager *PM) {
- assert(PM && "Unable to push. Pass Manager expected");
- assert(PM->getDepth()==0 && "Pass Manager depth set too early");
-
- if (!this->empty()) {
- assert(PM->getPassManagerType() > this->top()->getPassManagerType()
- && "pushing bad pass manager to PMStack");
- PMTopLevelManager *TPM = this->top()->getTopLevelManager();
-
- assert(TPM && "Unable to find top level manager");
- TPM->addIndirectPassManager(PM);
- PM->setTopLevelManager(TPM);
- PM->setDepth(this->top()->getDepth()+1);
- } else {
- assert((PM->getPassManagerType() == PMT_ModulePassManager
- || PM->getPassManagerType() == PMT_FunctionPassManager)
- && "pushing bad pass manager to PMStack");
- PM->setDepth(1);
- }
-
- S.push_back(PM);
-}
-
-// Dump content of the pass manager stack.
-void PMStack::dump() const {
- for (std::vector<PMDataManager *>::const_iterator I = S.begin(),
- E = S.end(); I != E; ++I)
- dbgs() << (*I)->getAsPass()->getPassName() << ' ';
-
- if (!S.empty())
- dbgs() << '\n';
-}
-
-/// Find appropriate Module Pass Manager in the PM Stack and
-/// add self into that manager.
-void ModulePass::assignPassManager(PMStack &PMS,
- PassManagerType PreferredType) {
- // Find Module Pass Manager
- while (!PMS.empty()) {
- PassManagerType TopPMType = PMS.top()->getPassManagerType();
- if (TopPMType == PreferredType)
- break; // We found desired pass manager
- else if (TopPMType > PMT_ModulePassManager)
- PMS.pop(); // Pop children pass managers
- else
- break;
- }
- assert(!PMS.empty() && "Unable to find appropriate Pass Manager");
- PMS.top()->add(this);
-}
-
-/// Find appropriate Function Pass Manager or Call Graph Pass Manager
-/// in the PM Stack and add self into that manager.
-void FunctionPass::assignPassManager(PMStack &PMS,
- PassManagerType PreferredType) {
-
- // Find Function Pass Manager
- while (!PMS.empty()) {
- if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager)
- PMS.pop();
- else
- break;
- }
-
- // Create new Function Pass Manager if needed.
- FPPassManager *FPP;
- if (PMS.top()->getPassManagerType() == PMT_FunctionPassManager) {
- FPP = (FPPassManager *)PMS.top();
- } else {
- assert(!PMS.empty() && "Unable to create Function Pass Manager");
- PMDataManager *PMD = PMS.top();
-
- // [1] Create new Function Pass Manager
- FPP = new FPPassManager();
- FPP->populateInheritedAnalysis(PMS);
-
- // [2] Set up new manager's top level manager
- PMTopLevelManager *TPM = PMD->getTopLevelManager();
- TPM->addIndirectPassManager(FPP);
-
- // [3] Assign manager to manage this new manager. This may create
- // and push new managers into PMS
- FPP->assignPassManager(PMS, PMD->getPassManagerType());
-
- // [4] Push new manager into PMS
- PMS.push(FPP);
- }
-
- // Assign FPP as the manager of this pass.
- FPP->add(this);
-}
-
-/// Find appropriate Basic Pass Manager or Call Graph Pass Manager
-/// in the PM Stack and add self into that manager.
-void BasicBlockPass::assignPassManager(PMStack &PMS,
- PassManagerType PreferredType) {
- BBPassManager *BBP;
-
- // Basic Pass Manager is a leaf pass manager. It does not handle
- // any other pass manager.
- if (!PMS.empty() &&
- PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager) {
- BBP = (BBPassManager *)PMS.top();
- } else {
- // If leaf manager is not Basic Block Pass manager then create new
- // basic Block Pass manager.
- assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager");
- PMDataManager *PMD = PMS.top();
-
- // [1] Create new Basic Block Manager
- BBP = new BBPassManager();
-
- // [2] Set up new manager's top level manager
- // Basic Block Pass Manager does not live by itself
- PMTopLevelManager *TPM = PMD->getTopLevelManager();
- TPM->addIndirectPassManager(BBP);
-
- // [3] Assign manager to manage this new manager. This may create
- // and push new managers into PMS
- BBP->assignPassManager(PMS, PreferredType);
-
- // [4] Push new manager into PMS
- PMS.push(BBP);
- }
-
- // Assign BBP as the manager of this pass.
- BBP->add(this);
-}
-
-PassManagerBase::~PassManagerBase() {}
DominatorTreeTest.cpp
IRBuilderTest.cpp
InstructionsTest.cpp
+ LegacyPassManagerTest.cpp
MDBuilderTest.cpp
MetadataTest.cpp
- PassManagerTest.cpp
PatternMatch.cpp
TypeBuilderTest.cpp
TypesTest.cpp
--- /dev/null
+//===- llvm/unittest/IR/LegacyPassManager.cpp - Legacy PassManager tests --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This unit test exercises the legacy pass manager infrastructure. We use the
+// old names as well to ensure that the source-level compatibility wrapper
+// works for out-of-tree code that expects to include llvm/PassManager.h and
+// subclass the core pass classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/PassManager.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/CallGraphSCCPass.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace llvm {
+ void initializeModuleNDMPass(PassRegistry&);
+ void initializeFPassPass(PassRegistry&);
+ void initializeCGPassPass(PassRegistry&);
+ void initializeLPassPass(PassRegistry&);
+ void initializeBPassPass(PassRegistry&);
+
+ namespace {
+ // ND = no deps
+ // NM = no modifications
+ struct ModuleNDNM: public ModulePass {
+ public:
+ static char run;
+ static char ID;
+ ModuleNDNM() : ModulePass(ID) { }
+ virtual bool runOnModule(Module &M) {
+ run++;
+ return false;
+ }
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+ };
+ char ModuleNDNM::ID=0;
+ char ModuleNDNM::run=0;
+
+ struct ModuleNDM : public ModulePass {
+ public:
+ static char run;
+ static char ID;
+ ModuleNDM() : ModulePass(ID) {}
+ virtual bool runOnModule(Module &M) {
+ run++;
+ return true;
+ }
+ };
+ char ModuleNDM::ID=0;
+ char ModuleNDM::run=0;
+
+ struct ModuleNDM2 : public ModulePass {
+ public:
+ static char run;
+ static char ID;
+ ModuleNDM2() : ModulePass(ID) {}
+ virtual bool runOnModule(Module &M) {
+ run++;
+ return true;
+ }
+ };
+ char ModuleNDM2::ID=0;
+ char ModuleNDM2::run=0;
+
+ struct ModuleDNM : public ModulePass {
+ public:
+ static char run;
+ static char ID;
+ ModuleDNM() : ModulePass(ID) {
+ initializeModuleNDMPass(*PassRegistry::getPassRegistry());
+ }
+ virtual bool runOnModule(Module &M) {
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ run++;
+ return false;
+ }
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<ModuleNDM>();
+ AU.setPreservesAll();
+ }
+ };
+ char ModuleDNM::ID=0;
+ char ModuleDNM::run=0;
+
+ template<typename P>
+ struct PassTestBase : public P {
+ protected:
+ static int runc;
+ static bool initialized;
+ static bool finalized;
+ int allocated;
+ void run() {
+ EXPECT_TRUE(initialized);
+ EXPECT_FALSE(finalized);
+ EXPECT_EQ(0, allocated);
+ allocated++;
+ runc++;
+ }
+ public:
+ static char ID;
+ static void finishedOK(int run) {
+ EXPECT_GT(runc, 0);
+ EXPECT_TRUE(initialized);
+ EXPECT_TRUE(finalized);
+ EXPECT_EQ(run, runc);
+ }
+ PassTestBase() : P(ID), allocated(0) {
+ initialized = false;
+ finalized = false;
+ runc = 0;
+ }
+
+ virtual void releaseMemory() {
+ EXPECT_GT(runc, 0);
+ EXPECT_GT(allocated, 0);
+ allocated--;
+ }
+ };
+ template<typename P> char PassTestBase<P>::ID;
+ template<typename P> int PassTestBase<P>::runc;
+ template<typename P> bool PassTestBase<P>::initialized;
+ template<typename P> bool PassTestBase<P>::finalized;
+
+ template<typename T, typename P>
+ struct PassTest : public PassTestBase<P> {
+ public:
+#ifndef _MSC_VER // MSVC complains that Pass is not base class.
+ using llvm::Pass::doInitialization;
+ using llvm::Pass::doFinalization;
+#endif
+ virtual bool doInitialization(T &t) {
+ EXPECT_FALSE(PassTestBase<P>::initialized);
+ PassTestBase<P>::initialized = true;
+ return false;
+ }
+ virtual bool doFinalization(T &t) {
+ EXPECT_FALSE(PassTestBase<P>::finalized);
+ PassTestBase<P>::finalized = true;
+ EXPECT_EQ(0, PassTestBase<P>::allocated);
+ return false;
+ }
+ };
+
+ struct CGPass : public PassTest<CallGraph, CallGraphSCCPass> {
+ public:
+ CGPass() {
+ initializeCGPassPass(*PassRegistry::getPassRegistry());
+ }
+ virtual bool runOnSCC(CallGraphSCC &SCMM) {
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ run();
+ return false;
+ }
+ };
+
+ struct FPass : public PassTest<Module, FunctionPass> {
+ public:
+ virtual bool runOnFunction(Function &F) {
+ // FIXME: PR4112
+ // EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ run();
+ return false;
+ }
+ };
+
+ struct LPass : public PassTestBase<LoopPass> {
+ private:
+ static int initcount;
+ static int fincount;
+ public:
+ LPass() {
+ initializeLPassPass(*PassRegistry::getPassRegistry());
+ initcount = 0; fincount=0;
+ EXPECT_FALSE(initialized);
+ }
+ static void finishedOK(int run, int finalized) {
+ PassTestBase<LoopPass>::finishedOK(run);
+ EXPECT_EQ(run, initcount);
+ EXPECT_EQ(finalized, fincount);
+ }
+ using llvm::Pass::doInitialization;
+ using llvm::Pass::doFinalization;
+ virtual bool doInitialization(Loop* L, LPPassManager &LPM) {
+ initialized = true;
+ initcount++;
+ return false;
+ }
+ virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ run();
+ return false;
+ }
+ virtual bool doFinalization() {
+ fincount++;
+ finalized = true;
+ return false;
+ }
+ };
+ int LPass::initcount=0;
+ int LPass::fincount=0;
+
+ struct BPass : public PassTestBase<BasicBlockPass> {
+ private:
+ static int inited;
+ static int fin;
+ public:
+ static void finishedOK(int run, int N) {
+ PassTestBase<BasicBlockPass>::finishedOK(run);
+ EXPECT_EQ(inited, N);
+ EXPECT_EQ(fin, N);
+ }
+ BPass() {
+ inited = 0;
+ fin = 0;
+ }
+ virtual bool doInitialization(Module &M) {
+ EXPECT_FALSE(initialized);
+ initialized = true;
+ return false;
+ }
+ virtual bool doInitialization(Function &F) {
+ inited++;
+ return false;
+ }
+ virtual bool runOnBasicBlock(BasicBlock &BB) {
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ run();
+ return false;
+ }
+ virtual bool doFinalization(Function &F) {
+ fin++;
+ return false;
+ }
+ virtual bool doFinalization(Module &M) {
+ EXPECT_FALSE(finalized);
+ finalized = true;
+ EXPECT_EQ(0, allocated);
+ return false;
+ }
+ };
+ int BPass::inited=0;
+ int BPass::fin=0;
+
+ struct OnTheFlyTest: public ModulePass {
+ public:
+ static char ID;
+ OnTheFlyTest() : ModulePass(ID) {
+ initializeFPassPass(*PassRegistry::getPassRegistry());
+ }
+ virtual bool runOnModule(Module &M) {
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
+ for (Module::iterator I=M.begin(),E=M.end(); I != E; ++I) {
+ Function &F = *I;
+ {
+ SCOPED_TRACE("Running on the fly function pass");
+ getAnalysis<FPass>(F);
+ }
+ }
+ return false;
+ }
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<FPass>();
+ }
+ };
+ char OnTheFlyTest::ID=0;
+
+ TEST(PassManager, RunOnce) {
+ Module M("test-once", getGlobalContext());
+ struct ModuleNDNM *mNDNM = new ModuleNDNM();
+ struct ModuleDNM *mDNM = new ModuleDNM();
+ struct ModuleNDM *mNDM = new ModuleNDM();
+ struct ModuleNDM2 *mNDM2 = new ModuleNDM2();
+
+ mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
+
+ PassManager Passes;
+ Passes.add(new DataLayout(&M));
+ Passes.add(mNDM2);
+ Passes.add(mNDM);
+ Passes.add(mNDNM);
+ Passes.add(mDNM);
+
+ Passes.run(M);
+ // each pass must be run exactly once, since nothing invalidates them
+ EXPECT_EQ(1, mNDM->run);
+ EXPECT_EQ(1, mNDNM->run);
+ EXPECT_EQ(1, mDNM->run);
+ EXPECT_EQ(1, mNDM2->run);
+ }
+
+ TEST(PassManager, ReRun) {
+ Module M("test-rerun", getGlobalContext());
+ struct ModuleNDNM *mNDNM = new ModuleNDNM();
+ struct ModuleDNM *mDNM = new ModuleDNM();
+ struct ModuleNDM *mNDM = new ModuleNDM();
+ struct ModuleNDM2 *mNDM2 = new ModuleNDM2();
+
+ mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
+
+ PassManager Passes;
+ Passes.add(new DataLayout(&M));
+ Passes.add(mNDM);
+ Passes.add(mNDNM);
+ Passes.add(mNDM2);// invalidates mNDM needed by mDNM
+ Passes.add(mDNM);
+
+ Passes.run(M);
+ // Some passes must be rerun because a pass that modified the
+ // module/function was run in between
+ EXPECT_EQ(2, mNDM->run);
+ EXPECT_EQ(1, mNDNM->run);
+ EXPECT_EQ(1, mNDM2->run);
+ EXPECT_EQ(1, mDNM->run);
+ }
+
+ Module* makeLLVMModule();
+
+ template<typename T>
+ void MemoryTestHelper(int run) {
+ OwningPtr<Module> M(makeLLVMModule());
+ T *P = new T();
+ PassManager Passes;
+ Passes.add(new DataLayout(M.get()));
+ Passes.add(P);
+ Passes.run(*M);
+ T::finishedOK(run);
+ }
+
+ template<typename T>
+ void MemoryTestHelper(int run, int N) {
+ Module *M = makeLLVMModule();
+ T *P = new T();
+ PassManager Passes;
+ Passes.add(new DataLayout(M));
+ Passes.add(P);
+ Passes.run(*M);
+ T::finishedOK(run, N);
+ delete M;
+ }
+
+ TEST(PassManager, Memory) {
+ // SCC#1: test1->test2->test3->test1
+ // SCC#2: test4
+ // SCC#3: indirect call node
+ {
+ SCOPED_TRACE("Callgraph pass");
+ MemoryTestHelper<CGPass>(3);
+ }
+
+ {
+ SCOPED_TRACE("Function pass");
+ MemoryTestHelper<FPass>(4);// 4 functions
+ }
+
+ {
+ SCOPED_TRACE("Loop pass");
+ MemoryTestHelper<LPass>(2, 1); //2 loops, 1 function
+ }
+ {
+ SCOPED_TRACE("Basic block pass");
+ MemoryTestHelper<BPass>(7, 4); //9 basic blocks
+ }
+
+ }
+
+ TEST(PassManager, MemoryOnTheFly) {
+ Module *M = makeLLVMModule();
+ {
+ SCOPED_TRACE("Running OnTheFlyTest");
+ struct OnTheFlyTest *O = new OnTheFlyTest();
+ PassManager Passes;
+ Passes.add(new DataLayout(M));
+ Passes.add(O);
+ Passes.run(*M);
+
+ FPass::finishedOK(4);
+ }
+ delete M;
+ }
+
+ Module* makeLLVMModule() {
+ // Module Construction
+ Module* mod = new Module("test-mem", getGlobalContext());
+ mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
+ "a0:0:64-s0:64:64-f80:128:128");
+ mod->setTargetTriple("x86_64-unknown-linux-gnu");
+
+ // Type Definitions
+ std::vector<Type*>FuncTy_0_args;
+ FunctionType* FuncTy_0 = FunctionType::get(
+ /*Result=*/IntegerType::get(getGlobalContext(), 32),
+ /*Params=*/FuncTy_0_args,
+ /*isVarArg=*/false);
+
+ std::vector<Type*>FuncTy_2_args;
+ FuncTy_2_args.push_back(IntegerType::get(getGlobalContext(), 1));
+ FunctionType* FuncTy_2 = FunctionType::get(
+ /*Result=*/Type::getVoidTy(getGlobalContext()),
+ /*Params=*/FuncTy_2_args,
+ /*isVarArg=*/false);
+
+
+ // Function Declarations
+
+ Function* func_test1 = Function::Create(
+ /*Type=*/FuncTy_0,
+ /*Linkage=*/GlobalValue::ExternalLinkage,
+ /*Name=*/"test1", mod);
+ func_test1->setCallingConv(CallingConv::C);
+ AttributeSet func_test1_PAL;
+ func_test1->setAttributes(func_test1_PAL);
+
+ Function* func_test2 = Function::Create(
+ /*Type=*/FuncTy_0,
+ /*Linkage=*/GlobalValue::ExternalLinkage,
+ /*Name=*/"test2", mod);
+ func_test2->setCallingConv(CallingConv::C);
+ AttributeSet func_test2_PAL;
+ func_test2->setAttributes(func_test2_PAL);
+
+ Function* func_test3 = Function::Create(
+ /*Type=*/FuncTy_0,
+ /*Linkage=*/GlobalValue::ExternalLinkage,
+ /*Name=*/"test3", mod);
+ func_test3->setCallingConv(CallingConv::C);
+ AttributeSet func_test3_PAL;
+ func_test3->setAttributes(func_test3_PAL);
+
+ Function* func_test4 = Function::Create(
+ /*Type=*/FuncTy_2,
+ /*Linkage=*/GlobalValue::ExternalLinkage,
+ /*Name=*/"test4", mod);
+ func_test4->setCallingConv(CallingConv::C);
+ AttributeSet func_test4_PAL;
+ func_test4->setAttributes(func_test4_PAL);
+
+ // Global Variable Declarations
+
+
+ // Constant Definitions
+
+ // Global Variable Definitions
+
+ // Function Definitions
+
+ // Function: test1 (func_test1)
+ {
+
+ BasicBlock* label_entry = BasicBlock::Create(getGlobalContext(), "entry",func_test1,0);
+
+ // Block entry (label_entry)
+ CallInst* int32_3 = CallInst::Create(func_test2, "", label_entry);
+ int32_3->setCallingConv(CallingConv::C);
+ int32_3->setTailCall(false);AttributeSet int32_3_PAL;
+ int32_3->setAttributes(int32_3_PAL);
+
+ ReturnInst::Create(getGlobalContext(), int32_3, label_entry);
+
+ }
+
+ // Function: test2 (func_test2)
+ {
+
+ BasicBlock* label_entry_5 = BasicBlock::Create(getGlobalContext(), "entry",func_test2,0);
+
+ // Block entry (label_entry_5)
+ CallInst* int32_6 = CallInst::Create(func_test3, "", label_entry_5);
+ int32_6->setCallingConv(CallingConv::C);
+ int32_6->setTailCall(false);AttributeSet int32_6_PAL;
+ int32_6->setAttributes(int32_6_PAL);
+
+ ReturnInst::Create(getGlobalContext(), int32_6, label_entry_5);
+
+ }
+
+ // Function: test3 (func_test3)
+ {
+
+ BasicBlock* label_entry_8 = BasicBlock::Create(getGlobalContext(), "entry",func_test3,0);
+
+ // Block entry (label_entry_8)
+ CallInst* int32_9 = CallInst::Create(func_test1, "", label_entry_8);
+ int32_9->setCallingConv(CallingConv::C);
+ int32_9->setTailCall(false);AttributeSet int32_9_PAL;
+ int32_9->setAttributes(int32_9_PAL);
+
+ ReturnInst::Create(getGlobalContext(), int32_9, label_entry_8);
+
+ }
+
+ // Function: test4 (func_test4)
+ {
+ Function::arg_iterator args = func_test4->arg_begin();
+ Value* int1_f = args++;
+ int1_f->setName("f");
+
+ BasicBlock* label_entry_11 = BasicBlock::Create(getGlobalContext(), "entry",func_test4,0);
+ BasicBlock* label_bb = BasicBlock::Create(getGlobalContext(), "bb",func_test4,0);
+ BasicBlock* label_bb1 = BasicBlock::Create(getGlobalContext(), "bb1",func_test4,0);
+ BasicBlock* label_return = BasicBlock::Create(getGlobalContext(), "return",func_test4,0);
+
+ // Block entry (label_entry_11)
+ BranchInst::Create(label_bb, label_entry_11);
+
+ // Block bb (label_bb)
+ BranchInst::Create(label_bb, label_bb1, int1_f, label_bb);
+
+ // Block bb1 (label_bb1)
+ BranchInst::Create(label_bb1, label_return, int1_f, label_bb1);
+
+ // Block return (label_return)
+ ReturnInst::Create(getGlobalContext(), label_return);
+
+ }
+ return mod;
+ }
+
+ }
+}
+
+INITIALIZE_PASS(ModuleNDM, "mndm", "mndm", false, false)
+INITIALIZE_PASS_BEGIN(CGPass, "cgp","cgp", false, false)
+INITIALIZE_PASS_DEPENDENCY(CallGraph)
+INITIALIZE_PASS_END(CGPass, "cgp","cgp", false, false)
+INITIALIZE_PASS(FPass, "fp","fp", false, false)
+INITIALIZE_PASS_BEGIN(LPass, "lp","lp", false, false)
+INITIALIZE_PASS_DEPENDENCY(LoopInfo)
+INITIALIZE_PASS_END(LPass, "lp","lp", false, false)
+INITIALIZE_PASS(BPass, "bp","bp", false, false)
+++ /dev/null
-//===- llvm/unittest/IR/PassManager.cpp - PassManager unit tests ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/PassManager.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/CallGraphSCCPass.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPass.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CallingConv.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/InlineAsm.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-namespace llvm {
- void initializeModuleNDMPass(PassRegistry&);
- void initializeFPassPass(PassRegistry&);
- void initializeCGPassPass(PassRegistry&);
- void initializeLPassPass(PassRegistry&);
- void initializeBPassPass(PassRegistry&);
-
- namespace {
- // ND = no deps
- // NM = no modifications
- struct ModuleNDNM: public ModulePass {
- public:
- static char run;
- static char ID;
- ModuleNDNM() : ModulePass(ID) { }
- virtual bool runOnModule(Module &M) {
- run++;
- return false;
- }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
- };
- char ModuleNDNM::ID=0;
- char ModuleNDNM::run=0;
-
- struct ModuleNDM : public ModulePass {
- public:
- static char run;
- static char ID;
- ModuleNDM() : ModulePass(ID) {}
- virtual bool runOnModule(Module &M) {
- run++;
- return true;
- }
- };
- char ModuleNDM::ID=0;
- char ModuleNDM::run=0;
-
- struct ModuleNDM2 : public ModulePass {
- public:
- static char run;
- static char ID;
- ModuleNDM2() : ModulePass(ID) {}
- virtual bool runOnModule(Module &M) {
- run++;
- return true;
- }
- };
- char ModuleNDM2::ID=0;
- char ModuleNDM2::run=0;
-
- struct ModuleDNM : public ModulePass {
- public:
- static char run;
- static char ID;
- ModuleDNM() : ModulePass(ID) {
- initializeModuleNDMPass(*PassRegistry::getPassRegistry());
- }
- virtual bool runOnModule(Module &M) {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
- run++;
- return false;
- }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<ModuleNDM>();
- AU.setPreservesAll();
- }
- };
- char ModuleDNM::ID=0;
- char ModuleDNM::run=0;
-
- template<typename P>
- struct PassTestBase : public P {
- protected:
- static int runc;
- static bool initialized;
- static bool finalized;
- int allocated;
- void run() {
- EXPECT_TRUE(initialized);
- EXPECT_FALSE(finalized);
- EXPECT_EQ(0, allocated);
- allocated++;
- runc++;
- }
- public:
- static char ID;
- static void finishedOK(int run) {
- EXPECT_GT(runc, 0);
- EXPECT_TRUE(initialized);
- EXPECT_TRUE(finalized);
- EXPECT_EQ(run, runc);
- }
- PassTestBase() : P(ID), allocated(0) {
- initialized = false;
- finalized = false;
- runc = 0;
- }
-
- virtual void releaseMemory() {
- EXPECT_GT(runc, 0);
- EXPECT_GT(allocated, 0);
- allocated--;
- }
- };
- template<typename P> char PassTestBase<P>::ID;
- template<typename P> int PassTestBase<P>::runc;
- template<typename P> bool PassTestBase<P>::initialized;
- template<typename P> bool PassTestBase<P>::finalized;
-
- template<typename T, typename P>
- struct PassTest : public PassTestBase<P> {
- public:
-#ifndef _MSC_VER // MSVC complains that Pass is not base class.
- using llvm::Pass::doInitialization;
- using llvm::Pass::doFinalization;
-#endif
- virtual bool doInitialization(T &t) {
- EXPECT_FALSE(PassTestBase<P>::initialized);
- PassTestBase<P>::initialized = true;
- return false;
- }
- virtual bool doFinalization(T &t) {
- EXPECT_FALSE(PassTestBase<P>::finalized);
- PassTestBase<P>::finalized = true;
- EXPECT_EQ(0, PassTestBase<P>::allocated);
- return false;
- }
- };
-
- struct CGPass : public PassTest<CallGraph, CallGraphSCCPass> {
- public:
- CGPass() {
- initializeCGPassPass(*PassRegistry::getPassRegistry());
- }
- virtual bool runOnSCC(CallGraphSCC &SCMM) {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
- run();
- return false;
- }
- };
-
- struct FPass : public PassTest<Module, FunctionPass> {
- public:
- virtual bool runOnFunction(Function &F) {
- // FIXME: PR4112
- // EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
- run();
- return false;
- }
- };
-
- struct LPass : public PassTestBase<LoopPass> {
- private:
- static int initcount;
- static int fincount;
- public:
- LPass() {
- initializeLPassPass(*PassRegistry::getPassRegistry());
- initcount = 0; fincount=0;
- EXPECT_FALSE(initialized);
- }
- static void finishedOK(int run, int finalized) {
- PassTestBase<LoopPass>::finishedOK(run);
- EXPECT_EQ(run, initcount);
- EXPECT_EQ(finalized, fincount);
- }
- using llvm::Pass::doInitialization;
- using llvm::Pass::doFinalization;
- virtual bool doInitialization(Loop* L, LPPassManager &LPM) {
- initialized = true;
- initcount++;
- return false;
- }
- virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
- run();
- return false;
- }
- virtual bool doFinalization() {
- fincount++;
- finalized = true;
- return false;
- }
- };
- int LPass::initcount=0;
- int LPass::fincount=0;
-
- struct BPass : public PassTestBase<BasicBlockPass> {
- private:
- static int inited;
- static int fin;
- public:
- static void finishedOK(int run, int N) {
- PassTestBase<BasicBlockPass>::finishedOK(run);
- EXPECT_EQ(inited, N);
- EXPECT_EQ(fin, N);
- }
- BPass() {
- inited = 0;
- fin = 0;
- }
- virtual bool doInitialization(Module &M) {
- EXPECT_FALSE(initialized);
- initialized = true;
- return false;
- }
- virtual bool doInitialization(Function &F) {
- inited++;
- return false;
- }
- virtual bool runOnBasicBlock(BasicBlock &BB) {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
- run();
- return false;
- }
- virtual bool doFinalization(Function &F) {
- fin++;
- return false;
- }
- virtual bool doFinalization(Module &M) {
- EXPECT_FALSE(finalized);
- finalized = true;
- EXPECT_EQ(0, allocated);
- return false;
- }
- };
- int BPass::inited=0;
- int BPass::fin=0;
-
- struct OnTheFlyTest: public ModulePass {
- public:
- static char ID;
- OnTheFlyTest() : ModulePass(ID) {
- initializeFPassPass(*PassRegistry::getPassRegistry());
- }
- virtual bool runOnModule(Module &M) {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
- for (Module::iterator I=M.begin(),E=M.end(); I != E; ++I) {
- Function &F = *I;
- {
- SCOPED_TRACE("Running on the fly function pass");
- getAnalysis<FPass>(F);
- }
- }
- return false;
- }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<FPass>();
- }
- };
- char OnTheFlyTest::ID=0;
-
- TEST(PassManager, RunOnce) {
- Module M("test-once", getGlobalContext());
- struct ModuleNDNM *mNDNM = new ModuleNDNM();
- struct ModuleDNM *mDNM = new ModuleDNM();
- struct ModuleNDM *mNDM = new ModuleNDM();
- struct ModuleNDM2 *mNDM2 = new ModuleNDM2();
-
- mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
-
- PassManager Passes;
- Passes.add(new DataLayout(&M));
- Passes.add(mNDM2);
- Passes.add(mNDM);
- Passes.add(mNDNM);
- Passes.add(mDNM);
-
- Passes.run(M);
- // each pass must be run exactly once, since nothing invalidates them
- EXPECT_EQ(1, mNDM->run);
- EXPECT_EQ(1, mNDNM->run);
- EXPECT_EQ(1, mDNM->run);
- EXPECT_EQ(1, mNDM2->run);
- }
-
- TEST(PassManager, ReRun) {
- Module M("test-rerun", getGlobalContext());
- struct ModuleNDNM *mNDNM = new ModuleNDNM();
- struct ModuleDNM *mDNM = new ModuleDNM();
- struct ModuleNDM *mNDM = new ModuleNDM();
- struct ModuleNDM2 *mNDM2 = new ModuleNDM2();
-
- mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
-
- PassManager Passes;
- Passes.add(new DataLayout(&M));
- Passes.add(mNDM);
- Passes.add(mNDNM);
- Passes.add(mNDM2);// invalidates mNDM needed by mDNM
- Passes.add(mDNM);
-
- Passes.run(M);
- // Some passes must be rerun because a pass that modified the
- // module/function was run in between
- EXPECT_EQ(2, mNDM->run);
- EXPECT_EQ(1, mNDNM->run);
- EXPECT_EQ(1, mNDM2->run);
- EXPECT_EQ(1, mDNM->run);
- }
-
- Module* makeLLVMModule();
-
- template<typename T>
- void MemoryTestHelper(int run) {
- OwningPtr<Module> M(makeLLVMModule());
- T *P = new T();
- PassManager Passes;
- Passes.add(new DataLayout(M.get()));
- Passes.add(P);
- Passes.run(*M);
- T::finishedOK(run);
- }
-
- template<typename T>
- void MemoryTestHelper(int run, int N) {
- Module *M = makeLLVMModule();
- T *P = new T();
- PassManager Passes;
- Passes.add(new DataLayout(M));
- Passes.add(P);
- Passes.run(*M);
- T::finishedOK(run, N);
- delete M;
- }
-
- TEST(PassManager, Memory) {
- // SCC#1: test1->test2->test3->test1
- // SCC#2: test4
- // SCC#3: indirect call node
- {
- SCOPED_TRACE("Callgraph pass");
- MemoryTestHelper<CGPass>(3);
- }
-
- {
- SCOPED_TRACE("Function pass");
- MemoryTestHelper<FPass>(4);// 4 functions
- }
-
- {
- SCOPED_TRACE("Loop pass");
- MemoryTestHelper<LPass>(2, 1); //2 loops, 1 function
- }
- {
- SCOPED_TRACE("Basic block pass");
- MemoryTestHelper<BPass>(7, 4); //9 basic blocks
- }
-
- }
-
- TEST(PassManager, MemoryOnTheFly) {
- Module *M = makeLLVMModule();
- {
- SCOPED_TRACE("Running OnTheFlyTest");
- struct OnTheFlyTest *O = new OnTheFlyTest();
- PassManager Passes;
- Passes.add(new DataLayout(M));
- Passes.add(O);
- Passes.run(*M);
-
- FPass::finishedOK(4);
- }
- delete M;
- }
-
- Module* makeLLVMModule() {
- // Module Construction
- Module* mod = new Module("test-mem", getGlobalContext());
- mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
- "a0:0:64-s0:64:64-f80:128:128");
- mod->setTargetTriple("x86_64-unknown-linux-gnu");
-
- // Type Definitions
- std::vector<Type*>FuncTy_0_args;
- FunctionType* FuncTy_0 = FunctionType::get(
- /*Result=*/IntegerType::get(getGlobalContext(), 32),
- /*Params=*/FuncTy_0_args,
- /*isVarArg=*/false);
-
- std::vector<Type*>FuncTy_2_args;
- FuncTy_2_args.push_back(IntegerType::get(getGlobalContext(), 1));
- FunctionType* FuncTy_2 = FunctionType::get(
- /*Result=*/Type::getVoidTy(getGlobalContext()),
- /*Params=*/FuncTy_2_args,
- /*isVarArg=*/false);
-
-
- // Function Declarations
-
- Function* func_test1 = Function::Create(
- /*Type=*/FuncTy_0,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"test1", mod);
- func_test1->setCallingConv(CallingConv::C);
- AttributeSet func_test1_PAL;
- func_test1->setAttributes(func_test1_PAL);
-
- Function* func_test2 = Function::Create(
- /*Type=*/FuncTy_0,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"test2", mod);
- func_test2->setCallingConv(CallingConv::C);
- AttributeSet func_test2_PAL;
- func_test2->setAttributes(func_test2_PAL);
-
- Function* func_test3 = Function::Create(
- /*Type=*/FuncTy_0,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"test3", mod);
- func_test3->setCallingConv(CallingConv::C);
- AttributeSet func_test3_PAL;
- func_test3->setAttributes(func_test3_PAL);
-
- Function* func_test4 = Function::Create(
- /*Type=*/FuncTy_2,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"test4", mod);
- func_test4->setCallingConv(CallingConv::C);
- AttributeSet func_test4_PAL;
- func_test4->setAttributes(func_test4_PAL);
-
- // Global Variable Declarations
-
-
- // Constant Definitions
-
- // Global Variable Definitions
-
- // Function Definitions
-
- // Function: test1 (func_test1)
- {
-
- BasicBlock* label_entry = BasicBlock::Create(getGlobalContext(), "entry",func_test1,0);
-
- // Block entry (label_entry)
- CallInst* int32_3 = CallInst::Create(func_test2, "", label_entry);
- int32_3->setCallingConv(CallingConv::C);
- int32_3->setTailCall(false);AttributeSet int32_3_PAL;
- int32_3->setAttributes(int32_3_PAL);
-
- ReturnInst::Create(getGlobalContext(), int32_3, label_entry);
-
- }
-
- // Function: test2 (func_test2)
- {
-
- BasicBlock* label_entry_5 = BasicBlock::Create(getGlobalContext(), "entry",func_test2,0);
-
- // Block entry (label_entry_5)
- CallInst* int32_6 = CallInst::Create(func_test3, "", label_entry_5);
- int32_6->setCallingConv(CallingConv::C);
- int32_6->setTailCall(false);AttributeSet int32_6_PAL;
- int32_6->setAttributes(int32_6_PAL);
-
- ReturnInst::Create(getGlobalContext(), int32_6, label_entry_5);
-
- }
-
- // Function: test3 (func_test3)
- {
-
- BasicBlock* label_entry_8 = BasicBlock::Create(getGlobalContext(), "entry",func_test3,0);
-
- // Block entry (label_entry_8)
- CallInst* int32_9 = CallInst::Create(func_test1, "", label_entry_8);
- int32_9->setCallingConv(CallingConv::C);
- int32_9->setTailCall(false);AttributeSet int32_9_PAL;
- int32_9->setAttributes(int32_9_PAL);
-
- ReturnInst::Create(getGlobalContext(), int32_9, label_entry_8);
-
- }
-
- // Function: test4 (func_test4)
- {
- Function::arg_iterator args = func_test4->arg_begin();
- Value* int1_f = args++;
- int1_f->setName("f");
-
- BasicBlock* label_entry_11 = BasicBlock::Create(getGlobalContext(), "entry",func_test4,0);
- BasicBlock* label_bb = BasicBlock::Create(getGlobalContext(), "bb",func_test4,0);
- BasicBlock* label_bb1 = BasicBlock::Create(getGlobalContext(), "bb1",func_test4,0);
- BasicBlock* label_return = BasicBlock::Create(getGlobalContext(), "return",func_test4,0);
-
- // Block entry (label_entry_11)
- BranchInst::Create(label_bb, label_entry_11);
-
- // Block bb (label_bb)
- BranchInst::Create(label_bb, label_bb1, int1_f, label_bb);
-
- // Block bb1 (label_bb1)
- BranchInst::Create(label_bb1, label_return, int1_f, label_bb1);
-
- // Block return (label_return)
- ReturnInst::Create(getGlobalContext(), label_return);
-
- }
- return mod;
- }
-
- }
-}
-
-INITIALIZE_PASS(ModuleNDM, "mndm", "mndm", false, false)
-INITIALIZE_PASS_BEGIN(CGPass, "cgp","cgp", false, false)
-INITIALIZE_PASS_DEPENDENCY(CallGraph)
-INITIALIZE_PASS_END(CGPass, "cgp","cgp", false, false)
-INITIALIZE_PASS(FPass, "fp","fp", false, false)
-INITIALIZE_PASS_BEGIN(LPass, "lp","lp", false, false)
-INITIALIZE_PASS_DEPENDENCY(LoopInfo)
-INITIALIZE_PASS_END(LPass, "lp","lp", false, false)
-INITIALIZE_PASS(BPass, "bp","bp", false, false)