+ if (DebugPM)
+ dbgs() << "Invalidating function analysis: " << lookupPass(PassID).name()
+ << "\n";
+ FunctionAnalysisResultLists[&F].erase(RI->second);
+ FunctionAnalysisResults.erase(RI);
+}
+
+PreservedAnalyses
+FunctionAnalysisManager::invalidateImpl(Function &F, PreservedAnalyses PA) {
+ // Short circuit for a common case of all analyses being preserved.
+ if (PA.areAllPreserved())
+ return std::move(PA);
+
+ if (DebugPM)
+ dbgs() << "Invalidating all non-preserved analyses for function: "
+ << F.getName() << "\n";
+
+ // Clear all the invalidated results associated specifically with this
+ // function.
+ SmallVector<void *, 8> InvalidatedPassIDs;
+ FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[&F];
+ for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(),
+ E = ResultsList.end();
+ I != E;) {
+ void *PassID = I->first;
+
+ // Pass the invalidation down to the pass itself to see if it thinks it is
+ // 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(F, PA)) {
+ if (DebugPM)
+ dbgs() << "Invalidating function analysis: "
+ << lookupPass(PassID).name() << "\n";
+
+ InvalidatedPassIDs.push_back(I->first);
+ I = ResultsList.erase(I);
+ } else {
+ ++I;
+ }
+
+ // After handling each pass, we mark it as preserved. Once we've
+ // invalidated any stale results, the rest of the system is allowed to
+ // start preserving this analysis again.
+ PA.preserve(PassID);
+ }
+ while (!InvalidatedPassIDs.empty())
+ FunctionAnalysisResults.erase(
+ std::make_pair(InvalidatedPassIDs.pop_back_val(), &F));
+ if (ResultsList.empty())
+ FunctionAnalysisResultLists.erase(&F);
+
+ return std::move(PA);
+}
+
+char FunctionAnalysisManagerModuleProxy::PassID;
+
+FunctionAnalysisManagerModuleProxy::Result
+FunctionAnalysisManagerModuleProxy::run(Module &M) {
+ assert(FAM->empty() && "Function analyses ran prior to the module proxy!");
+ return Result(*FAM);
+}
+
+FunctionAnalysisManagerModuleProxy::Result::~Result() {
+ // Clear out the analysis manager if we're being destroyed -- it means we
+ // didn't even see an invalidate call when we got invalidated.
+ FAM->clear();