//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Devang Patel and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/ModuleProvider.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm-c/Core.h"
#include <algorithm>
#include <vector>
#include <map>
+using namespace llvm;
// See PassManagers.h for Pass Manager infrastructure overview.
public:
static char ID;
- BBPassManager(int Depth)
+ explicit BBPassManager(int Depth)
: PMDataManager(Depth), FunctionPass((intptr_t)&ID) {}
/// Execute all of the passes scheduled for execution. Keep track of
bool doFinalization(Function &F);
virtual const char *getPassName() const {
- return "BasicBlock Pass Manager";
+ return "BasicBlock Pass Manager";
}
// Print passes managed by this manager
public PMTopLevelManager {
public:
static char ID;
- FunctionPassManagerImpl(int Depth) :
+ explicit FunctionPassManagerImpl(int Depth) :
Pass((intptr_t)&ID), PMDataManager(Depth),
PMTopLevelManager(TLM_Function) { }
// MPPassManager
//
/// MPPassManager manages ModulePasses and function pass managers.
-/// It batches all Module passes passes and function pass managers together and
-/// sequence them to process one module.
+/// 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;
- MPPassManager(int Depth) : Pass((intptr_t)&ID), PMDataManager(Depth) { }
+ explicit MPPassManager(int Depth) :
+ Pass((intptr_t)&ID), PMDataManager(Depth) { }
// Delete on the fly managers.
virtual ~MPPassManager() {
public:
static char ID;
- PassManagerImpl(int Depth) : Pass((intptr_t)&ID), PMDataManager(Depth),
- PMTopLevelManager(TLM_Pass) { }
+ explicit PassManagerImpl(int Depth) :
+ Pass((intptr_t)&ID), PMDataManager(Depth),
+ PMTopLevelManager(TLM_Pass) { }
/// 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
}
};
-static TimingInfo *TheTimeInfo;
-
} // End of anon namespace
+static TimingInfo *TheTimeInfo;
+
//===----------------------------------------------------------------------===//
// PMTopLevelManager implementation
// 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.
+ if (P->getPassInfo() &&
+ P->getPassInfo()->isAnalysis() && findAnalysisPass(P->getPassInfo()))
+ return;
+
AnalysisUsage AnUsage;
P->getAnalysisUsage(AnUsage);
const std::vector<AnalysisID> &RequiredSet = AnUsage.getRequiredSet();
Pass *P = NULL;
// Check pass managers
- for (std::vector<Pass *>::iterator I = PassManagers.begin(),
+ for (std::vector<PMDataManager *>::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");
+ PMDataManager *PMD = *I;
P = PMD->findAnalysisPass(AID, false);
}
// If Pass not found then check the interfaces implemented by Immutable Pass
if (!P) {
- const std::vector<const PassInfo*> &ImmPI = PI->getInterfacesImplemented();
+ const std::vector<const PassInfo*> &ImmPI =
+ PI->getInterfacesImplemented();
if (std::find(ImmPI.begin(), ImmPI.end(), AID) != ImmPI.end())
P = *I;
}
ImmutablePasses[i]->dumpPassStructure(0);
}
- for (std::vector<Pass *>::const_iterator I = PassManagers.begin(),
+ // 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 dynamic_cast to get
+ // from a PMDataManager* to a Pass*.
+ for (std::vector<PMDataManager *>::const_iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I)
- (*I)->dumpPassStructure(1);
+ dynamic_cast<Pass *>(*I)->dumpPassStructure(1);
}
void PMTopLevelManager::dumpArguments() const {
return;
cerr << "Pass Arguments: ";
- for (std::vector<Pass *>::const_iterator I = PassManagers.begin(),
+ for (std::vector<PMDataManager *>::const_iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I) {
- PMDataManager *PMD = dynamic_cast<PMDataManager *>(*I);
- assert(PMD && "This is not a PassManager");
+ PMDataManager *PMD = *I;
PMD->dumpPassArguments();
}
cerr << "\n";
void PMTopLevelManager::initializeAllAnalysisInfo() {
- for (std::vector<Pass *>::iterator I = PassManagers.begin(),
+ for (std::vector<PMDataManager *>::iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I) {
- PMDataManager *PMD = dynamic_cast<PMDataManager *>(*I);
- assert(PMD && "This is not a PassManager");
+ PMDataManager *PMD = *I;
PMD->initializeAnalysisInfo();
}
/// Destructor
PMTopLevelManager::~PMTopLevelManager() {
- for (std::vector<Pass *>::iterator I = PassManagers.begin(),
+ for (std::vector<PMDataManager *>::iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I)
delete *I;
for (std::vector<ImmutablePass *>::iterator
I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
delete *I;
-
- PassManagers.clear();
}
//===----------------------------------------------------------------------===//
// PMDataManager implementation
-/// Return true IFF pass P's required analysis set does not required new
-/// manager.
-bool PMDataManager::manageablePass(Pass *P) {
-
- // TODO
- // If this pass is not preserving information that is required by a
- // pass maintained by higher level pass manager then do not insert
- // this pass into current manager. Use new manager. For example,
- // For example, If FunctionPass F is not preserving ModulePass Info M1
- // that is used by another ModulePass M2 then do not insert F in
- // current function pass manager.
- return true;
-}
-
/// Augement AvailableAnalysis by adding analysis made available by pass P.
void PMDataManager::recordAvailableAnalysis(Pass *P) {
for (std::vector<Pass *>::iterator I = HigherLevelAnalysis.begin(),
E = HigherLevelAnalysis.end(); I != E; ++I) {
Pass *P1 = *I;
- if (!dynamic_cast<ImmutablePass*>(P1)
- && std::find(PreservedSet.begin(), PreservedSet.end(), P1->getPassInfo()) ==
+ if (!dynamic_cast<ImmutablePass*>(P1) &&
+ std::find(PreservedSet.begin(), PreservedSet.end(),
+ P1->getPassInfo()) ==
PreservedSet.end())
return false;
}
I = InheritedAnalysis[Index]->begin(),
E = InheritedAnalysis[Index]->end(); I != E; ) {
std::map<AnalysisID, Pass *>::iterator Info = I++;
- if (!dynamic_cast<ImmutablePass*>(Info->second)
- && std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
+ if (!dynamic_cast<ImmutablePass*>(Info->second) &&
+ std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
PreservedSet.end())
// Remove this analysis
InheritedAnalysis[Index]->erase(Info);
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.
assert (0 && "Unable to handle Pass that requires lower level Analysis pass");
}
E = PassVector.end(); I != E; ++I)
delete *I;
- PassVector.clear();
}
//===----------------------------------------------------------------------===//
if (TheTimeInfo) TheTimeInfo->passEnded(BP);
if (Changed)
- dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, I->getNameStart());
+ dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
+ I->getNameStart());
dumpAnalysisSetInfo("Preserved", BP, AnUsage.getPreservedSet());
verifyPreservedAnalysis(BP);
// FPM is the top level manager.
FPM->setTopLevelManager(FPM);
- PMDataManager *PMD = dynamic_cast<PMDataManager *>(FPM);
- AnalysisResolver *AR = new AnalysisResolver(*PMD);
+ AnalysisResolver *AR = new AnalysisResolver(*FPM);
FPM->setResolver(AR);
MP = P;
if (F.isDeclaration())
return false;
+
+ // Collect inherited analysis from Module level pass manager.
+ populateInheritedAnalysis(TPM->activeStack);
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
FunctionPass *FP = getContainedPass(Index);
AnalysisUsage AnUsage;
MP->getAnalysisUsage(AnUsage);
- dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier().c_str());
+ dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG,
+ M.getModuleIdentifier().c_str());
dumpAnalysisSetInfo("Required", MP, AnUsage.getRequiredSet());
initializeAnalysisImpl(MP);
if (TheTimeInfo) TheTimeInfo->passEnded(MP);
if (Changed)
- dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG, M.getModuleIdentifier().c_str());
+ dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
+ M.getModuleIdentifier().c_str());
dumpAnalysisSetInfo("Preserved", MP, AnUsage.getPreservedSet());
verifyPreservedAnalysis(MP);
}
// Push PM on the stack and set its top level manager.
-void PMStack::push(Pass *P) {
+void PMStack::push(PMDataManager *PM) {
PMDataManager *Top = NULL;
- PMDataManager *PM = dynamic_cast<PMDataManager *>(P);
assert (PM && "Unable to push. Pass Manager expected");
if (this->empty()) {
// [1] Create new Function Pass Manager
FPP = new FPPassManager(PMD->getDepth() + 1);
+ FPP->populateInheritedAnalysis(PMS);
// [2] Set up new manager's top level manager
PMTopLevelManager *TPM = PMD->getTopLevelManager();
// [3] Assign manager to manage this new manager. This may create
// and push new managers into PMS
- Pass *P = dynamic_cast<Pass *>(FPP);
// If Call Graph Pass Manager is active then use it to manage
// this new Function Pass manager.
if (PMD->getPassManagerType() == PMT_CallGraphPassManager)
- P->assignPassManager(PMS, PMT_CallGraphPassManager);
+ FPP->assignPassManager(PMS, PMT_CallGraphPassManager);
else
- P->assignPassManager(PMS);
+ FPP->assignPassManager(PMS);
// [4] Push new manager into PMS
PMS.push(FPP);
// [3] Assign manager to manage this new manager. This may create
// and push new managers into PMS
- Pass *P = dynamic_cast<Pass *>(BBP);
- P->assignPassManager(PMS);
+ BBP->assignPassManager(PMS);
// [4] Push new manager into PMS
PMS.push(BBP);
BBP->add(this);
}
+PassManagerBase::~PassManagerBase() {}
+
+/*===-- C Bindings --------------------------------------------------------===*/
+LLVMPassManagerRef LLVMCreatePassManager() {
+ return wrap(new PassManager());
+}
+
+LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef P) {
+ return wrap(new FunctionPassManager(unwrap(P)));
+}
+
+int LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
+ return unwrap<PassManager>(PM)->run(*unwrap(M));
+}
+
+int LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM) {
+ return unwrap<FunctionPassManager>(FPM)->doInitialization();
+}
+
+int LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F) {
+ return unwrap<FunctionPassManager>(FPM)->run(*unwrap<Function>(F));
+}
+
+int LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM) {
+ return unwrap<FunctionPassManager>(FPM)->doFinalization();
+}
+
+void LLVMDisposePassManager(LLVMPassManagerRef PM) {
+ delete unwrap(PM);
+}