//
//===----------------------------------------------------------------------===//
//
-// This file implements the LLVM Pass Manager infrastructure.
+// This file implements the LLVM Pass Manager infrastructure.
//
//===----------------------------------------------------------------------===//
#include "llvm/PassManagers.h"
+#include "llvm/PassManager.h"
+#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Module.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Mutex.h"
-#include "llvm/System/Threading.h"
-#include "llvm-c/Core.h"
#include <algorithm>
#include <cstdio>
#include <map>
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"));
+
+static PassOptionList
+PrintAfter("print-after",
+ llvm::cl::desc("Print IR after specified passes"));
+
+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 void *PassID,
+ PassOptionList &PassesToPrint) {
+ if (const llvm::PassInfo *PI =
+ PassRegistry::getPassRegistry()->getPassInfo(PassID)) {
+ 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 void *PassID) {
+ return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PassID, PrintBefore);
+}
+
+/// This is a utility to check whether a pass should have IR dumped
+/// after it.
+static bool ShouldPrintAfterPass(const void *PassID) {
+ return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PassID, PrintAfter);
+}
+
} // End of llvm namespace
/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
OS << "Releasing pass '";
else
OS << "Running pass '";
-
+
OS << P->getPassName() << "'";
-
+
if (M) {
OS << " on module '" << M->getModuleIdentifier() << "'.\n";
return;
public:
static char ID;
- explicit BBPassManager(int Depth)
- : PMDataManager(Depth), FunctionPass(&ID) {}
+ explicit BBPassManager(int Depth)
+ : PMDataManager(Depth), 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.
return BP;
}
- virtual PassManagerType getPassManagerType() const {
- return PMT_BasicBlockPassManager;
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_BasicBlockPassManager;
}
};
bool wasRun;
public:
static char ID;
- explicit FunctionPassManagerImpl(int Depth) :
- Pass(PT_PassManager, &ID), PMDataManager(Depth),
- PMTopLevelManager(TLM_Function), wasRun(false) { }
+ explicit FunctionPassManagerImpl(int Depth) :
+ Pass(PT_PassManager, ID), PMDataManager(Depth),
+ PMTopLevelManager(new FPPassManager(1)), 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
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();
/// 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; }
Info.setPreservesAll();
}
- inline void addTopLevelPass(Pass *P) {
+ void addTopLevelPass(Pass *P) {
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.
addImmutablePass(IP);
recordAvailableAnalysis(IP);
} else {
- P->assignPassManager(activeStack);
+ P->assignPassManager(activeStack, PMT_FunctionPassManager);
}
}
};
char FunctionPassManagerImpl::ID = 0;
+
//===----------------------------------------------------------------------===//
// MPPassManager
//
public:
static char ID;
explicit MPPassManager(int Depth) :
- Pass(PT_PassManager, &ID), PMDataManager(Depth) { }
+ Pass(PT_PassManager, ID), PMDataManager(Depth) { }
// Delete on the fly managers.
virtual ~MPPassManager() {
- for (std::map<Pass *, FunctionPassManagerImpl *>::iterator
+ for (std::map<Pass *, FunctionPassManagerImpl *>::iterator
I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end();
I != E; ++I) {
FunctionPassManagerImpl *FPP = I->second;
}
}
+ /// 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);
/// through getAnalysis interface.
virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass);
- /// Return function pass corresponding to PassInfo PI, that is
+ /// 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, const PassInfo *PI, Function &F);
+ virtual Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F);
virtual const char *getPassName() const {
return "Module Pass Manager";
return static_cast<ModulePass *>(PassVector[N]);
}
- virtual PassManagerType getPassManagerType() const {
- return PMT_ModulePassManager;
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_ModulePassManager;
}
private:
public:
static char ID;
explicit PassManagerImpl(int Depth) :
- Pass(PT_PassManager, &ID), PMDataManager(Depth),
- PMTopLevelManager(TLM_Pass) { }
+ Pass(PT_PassManager, ID), PMDataManager(Depth),
+ PMTopLevelManager(new MPPassManager(1)) {}
/// 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
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);
Info.setPreservesAll();
}
- inline void addTopLevelPass(Pass *P) {
+ void addTopLevelPass(Pass *P) {
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.
addImmutablePass(IP);
recordAvailableAnalysis(IP);
} else {
- P->assignPassManager(activeStack);
+ P->assignPassManager(activeStack, PMT_ModulePassManager);
}
}
static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex;
class TimingInfo {
- std::map<Pass*, Timer> TimingData;
+ 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...
- TimingData.clear();
+ // 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.
}
// null. It may be called multiple times.
static void createTheTimeInfo();
- /// passStarted - This method creates a timer for the given pass if it doesn't
- /// already have one, and starts the timer.
- Timer *passStarted(Pass *P) {
- if (P->getAsPMDataManager())
+ /// 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);
- std::map<Pass*, Timer>::iterator I = TimingData.find(P);
- if (I == TimingData.end())
- I=TimingData.insert(std::make_pair(P, Timer(P->getPassName(), TG))).first;
- Timer *T = &I->second;
- T->startTimer();
+ Timer *&T = TimingData[P];
+ if (T == 0)
+ T = new Timer(P->getPassName(), TG);
return T;
}
};
// PMTopLevelManager implementation
/// Initialize top level manager. Create first pass manager.
-PMTopLevelManager::PMTopLevelManager(enum TopLevelManagerType t) {
- if (t == TLM_Pass) {
- MPPassManager *MPP = new MPPassManager(1);
- MPP->setTopLevelManager(this);
- addPassManager(MPP);
- activeStack.push(MPP);
- } else if (t == TLM_Function) {
- FPPassManager *FPP = new FPPassManager(1);
- FPP->setTopLevelManager(this);
- addPassManager(FPP);
- activeStack.push(FPP);
- }
+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(SmallVector<Pass *, 12> &AnalysisPasses,
+void PMTopLevelManager::setLastUser(SmallVector<Pass *, 12> &AnalysisPasses,
Pass *P) {
for (SmallVector<Pass *, 12>::iterator I = AnalysisPasses.begin(),
E = AnalysisPasses.end(); I != E; ++I) {
Pass *AP = *I;
LastUser[AP] = P;
-
+
if (P == AP)
continue;
/// Collect passes whose last user is P
void PMTopLevelManager::collectLastUses(SmallVector<Pass *, 12> &LastUses,
Pass *P) {
- DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator DMI =
+ DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator DMI =
InversedLastUser.find(P);
if (DMI == InversedLastUser.end())
return;
AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) {
AnalysisUsage *AnUsage = NULL;
DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P);
- if (DMI != AnUsageMap.end())
+ if (DMI != AnUsageMap.end())
AnUsage = DMI->second;
else {
AnUsage = new AnalysisUsage();
// 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.
- if (P->getPassInfo() &&
- P->getPassInfo()->isAnalysis() && findAnalysisPass(P->getPassInfo())) {
+ const PassInfo *PI =
+ PassRegistry::getPassRegistry()->getPassInfo(P->getPassID());
+ if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) {
delete P;
return;
}
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) {
- AnalysisPass = (*I)->createPass();
+ const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
+ AnalysisPass = PI->createPass();
if (P->getPotentialPassManagerType () ==
AnalysisPass->getPotentialPassManagerType())
// Schedule analysis pass that is managed by the same pass manager.
AnalysisPass->getPotentialPassManagerType()) {
// Schedule analysis pass that is managed by a new manager.
schedulePass(AnalysisPass);
- // Recheck analysis passes to ensure that required analysises that
+ // 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
+ // Do not schedule this analysis. Lower level analsyis
// passes are run on the fly.
delete AnalysisPass;
}
for (SmallVector<ImmutablePass *, 8>::iterator I = ImmutablePasses.begin(),
E = ImmutablePasses.end(); P == NULL && I != E; ++I) {
- const PassInfo *PI = (*I)->getPassInfo();
+ AnalysisID PI = (*I)->getPassID();
if (PI == AID)
P = *I;
// If Pass not found then check the interfaces implemented by Immutable Pass
if (!P) {
+ const PassInfo *PassInf =
+ PassRegistry::getPassRegistry()->getPassInfo(PI);
const std::vector<const PassInfo*> &ImmPI =
- PI->getInterfacesImplemented();
- if (std::find(ImmPI.begin(), ImmPI.end(), AID) != ImmPI.end())
- P = *I;
+ PassInf->getInterfacesImplemented();
+ for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(),
+ EE = ImmPI.end(); II != EE; ++II) {
+ if ((*II)->getTypeInfo() == AID)
+ P = *I;
+ }
}
}
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
for (SmallVector<PMDataManager *, 8>::iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I)
(*I)->initializeAnalysisInfo();
-
+
// Initailize other pass managers
- for (SmallVector<PMDataManager *, 8>::iterator I = IndirectPassManagers.begin(),
- E = IndirectPassManagers.end(); I != E; ++I)
+ for (SmallVector<PMDataManager *, 8>::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 =
+ DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator InvDMI =
InversedLastUser.find(DMI->second);
if (InvDMI != InversedLastUser.end()) {
SmallPtrSet<Pass *, 8> &L = InvDMI->second;
for (SmallVector<PMDataManager *, 8>::iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I)
delete *I;
-
+
for (SmallVector<ImmutablePass *, 8>::iterator
I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
delete *I;
/// Augement AvailableAnalysis by adding analysis made available by pass P.
void PMDataManager::recordAvailableAnalysis(Pass *P) {
- const PassInfo *PI = P->getPassInfo();
- if (PI == 0) return;
-
+ AnalysisID PI = P->getPassID();
+
AvailableAnalysis[PI] = P;
- //This pass is the current implementation of all of the interfaces it
- //implements as well.
- const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented();
+ 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]] = P;
+ AvailableAnalysis[II[i]->getTypeInfo()] = P;
}
// Return true if P preserves high level analysis used by other
AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
if (AnUsage->getPreservesAll())
return true;
-
+
const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
for (SmallVector<Pass *, 8>::iterator I = HigherLevelAnalysis.begin(),
E = HigherLevelAnalysis.end(); I != E; ++I) {
Pass *P1 = *I;
if (P1->getAsImmutablePass() == 0 &&
std::find(PreservedSet.begin(), PreservedSet.end(),
- P1->getPassInfo()) ==
+ P1->getPassID()) ==
PreservedSet.end())
return false;
}
-
+
return true;
}
E = PreservedSet.end(); I != E; ++I) {
AnalysisID AID = *I;
if (Pass *AP = findAnalysisPass(AID, true)) {
-
- Timer *T = 0;
- if (TheTimeInfo) T = TheTimeInfo->passStarted(AP);
+ TimeRegion PassTimer(getPassTimer(AP));
AP->verifyAnalysis();
- if (T) T->stopTimer();
}
}
}
E = AvailableAnalysis.end(); I != E; ) {
std::map<AnalysisID, Pass*>::iterator Info = I++;
if (Info->second->getAsImmutablePass() == 0 &&
- std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
+ std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
PreservedSet.end()) {
// Remove this analysis
if (PassDebugging >= Details) {
if (!InheritedAnalysis[Index])
continue;
- for (std::map<AnalysisID, Pass*>::iterator
+ for (std::map<AnalysisID, Pass*>::iterator
I = InheritedAnalysis[Index]->begin(),
E = InheritedAnalysis[Index]->end(); I != E; ) {
std::map<AnalysisID, Pass *>::iterator Info = I++;
if (Info->second->getAsImmutablePass() == 0 &&
- std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
+ std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
PreservedSet.end()) {
// Remove this analysis
if (PassDebugging >= Details) {
{
// If the pass crashes releasing memory, remember this.
PassManagerPrettyStackEntry X(P);
-
- Timer *T = StartPassTimer(P);
+ TimeRegion PassTimer(getPassTimer(P));
+
P->releaseMemory();
- StopPassTimer(P, T);
}
- if (const PassInfo *PI = P->getPassInfo()) {
+ 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 = PI->getInterfacesImplemented();
+ const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented();
for (unsigned i = 0, e = II.size(); i != e; ++i) {
std::map<AnalysisID, Pass*>::iterator Pos =
- AvailableAnalysis.find(II[i]);
+ AvailableAnalysis.find(II[i]->getTypeInfo());
if (Pos != AvailableAnalysis.end() && Pos->second == P)
AvailableAnalysis.erase(Pos);
}
}
}
-/// Add pass P into the PassVector. Update
+/// 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
unsigned PDepth = this->getDepth();
- collectRequiredAnalysis(RequiredPasses,
+ collectRequiredAnalysis(RequiredPasses,
ReqAnalysisNotAvailable, P);
for (SmallVector<Pass *, 8>::iterator I = RequiredPasses.begin(),
E = RequiredPasses.end(); I != E; ++I) {
TransferLastUses.push_back(PRequired);
// Keep track of higher level analysis used by this manager.
HigherLevelAnalysis.push_back(PRequired);
- } else
+ } else
llvm_unreachable("Unable to accomodate Required Pass");
}
TransferLastUses.clear();
}
- // Now, take care of required analysises that are not available.
- for (SmallVector<AnalysisID, 8>::iterator
- I = ReqAnalysisNotAvailable.begin(),
+ // Now, take care of required analyses that are not available.
+ for (SmallVector<AnalysisID, 8>::iterator
+ I = ReqAnalysisNotAvailable.begin(),
E = ReqAnalysisNotAvailable.end() ;I != E; ++I) {
- Pass *AnalysisPass = (*I)->createPass();
+ const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
+ Pass *AnalysisPass = PI->createPass();
this->addLowerLevelRequiredPass(P, AnalysisPass);
}
Pass *P) {
AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
- for (AnalysisUsage::VectorType::const_iterator
+ for (AnalysisUsage::VectorType::const_iterator
I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) {
if (Pass *AnalysisPass = findAnalysisPass(*I, true))
- RP.push_back(AnalysisPass);
+ RP.push_back(AnalysisPass);
else
RP_NotAvail.push_back(*I);
}
for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(),
E = IDs.end(); I != E; ++I) {
if (Pass *AnalysisPass = findAnalysisPass(*I, true))
- RP.push_back(AnalysisPass);
+ RP.push_back(AnalysisPass);
else
RP_NotAvail.push_back(*I);
}
// Search Parents through TopLevelManager
if (SearchParent)
return TPM->findAnalysisPass(AID);
-
+
return NULL;
}
return;
TPM->collectLastUses(LUses, P);
-
+
for (SmallVector<Pass *, 12>::iterator I = LUses.begin(),
E = LUses.end(); I != E; ++I) {
llvm::dbgs() << "--" << std::string(Offset*2, ' ');
if (PMDataManager *PMD = (*I)->getAsPMDataManager())
PMD->dumpPassArguments();
else
- if (const PassInfo *PI = (*I)->getPassInfo())
+ if (const PassInfo *PI =
+ PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID()))
if (!PI->isAnalysisGroup())
dbgs() << " -" << PI->getPassArgument();
}
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());
dbgs() << (void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:";
for (unsigned i = 0; i != Set.size(); ++i) {
if (i) dbgs() << ',';
- dbgs() << ' ' << Set[i]->getPassName();
+ const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(Set[i]);
+ dbgs() << ' ' << PInf->getPassName();
}
dbgs() << '\n';
}
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 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
+ // 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();
llvm_unreachable("Unable to schedule pass");
}
+Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) {
+ assert(0 && "Unable to find on the fly pass");
+ return NULL;
+}
+
// Destructor
PMDataManager::~PMDataManager() {
for (SmallVector<Pass *, 8>::iterator I = PassVector.begin(),
return PM.findAnalysisPass(ID, dir);
}
-Pass *AnalysisResolver::findImplPass(Pass *P, const PassInfo *AnalysisPI,
+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
+/// 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())
{
// If the pass crashes, remember this.
PassManagerPrettyStackEntry X(BP, *I);
-
- Timer *T = StartPassTimer(BP);
+ TimeRegion PassTimer(getPassTimer(BP));
+
LocalChanged |= BP->runOnBasicBlock(*I);
- StopPassTimer(BP, T);
}
Changed |= LocalChanged;
- if (LocalChanged)
+ if (LocalChanged)
dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
I->getName());
dumpPreservedSet(BP);
delete FPM;
}
+/// addImpl - Add a pass to the queue of passes to run, without
+/// checking whether to add a printer pass.
+void FunctionPassManager::addImpl(Pass *P) {
+ FPM->add(P);
+}
+
/// 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);
+void FunctionPassManager::add(Pass *P) {
+ // If this is a not a function pass, don't add a printer for it.
+ const void *PassID = P->getPassID();
+ if (P->getPassKind() == PT_Function)
+ if (ShouldPrintBeforePass(PassID))
+ addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ")
+ + P->getPassName() + " ***"));
+
+ addImpl(P);
+
+ if (P->getPassKind() == PT_Function)
+ if (ShouldPrintAfterPass(PassID))
+ addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ")
+ + P->getPassName() + " ***"));
}
/// run - Execute all of the passes scheduled for execution. Keep
bool FunctionPassManager::run(Function &F) {
if (F.isMaterializable()) {
std::string errstr;
- if (F.Materialize(&errstr)) {
- llvm_report_error("Error reading bitcode file: " + errstr);
- }
+ if (F.Materialize(&errstr))
+ report_fatal_error("Error reading bitcode file: " + Twine(errstr));
}
return FPM->run(F);
}
}
-/// Execute all of the passes scheduled for execution by invoking
-/// runOnFunction method. Keep track of whether any of the passes modifies
+/// 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())
{
PassManagerPrettyStackEntry X(FP, F);
+ TimeRegion PassTimer(getPassTimer(FP));
- Timer *T = StartPassTimer(FP);
LocalChanged |= FP->runOnFunction(F);
- StopPassTimer(FP, T);
}
Changed |= LocalChanged;
//===----------------------------------------------------------------------===//
// MPPassManager implementation
-/// Execute all of the passes scheduled for execution by invoking
-/// runOnModule method. Keep track of whether any of the passes modifies
+/// 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) {
{
PassManagerPrettyStackEntry X(MP, M);
- Timer *T = StartPassTimer(MP);
+ TimeRegion PassTimer(getPassTimer(MP));
+
LocalChanged |= MP->runOnModule(M);
- StopPassTimer(MP, T);
}
Changed |= LocalChanged;
dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
M.getModuleIdentifier());
dumpPreservedSet(MP);
-
+
verifyPreservedAnalysis(MP);
removeNotPreservedAnalysis(MP);
recordAvailableAnalysis(MP);
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() <
+ assert((P->getPotentialPassManagerType() <
RequiredPass->getPotentialPassManagerType()) &&
"Unable to handle Pass that requires lower level Analysis pass");
FPP->setLastUser(LU, P);
}
-/// Return function pass corresponding to PassInfo PI, that is
+/// 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, const PassInfo *PI, 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);
delete PM;
}
+/// addImpl - Add a pass to the queue of passes to run, without
+/// checking whether to add a printer pass.
+void PassManager::addImpl(Pass *P) {
+ PM->add(P);
+}
+
/// 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);
+ const void* PassID = P->getPassID();
+ if (ShouldPrintBeforePass(PassID))
+ addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump Before ")
+ + P->getPassName() + " ***"));
+
+ addImpl(P);
+
+ if (ShouldPrintAfterPass(PassID))
+ addImpl(P->createPrinterPass(dbgs(), std::string("*** IR Dump After ")
+ + P->getPassName() + " ***"));
}
/// run - Execute all of the passes scheduled for execution. Keep track of
}
/// If TimingInfo is enabled then start pass timer.
-Timer *llvm::StartPassTimer(Pass *P) {
- if (TheTimeInfo)
- return TheTimeInfo->passStarted(P);
+Timer *llvm::getPassTimer(Pass *P) {
+ if (TheTimeInfo)
+ return TheTimeInfo->getPassTimer(P);
return 0;
}
-/// If TimingInfo is enabled then stop pass timer.
-void llvm::StopPassTimer(Pass *P, Timer *T) {
- if (T) T->stopTimer();
-}
-
//===----------------------------------------------------------------------===//
// PMStack implementation
//
}
// Dump content of the pass manager stack.
-void PMStack::dump() {
- for (std::deque<PMDataManager *>::iterator I = S.begin(),
+void PMStack::dump() const {
+ for (std::vector<PMDataManager *>::const_iterator I = S.begin(),
E = S.end(); I != E; ++I)
printf("%s ", (*I)->getAsPass()->getPassName());
}
/// Find appropriate Module Pass Manager in the PM Stack and
-/// add self into that manager.
-void ModulePass::assignPassManager(PMStack &PMS,
+/// add self into that manager.
+void ModulePass::assignPassManager(PMStack &PMS,
PassManagerType PreferredType) {
// Find Module Pass Manager
- while(!PMS.empty()) {
+ while (!PMS.empty()) {
PassManagerType TopPMType = PMS.top()->getPassManagerType();
if (TopPMType == PreferredType)
break; // We found desired pass manager
}
/// Find appropriate Function Pass Manager or Call Graph Pass Manager
-/// in the PM Stack and add self into that manager.
+/// in the PM Stack and add self into that manager.
void FunctionPass::assignPassManager(PMStack &PMS,
PassManagerType PreferredType) {
if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager)
PMS.pop();
else
- break;
+ break;
}
// Create new Function Pass Manager if needed.
}
/// Find appropriate Basic Pass Manager or Call Graph Pass Manager
-/// in the PM Stack and add self into that 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() &&
+ if (!PMS.empty() &&
PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager) {
BBP = (BBPassManager *)PMS.top();
} else {
// [3] Assign manager to manage this new manager. This may create
// and push new managers into PMS
- BBP->assignPassManager(PMS);
+ BBP->assignPassManager(PMS, PreferredType);
// [4] Push new manager into PMS
PMS.push(BBP);
}
PassManagerBase::~PassManagerBase() {}
-
-/*===-- C Bindings --------------------------------------------------------===*/
-
-LLVMPassManagerRef LLVMCreatePassManager() {
- return wrap(new PassManager());
-}
-
-LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M) {
- return wrap(new FunctionPassManager(unwrap(M)));
-}
-
-LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef P) {
- return LLVMCreateFunctionPassManagerForModule(
- reinterpret_cast<LLVMModuleRef>(P));
-}
-
-LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
- return unwrap<PassManager>(PM)->run(*unwrap(M));
-}
-
-LLVMBool LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM) {
- return unwrap<FunctionPassManager>(FPM)->doInitialization();
-}
-
-LLVMBool LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F) {
- return unwrap<FunctionPassManager>(FPM)->run(*unwrap<Function>(F));
-}
-
-LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM) {
- return unwrap<FunctionPassManager>(FPM)->doFinalization();
-}
-
-void LLVMDisposePassManager(LLVMPassManagerRef PM) {
- delete unwrap(PM);
-}