namespace llvm {
+class PMDataManager;
+
//===----------------------------------------------------------------------===//
// PMTopLevelManager
//
return ImmutablePasses;
}
+ void addPassManager(Pass *Manager) {
+ PassManagers.push_back(Manager);
+ }
+
+ // Add Manager into the list of managers that are not directly
+ // maintained by this top level pass manager
+ inline void addIndirectPassManager(PMDataManager *Manager) {
+ IndirectPassManagers.push_back(Manager);
+ }
+
private:
/// Collection of pass managers
std::vector<Pass *> PassManagers;
+ /// Collection of pass managers that are not directly maintained
+ /// by this pass manager
+ std::vector<PMDataManager *> IndirectPassManagers;
+
// 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;
std::vector<ImmutablePass *> ImmutablePasses;
};
-/// Set pass P as the last user of the given analysis passes.
-void PMTopLevelManager::setLastUser(std::vector<Pass *> &AnalysisPasses,
- Pass *P) {
-
- for (std::vector<Pass *>::iterator I = AnalysisPasses.begin(),
- E = AnalysisPasses.end(); I != E; ++I) {
- Pass *AP = *I;
- LastUser[AP] = P;
- // If AP is the last user of other passes then make P last user of
- // such passes.
- for (std::map<Pass *, Pass *>::iterator LUI = LastUser.begin(),
- LUE = LastUser.end(); LUI != LUE; ++LUI) {
- if (LUI->second == AP)
- LastUser[LUI->first] = P;
- }
- }
-
-}
-
-/// Collect passes whose last user is P
-void PMTopLevelManager::collectLastUses(std::vector<Pass *> &LastUses,
- Pass *P) {
- for (std::map<Pass *, Pass *>::iterator LUI = LastUser.begin(),
- LUE = LastUser.end(); LUI != LUE; ++LUI)
- if (LUI->second == P)
- LastUses.push_back(LUI->first);
-}
-
-/// 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
-
- AnalysisUsage AnUsage;
- P->getAnalysisUsage(AnUsage);
- const std::vector<AnalysisID> &RequiredSet = AnUsage.getRequiredSet();
- for (std::vector<AnalysisID>::const_iterator I = RequiredSet.begin(),
- E = RequiredSet.end(); I != E; ++I) {
-
- Pass *AnalysisPass = findAnalysisPass(*I);
- if (!AnalysisPass) {
- // Schedule this analysis run first.
- AnalysisPass = (*I)->createPass();
- schedulePass(AnalysisPass);
- }
- }
-
- // Now all required passes are available.
- addTopLevelPass(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 *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
-
- Pass *P = NULL;
- for (std::vector<ImmutablePass *>::iterator I = ImmutablePasses.begin(),
- E = ImmutablePasses.end(); P == NULL && I != E; ++I) {
- const PassInfo *PI = (*I)->getPassInfo();
- if (PI == AID)
- P = *I;
-
- // If Pass not found then check the interfaces implemented by Immutable Pass
- if (!P) {
- const std::vector<const PassInfo*> &ImmPI =
- PI->getInterfacesImplemented();
- for (unsigned Index = 0, End = ImmPI.size();
- P == NULL && Index != End; ++Index)
- if (ImmPI[Index] == AID)
- P = *I;
- }
- }
-
- if (P)
- return P;
-
- // Check pass managers;
- for (std::vector<Pass *>::iterator I = PassManagers.begin(),
- E = PassManagers.end(); P == NULL && I != E; ++I)
- P = NULL; // FIXME: (*I)->findAnalysisPass(AID, false /* Search downward */);
-
- return P;
-}
-
//===----------------------------------------------------------------------===//
// PMDataManager
void initializeAnalysisInfo() {
ForcedLastUses.clear();
AvailableAnalysis.clear();
-
- // Include immutable passes into AvailableAnalysis vector.
- std::vector<ImmutablePass *> &ImmutablePasses = TPM->getImmutablePasses();
- for (std::vector<ImmutablePass *>::iterator I = ImmutablePasses.begin(),
- E = ImmutablePasses.end(); I != E; ++I)
- recordAvailableAnalysis(*I);
}
/// Populate RequiredPasses with the analysis pass that are required by
std::vector<Pass *> ForcedLastUses;
// Top level manager.
- // TODO : Make it a reference.
PMTopLevelManager *TPM;
private:
unsigned Depth;
};
+//===----------------------------------------------------------------------===//
+// BasicBlockPassManager_New
+//
/// BasicBlockPassManager_New manages BasicBlockPass. It batches all the
/// pass together and sequence them to process one basic block before
/// processing next basic block.
};
+//===----------------------------------------------------------------------===//
+// FunctionPassManagerImpl_New
+//
/// FunctionPassManagerImpl_New manages FunctionPasses and BasicBlockPassManagers.
/// It batches all function passes and basic block pass managers together and
/// sequence them to process one function at a time before processing next
public PMDataManager,
public PMTopLevelManager {
public:
- FunctionPassManagerImpl_New(ModuleProvider *P, int D) :
- PMDataManager(D) { /* TODO */ }
FunctionPassManagerImpl_New(int D) : PMDataManager(D) {
activeBBPassManager = NULL;
}
~FunctionPassManagerImpl_New() { /* TODO */ };
inline void addTopLevelPass(Pass *P) {
- addPass(P);
+
+ if (ImmutablePass *IP = dynamic_cast<ImmutablePass *> (P)) {
+
+ // P is a immutable pass then it will be managed by this
+ // top level manager. Set up analysis resolver to connect them.
+ AnalysisResolver_New *AR = new AnalysisResolver_New(*this);
+ P->setResolver(AR);
+ initializeAnalysisImpl(P);
+ addImmutablePass(IP);
+ recordAvailableAnalysis(IP);
+ }
+ else
+ addPass(P);
}
/// add - Add a pass to the queue of passes to run. This passes
/// so, return true.
bool runOnModule(Module &M);
bool runOnFunction(Function &F);
+ bool run(Function &F);
/// doInitialization - Run all of the initializers for the function passes.
///
BasicBlockPassManager_New *activeBBPassManager;
};
+//===----------------------------------------------------------------------===//
+// ModulePassManager_New
+//
/// ModulePassManager_New manages ModulePasses and function pass managers.
/// It batches all Module passes passes and function pass managers together and
/// sequence them to process one module.
FunctionPassManagerImpl_New *activeFunctionPassManager;
};
-/// PassManager_New manages ModulePassManagers
+//===----------------------------------------------------------------------===//
+// PassManagerImpl_New
+//
+/// PassManagerImpl_New manages ModulePassManagers
class PassManagerImpl_New : public Pass,
public PMDataManager,
public PMTopLevelManager {
public:
- PassManagerImpl_New(int D) : PMDataManager(D) {}
+ PassManagerImpl_New(int D) : PMDataManager(D) {
+ activeManager = NULL;
+ }
/// 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
}
inline void addTopLevelPass(Pass *P) {
- addPass(P);
+
+ if (ImmutablePass *IP = dynamic_cast<ImmutablePass *> (P)) {
+
+ // P is a immutable pass and it will be managed by this
+ // top level manager. Set up analysis resolver to connect them.
+ AnalysisResolver_New *AR = new AnalysisResolver_New(*this);
+ P->setResolver(AR);
+ initializeAnalysisImpl(P);
+ addImmutablePass(IP);
+ recordAvailableAnalysis(IP);
+ }
+ else
+ addPass(P);
}
private:
/// Add a pass into a passmanager queue.
bool addPass(Pass *p);
- // Collection of pass managers
- std::vector<ModulePassManager_New *> PassManagers;
-
// Active Pass Manager
ModulePassManager_New *activeManager;
};
} // End of llvm namespace
+//===----------------------------------------------------------------------===//
+// PMTopLevelManager implementation
+
+/// Set pass P as the last user of the given analysis passes.
+void PMTopLevelManager::setLastUser(std::vector<Pass *> &AnalysisPasses,
+ Pass *P) {
+
+ for (std::vector<Pass *>::iterator I = AnalysisPasses.begin(),
+ E = AnalysisPasses.end(); I != E; ++I) {
+ Pass *AP = *I;
+ LastUser[AP] = P;
+ // If AP is the last user of other passes then make P last user of
+ // such passes.
+ for (std::map<Pass *, Pass *>::iterator LUI = LastUser.begin(),
+ LUE = LastUser.end(); LUI != LUE; ++LUI) {
+ if (LUI->second == AP)
+ LastUser[LUI->first] = P;
+ }
+ }
+
+}
+
+/// Collect passes whose last user is P
+void PMTopLevelManager::collectLastUses(std::vector<Pass *> &LastUses,
+ Pass *P) {
+ for (std::map<Pass *, Pass *>::iterator LUI = LastUser.begin(),
+ LUE = LastUser.end(); LUI != LUE; ++LUI)
+ if (LUI->second == P)
+ LastUses.push_back(LUI->first);
+}
+
+/// 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
+
+ AnalysisUsage AnUsage;
+ P->getAnalysisUsage(AnUsage);
+ const std::vector<AnalysisID> &RequiredSet = AnUsage.getRequiredSet();
+ for (std::vector<AnalysisID>::const_iterator I = RequiredSet.begin(),
+ E = RequiredSet.end(); I != E; ++I) {
+
+ Pass *AnalysisPass = findAnalysisPass(*I);
+ if (!AnalysisPass) {
+ // Schedule this analysis run first.
+ AnalysisPass = (*I)->createPass();
+ schedulePass(AnalysisPass);
+ }
+ }
+
+ // Now all required passes are available.
+ addTopLevelPass(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 *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
+
+ Pass *P = NULL;
+ // Check pass managers
+ for (std::vector<Pass *>::iterator I = PassManagers.begin(),
+ E = PassManagers.end(); P == NULL && I != E; ++I) {
+ PMDataManager *PMD = dynamic_cast<PMDataManager *>(*I);
+ assert(PMD && "This is not a PassManager");
+ P = PMD->findAnalysisPass(AID, false);
+ }
+
+ // Check other pass managers
+ for (std::vector<PMDataManager *>::iterator I = IndirectPassManagers.begin(),
+ E = IndirectPassManagers.end(); P == NULL && I != E; ++I)
+ P = (*I)->findAnalysisPass(AID, false);
+
+ for (std::vector<ImmutablePass *>::iterator I = ImmutablePasses.begin(),
+ E = ImmutablePasses.end(); P == NULL && I != E; ++I) {
+ const PassInfo *PI = (*I)->getPassInfo();
+ if (PI == AID)
+ P = *I;
+
+ // If Pass not found then check the interfaces implemented by Immutable Pass
+ if (!P) {
+ const std::vector<const PassInfo*> &ImmPI =
+ PI->getInterfacesImplemented();
+ for (unsigned Index = 0, End = ImmPI.size();
+ P == NULL && Index != End; ++Index)
+ if (ImmPI[Index] == AID)
+ P = *I;
+ }
+ }
+
+ return P;
+}
+
//===----------------------------------------------------------------------===//
// PMDataManager implementation
const std::vector<AnalysisID> &PreservedSet = AnUsage.getPreservedSet();
for (std::map<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(),
- E = AvailableAnalysis.end(); I != E; ++I ) {
+ E = AvailableAnalysis.end(); I != E; ) {
if (std::find(PreservedSet.begin(), PreservedSet.end(), I->first) ==
PreservedSet.end()) {
// Remove this analysis
- std::map<AnalysisID, Pass*>::iterator J = I++;
- AvailableAnalysis.erase(J);
- }
+ if (!dynamic_cast<ImmutablePass*>(I->second)) {
+ std::map<AnalysisID, Pass*>::iterator J = I++;
+ AvailableAnalysis.erase(J);
+ } else
+ ++I;
+ } else
+ ++I;
}
}
void PMDataManager::addPassToManager(Pass *P,
bool ProcessAnalysis) {
+ // This manager is going to manage pass P. Set up analysis resolver
+ // to connect them.
+ AnalysisResolver_New *AR = new AnalysisResolver_New(*this);
+ P->setResolver(AR);
+
if (ProcessAnalysis) {
// At the moment, this pass is the last user of all required passes.
E = RequiredPasses.end(); I != E; ++I) {
Pass *PRequired = *I;
unsigned RDepth = 0;
- //FIXME: RDepth = PRequired->getResolver()->getDepth();
+
+ PMDataManager &DM = PRequired->getResolver()->getPMDataManager();
+ RDepth = DM.getDepth();
+
if (PDepth == RDepth)
LastUses.push_back(PRequired);
else if (PDepth > RDepth) {
// Take a note of analysis required and made available by this pass.
// Remove the analysis not preserved by this pass
- initializeAnalysisImpl(P);
removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P);
}
assert (AnalysisPass && "Analysis pass is not available");
RP.push_back(AnalysisPass);
}
+
+ const std::vector<AnalysisID> &IDs = AnUsage.getRequiredTransitiveSet();
+ for (std::vector<AnalysisID>::const_iterator I = IDs.begin(),
+ E = IDs.end(); I != E; ++I) {
+ Pass *AnalysisPass = findAnalysisPass(*I, true);
+ assert (AnalysisPass && "Analysis pass is not available");
+ RP.push_back(AnalysisPass);
+ }
}
// All Required analyses should be available to the pass as it runs! Here
Pass *Impl = findAnalysisPass(*I, true);
if (Impl == 0)
assert(0 && "Analysis used but not available!");
- // TODO: P->AnalysisImpls.push_back(std::make_pair(*I, Impl));
+ AnalysisResolver_New *AR = P->getResolver();
+ AR->addAnalysisImplsPair(*I, Impl);
}
}
if (SearchParent)
return TPM->findAnalysisPass(AID);
- // FIXME : This is expensive and requires. Need to check only managers not all passes.
- // One solution is to collect managers in advance at TPM level.
- Pass *P = NULL;
- for(std::vector<Pass *>::iterator I = passVectorBegin(),
- E = passVectorEnd(); P == NULL && I!= E; ++I )
- P = NULL; // FIXME : P = (*I)->getResolver()->getAnalysisToUpdate(AID, false /* Do not search parents again */);
+ return NULL;
+}
- return P;
+
+//===----------------------------------------------------------------------===//
+// NOTE: Is this the right place to define this method ?
+// getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
+Pass *AnalysisResolver_New::getAnalysisToUpdate(AnalysisID ID, bool dir) const {
+ return PM.findAnalysisPass(ID, dir);
}
//===----------------------------------------------------------------------===//
for (std::vector<Pass *>::iterator itr = passVectorBegin(),
e = passVectorEnd(); itr != e; ++itr) {
Pass *P = *itr;
-
+ initializeAnalysisImpl(P);
BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P);
Changed |= BP->runOnBasicBlock(*I);
removeNotPreservedAnalysis(P);
FunctionPassManager_New::FunctionPassManager_New(ModuleProvider *P) {
FPM = new FunctionPassManagerImpl_New(0);
+ // FPM is the top level manager.
+ FPM->setTopLevelManager(FPM);
MP = P;
}
cerr << "Error reading bytecode file: " << errstr << "\n";
abort();
}
- return FPM->runOnFunction(F);
+ return FPM->run(F);
}
// Create and add new manager
activeBBPassManager =
new BasicBlockPassManager_New(getDepth() + 1);
+ // Inherit top level manager
+ activeBBPassManager->setTopLevelManager(this->getTopLevelManager());
+
+ // Add new manager into current manager's list.
addPassToManager(activeBBPassManager, false);
+ // Add new manager into top level manager's indirect passes list
+ PMDataManager *PMD = dynamic_cast<PMDataManager *>(activeBBPassManager);
+ assert (PMD && "Manager is not Pass Manager");
+ TPM->addIndirectPassManager(PMD);
+
// Add pass into new manager. This time it must succeed.
if (!activeBBPassManager->addPass(BP))
assert(0 && "Unable to add Pass");
for (std::vector<Pass *>::iterator itr = passVectorBegin(),
e = passVectorEnd(); itr != e; ++itr) {
Pass *P = *itr;
-
+ initializeAnalysisImpl(P);
FunctionPass *FP = dynamic_cast<FunctionPass*>(P);
Changed |= FP->runOnFunction(F);
removeNotPreservedAnalysis(P);
return Changed;
}
+// Execute all the passes managed by this top level manager.
+// Return true if any function is modified by a pass.
+bool FunctionPassManagerImpl_New::run(Function &F) {
+
+ bool Changed = false;
+ for (std::vector<Pass *>::iterator I = passManagersBegin(),
+ E = passManagersEnd(); I != E; ++I) {
+ FunctionPass *FP = dynamic_cast<FunctionPass *>(*I);
+ Changed |= FP->runOnFunction(F);
+ }
+ return Changed;
+}
+
//===----------------------------------------------------------------------===//
// ModulePassManager implementation
// Create and add new manager
activeFunctionPassManager =
new FunctionPassManagerImpl_New(getDepth() + 1);
+
+ // Add new manager into current manager's list
addPassToManager(activeFunctionPassManager, false);
+ // Inherit top level manager
+ activeFunctionPassManager->setTopLevelManager(this->getTopLevelManager());
+
+ // Add new manager into top level manager's indirect passes list
+ PMDataManager *PMD = dynamic_cast<PMDataManager *>(activeFunctionPassManager);
+ assert (PMD && "Manager is not Pass Manager");
+ TPM->addIndirectPassManager(PMD);
+
// Add pass into new manager. This time it must succeed.
if (!activeFunctionPassManager->addPass(FP))
assert(0 && "Unable to add pass");
for (std::vector<Pass *>::iterator itr = passVectorBegin(),
e = passVectorEnd(); itr != e; ++itr) {
Pass *P = *itr;
-
+ initializeAnalysisImpl(P);
ModulePass *MP = dynamic_cast<ModulePass*>(P);
Changed |= MP->runOnModule(M);
removeNotPreservedAnalysis(P);
if (!activeManager || !activeManager->addPass(P)) {
activeManager = new ModulePassManager_New(getDepth() + 1);
- PassManagers.push_back(activeManager);
+ // Inherit top level manager
+ activeManager->setTopLevelManager(this->getTopLevelManager());
+
+ // This top level manager is going to manage activeManager.
+ // Set up analysis resolver to connect them.
+ AnalysisResolver_New *AR = new AnalysisResolver_New(*this);
+ activeManager->setResolver(AR);
+
+ addPassManager(activeManager);
return activeManager->addPass(P);
}
return true;
bool PassManagerImpl_New::run(Module &M) {
bool Changed = false;
- for (std::vector<ModulePassManager_New *>::iterator itr = PassManagers.begin(),
- e = PassManagers.end(); itr != e; ++itr) {
- ModulePassManager_New *pm = *itr;
- Changed |= pm->runOnModule(M);
+ for (std::vector<Pass *>::iterator I = passManagersBegin(),
+ E = passManagersEnd(); I != E; ++I) {
+ ModulePassManager_New *MP = dynamic_cast<ModulePassManager_New *>(*I);
+ Changed |= MP->runOnModule(M);
}
return Changed;
}
/// Create new pass manager
PassManager_New::PassManager_New() {
PM = new PassManagerImpl_New(0);
+ // PM is the top level manager
+ PM->setTopLevelManager(PM);
}
/// add - Add a pass to the queue of passes to run. This passes ownership of