//===- PassManager.cpp - LLVM Pass Infrastructure Implementation ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Devang Patel and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the LLVM Pass Manager infrastructure.
//
//===----------------------------------------------------------------------===//
#include "llvm/PassManager.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/Support/Streams.h"
#include <vector>
#include <map>
using namespace llvm;
//===----------------------------------------------------------------------===//
// 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 multipe pass managers. They are PassManager,
// FunctionPassManager, ModulePassManager, BasicBlockPassManager. This class
// hierarcy uses multiple inheritance but pass managers do not derive from
// another pass manager.
//
// PassManager and FunctionPassManager are two top level pass manager that
// represents the external interface of this entire pass manager infrastucture.
//
// Important classes :
//
// [o] class PMTopLevelManager;
//
// Two top level managers, PassManager and FunctionPassManager, derive from
// PMTopLevelManager. PMTopLevelManager manages information used by top level
// managers such as last user info.
//
// [o] class PMDataManager;
//
// PMDataManager manages information, e.g. list of available analysis info,
// used by a pass manager to manage execution order of passes. It also provides
// a place to implement common pass manager APIs. All pass managers derive from
// PMDataManager.
//
// [o] class BasicBlockPassManager : public FunctionPass, public PMDataManager;
//
// BasicBlockPassManager 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 FunctionPasses
// and BasicBlockPassManagers.
//
// [o] class ModulePassManager : public Pass, public PMDataManager;
//
// ModulePassManager manages ModulePasses and FunctionPassManagerImpls.
//
// [o] class PassManager;
//
// This is a external interface used by various tools to manages passes. It
// relies on PassManagerImpl to do all the tasks.
//
// [o] class PassManagerImpl : public Pass, public PMDataManager,
// public PMDTopLevelManager
//
// PassManagerImpl is a top level pass manager responsible for managing
// ModulePassManagers.
//===----------------------------------------------------------------------===//
namespace llvm {
//===----------------------------------------------------------------------===//
// PMTopLevelManager
//
/// PMTopLevelManager manages LastUser info and collects common APIs used by
/// top level pass managers.
class PMTopLevelManager {
public:
inline std::vector<Pass *>::iterator passManagersBegin() {
return PassManagers.begin();
}
inline std::vector<Pass *>::iterator passManagersEnd() {
return PassManagers.end();
}
/// Schedule pass P for execution. Make sure that passes required by
/// P are run before P is run. Update analysis info maintained by
/// the manager. Remove dead passes. This is a recursive function.
void schedulePass(Pass *P);
/// This is implemented by top level pass manager and used by
/// schedulePass() to add analysis info passes that are not available.
virtual void addTopLevelPass(Pass *P) = 0;
/// Set pass P as the last user of the given analysis passes.
void setLastUser(std::vector<Pass *> &AnalysisPasses, Pass *P);
/// Collect passes whose last user is P
void collectLastUses(std::vector<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);
virtual ~PMTopLevelManager() {
PassManagers.clear();
}
/// Add immutable pass and initialize it.
inline void addImmutablePass(ImmutablePass *P) {
P->initializePass();
ImmutablePasses.push_back(P);
}
inline std::vector<ImmutablePass *>& getImmutablePasses() {
return ImmutablePasses;
}
void addPassManager(Pass *Manager) {
PassManagers.push_back(Manager);
}
// Add Manager into the list of managers that are not directly
// maintained by this top level pass manager
void addOtherPassManager(Pass *Manager) {
OtherPassManagers.push_back(Manager);
}
private:
/// Collection of pass managers
std::vector<Pass *> PassManagers;
/// Collection of pass managers that are not directly maintained
/// by this pass manager
std::vector<Pass *> OtherPassManagers;
// Map to keep track of last user of the analysis pass.
// LastUser->second is the last user of Lastuser->first.
std::map<Pass *, Pass *> LastUser;
/// Immutable passes are managed by top level manager.
std::vector<ImmutablePass *> ImmutablePasses;
};
/// Set pass P as the last user of the given analysis passes.
voi