class Module;
class Function;
-namespace detail {
-
-// Declare our debug option here so we can refer to it from templates.
-extern cl::opt<bool> DebugPM;
-
-} // End detail namespace
-
/// \brief An abstract set of preserved analyses following a transformation pass
/// run.
///
SmallPtrSet<void *, 2> PreservedPassIDs;
};
-// Forward declare the analysis manager template and two typedefs used in the
-// pass managers.
+// Forward declare the analysis manager template.
template <typename IRUnitT> class AnalysisManager;
-typedef AnalysisManager<Module> ModuleAnalysisManager;
-typedef AnalysisManager<Function> FunctionAnalysisManager;
/// \brief Manages a sequence of passes over units of IR.
///
/// runs.
template <typename IRUnitT> class PassManager {
public:
+ /// \brief Construct a pass manager.
+ ///
+ /// It can be passed a flag to get debug logging as the passes are run.
+ PassManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
- PassManager() {}
- PassManager(PassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
+ PassManager(PassManager &&Arg)
+ : Passes(std::move(Arg.Passes)),
+ DebugLogging(std::move(Arg.DebugLogging)) {}
PassManager &operator=(PassManager &&RHS) {
Passes = std::move(RHS.Passes);
+ DebugLogging = std::move(RHS.DebugLogging);
return *this;
}
PreservedAnalyses run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM = nullptr) {
PreservedAnalyses PA = PreservedAnalyses::all();
- if (detail::DebugPM)
+ if (DebugLogging)
dbgs() << "Starting pass manager run.\n";
for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
- if (detail::DebugPM)
+ if (DebugLogging)
dbgs() << "Running pass: " << Passes[Idx]->name() << "\n";
PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM);
//IR.getContext().yield();
}
- if (detail::DebugPM)
+ if (DebugLogging)
dbgs() << "Finished pass manager run.\n";
return PA;
}
template <typename PassT> void addPass(PassT Pass) {
- Passes.emplace_back(new PassModel<PassT>(std::move(Pass)));
+ typedef detail::PassModel<IRUnitT, PassT> PassModelT;
+ Passes.emplace_back(new PassModelT(std::move(Pass)));
}
static StringRef name() { return "PassManager"; }
private:
- // Pull in the concept type and model template specialized for modules.
- typedef detail::PassConcept<IRUnitT, AnalysisManager<IRUnitT>> PassConcept;
- template <typename PassT>
- struct PassModel
- : detail::PassModel<IRUnitT, AnalysisManager<IRUnitT>, PassT> {
- PassModel(PassT Pass)
- : detail::PassModel<IRUnitT, AnalysisManager<IRUnitT>, PassT>(
- std::move(Pass)) {}
- };
+ typedef detail::PassConcept<IRUnitT> PassConceptT;
- PassManager(const PassManager &) LLVM_DELETED_FUNCTION;
- PassManager &operator=(const PassManager &) LLVM_DELETED_FUNCTION;
+ PassManager(const PassManager &) = delete;
+ PassManager &operator=(const PassManager &) = delete;
- std::vector<std::unique_ptr<PassConcept>> Passes;
+ std::vector<std::unique_ptr<PassConceptT>> Passes;
+
+ /// \brief Flag indicating whether we should do debug logging.
+ bool DebugLogging;
};
/// \brief Convenience typedef for a pass manager over modules.
return static_cast<const DerivedT *>(this);
}
- AnalysisManagerBase(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
+ AnalysisManagerBase(const AnalysisManagerBase &) = delete;
AnalysisManagerBase &
- operator=(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
+ operator=(const AnalysisManagerBase &) = delete;
protected:
typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;
- typedef detail::AnalysisPassConcept<IRUnitT, DerivedT> PassConceptT;
+ typedef detail::AnalysisPassConcept<IRUnitT> PassConceptT;
// FIXME: Provide template aliases for the models when we're using C++11 in
// a mode supporting them.
template <typename PassT> void registerPass(PassT Pass) {
assert(!AnalysisPasses.count(PassT::ID()) &&
"Registered the same analysis pass twice!");
- typedef detail::AnalysisPassModel<IRUnitT, DerivedT, PassT> PassModelT;
+ typedef detail::AnalysisPassModel<IRUnitT, PassT> PassModelT;
AnalysisPasses[PassT::ID()].reset(new PassModelT(std::move(Pass)));
}
public:
// Most public APIs are inherited from the CRTP base class.
+ /// \brief Construct an empty analysis manager.
+ ///
+ /// A flag can be passed to indicate that the manager should perform debug
+ /// logging.
+ AnalysisManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
+
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
- AnalysisManager() {}
AnalysisManager(AnalysisManager &&Arg)
: BaseT(std::move(static_cast<BaseT &>(Arg))),
- AnalysisResults(std::move(Arg.AnalysisResults)) {}
+ AnalysisResults(std::move(Arg.AnalysisResults)),
+ DebugLogging(std::move(Arg.DebugLogging)) {}
AnalysisManager &operator=(AnalysisManager &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
AnalysisResults = std::move(RHS.AnalysisResults);
+ DebugLogging = std::move(RHS.DebugLogging);
return *this;
}
}
private:
- AnalysisManager(const AnalysisManager &) LLVM_DELETED_FUNCTION;
- AnalysisManager &operator=(const AnalysisManager &) LLVM_DELETED_FUNCTION;
+ AnalysisManager(const AnalysisManager &) = delete;
+ AnalysisManager &operator=(const AnalysisManager &) = delete;
/// \brief Get an analysis result, running the pass if necessary.
ResultConceptT &getResultImpl(void *PassID, IRUnitT &IR) {
// run it to produce a result, which we then add to the cache.
if (Inserted) {
auto &P = this->lookupPass(PassID);
- if (detail::DebugPM)
+ if (DebugLogging)
dbgs() << "Running analysis: " << P.name() << "\n";
AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
ResultList.emplace_back(PassID, P.run(IR, this));
if (RI == AnalysisResults.end())
return;
- if (detail::DebugPM)
+ if (DebugLogging)
dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
<< "\n";
AnalysisResultLists[&IR].erase(RI->second);
if (PA.areAllPreserved())
return std::move(PA);
- if (detail::DebugPM)
+ if (DebugLogging)
dbgs() << "Invalidating all non-preserved analyses for: "
<< IR.getName() << "\n";
// necessary. The analysis pass can return false if no action on the part
// of the analysis manager is required for this invalidation event.
if (I->second->invalidate(IR, PA)) {
- if (detail::DebugPM)
+ if (DebugLogging)
dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
<< "\n";
/// \brief Map from an analysis ID and function to a particular cached
/// analysis result.
AnalysisResultMapT AnalysisResults;
+
+ /// \brief A flag indicating whether debug logging is enabled.
+ bool DebugLogging;
};
+/// \brief Convenience typedef for the Module analysis manager.
+typedef AnalysisManager<Module> ModuleAnalysisManager;
+
+/// \brief Convenience typedef for the Function analysis manager.
+typedef AnalysisManager<Function> FunctionAnalysisManager;
+
/// \brief A module analysis which acts as a proxy for a function analysis
/// manager.
///
FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
PreservedAnalyses PA = PreservedAnalyses::all();
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
- PreservedAnalyses PassPA = Pass.run(*I, FAM);
+ for (Function &F : M) {
+ if (F.isDeclaration())
+ continue;
+
+ PreservedAnalyses PassPA = Pass.run(F, FAM);
// We know that the function pass couldn't have invalidated any other
// function's analyses (that's the contract of a function pass), so
// update our preserved set to reflect that these have already been
// handled.
if (FAM)
- PassPA = FAM->invalidate(*I, std::move(PassPA));
+ PassPA = FAM->invalidate(F, std::move(PassPA));
// Then intersect the preserved set so that invalidation of module
// analyses will eventually occur when the module pass completes.
/// provided they satisfy the basic API requirements. When this pass is
/// created, these methods can be instantiated to satisfy whatever the
/// context requires.
- template <typename IRUnitT, typename AnalysisManagerT>
- PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT *AM) {
+ template <typename IRUnitT>
+ PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> *AM) {
if (AM)
(void)AM->template getResult<AnalysisT>(Arg);
/// provided they satisfy the basic API requirements. When this pass is
/// created, these methods can be instantiated to satisfy whatever the
/// context requires.
- template <typename IRUnitT, typename AnalysisManagerT>
- PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT *AM) {
+ template <typename IRUnitT>
+ PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> *AM) {
if (AM)
// We have to directly invalidate the analysis result as we can't
// enumerate all other analyses and use the preserved set to control it.