+static cl::opt<bool>
+DebugPM("debug-pass-manager", cl::Hidden,
+ cl::desc("Print pass management debugging information"));
+
+PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+
+ if (DebugPM)
+ dbgs() << "Starting module pass manager run.\n";
+
+ for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
+ if (DebugPM)
+ dbgs() << "Running module pass: " << Passes[Idx]->name() << "\n";
+
+ PreservedAnalyses PassPA = Passes[Idx]->run(M, AM);
+ if (AM)
+ AM->invalidate(M, PassPA);
+ PA.intersect(std::move(PassPA));
+
+ M->getContext().yield();
+ }
+
+ if (DebugPM)
+ dbgs() << "Finished module pass manager run.\n";
+
+ return PA;
+}
+
+ModuleAnalysisManager::ResultConceptT &
+ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) {
+ ModuleAnalysisResultMapT::iterator RI;
+ bool Inserted;
+ std::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair(
+ PassID, std::unique_ptr<detail::AnalysisResultConcept<Module *>>()));
+
+ // If we don't have a cached result for this module, look up the pass and run
+ // it to produce a result, which we then add to the cache.
+ if (Inserted)
+ RI->second = lookupPass(PassID).run(M, this);
+
+ return *RI->second;
+}
+
+ModuleAnalysisManager::ResultConceptT *
+ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module *M) const {
+ ModuleAnalysisResultMapT::const_iterator RI =
+ ModuleAnalysisResults.find(PassID);
+ return RI == ModuleAnalysisResults.end() ? nullptr : &*RI->second;