#ifndef LLVM_IR_PASSMANAGERIMPL_H
#define LLVM_IR_PASSMANAGERIMPL_H
#include "llvm/IR/PassManager.h"
namespace llvm {
template <typename IRUnitT, typename... ExtraArgTs>
inline AnalysisManager<IRUnitT, ExtraArgTs...>::AnalysisManager() = default;
template <typename IRUnitT, typename... ExtraArgTs>
inline AnalysisManager<IRUnitT, ExtraArgTs...>::AnalysisManager(
AnalysisManager &&) = default;
template <typename IRUnitT, typename... ExtraArgTs>
inline AnalysisManager<IRUnitT, ExtraArgTs...> &
AnalysisManager<IRUnitT, ExtraArgTs...>::operator=(AnalysisManager &&) =
default;
template <typename IRUnitT, typename... ExtraArgTs>
inline void
AnalysisManager<IRUnitT, ExtraArgTs...>::clear(IRUnitT &IR,
llvm::StringRef Name) {
if (auto *PI = getCachedResult<PassInstrumentationAnalysis>(IR))
PI->runAnalysesCleared(Name);
auto ResultsListI = AnalysisResultLists.find(&IR);
if (ResultsListI == AnalysisResultLists.end())
return;
for (auto &IDAndResult : ResultsListI->second)
AnalysisResults.erase({IDAndResult.first, &IR});
AnalysisResultLists.erase(ResultsListI);
}
template <typename IRUnitT, typename... ExtraArgTs>
inline typename AnalysisManager<IRUnitT, ExtraArgTs...>::ResultConceptT &
AnalysisManager<IRUnitT, ExtraArgTs...>::getResultImpl(
AnalysisKey *ID, IRUnitT &IR, ExtraArgTs... ExtraArgs) {
typename AnalysisResultMapT::iterator RI;
bool Inserted;
std::tie(RI, Inserted) = AnalysisResults.insert(std::make_pair(
std::make_pair(ID, &IR), typename AnalysisResultListT::iterator()));
if (Inserted) {
auto &P = this->lookUpPass(ID);
PassInstrumentation PI;
if (ID != PassInstrumentationAnalysis::ID()) {
PI = getResult<PassInstrumentationAnalysis>(IR, ExtraArgs...);
PI.runBeforeAnalysis(P, IR);
}
AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
PI.runAfterAnalysis(P, IR);
RI = AnalysisResults.find({ID, &IR});
assert(RI != AnalysisResults.end() && "we just inserted it!");
RI->second = std::prev(ResultList.end());
}
return *RI->second->second;
}
template <typename IRUnitT, typename... ExtraArgTs>
inline void AnalysisManager<IRUnitT, ExtraArgTs...>::invalidate(
IRUnitT &IR, const PreservedAnalyses &PA) {
if (PA.allAnalysesInSetPreserved<AllAnalysesOn<IRUnitT>>())
return;
SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
Invalidator Inv(IsResultInvalidated, AnalysisResults);
AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
for (auto &AnalysisResultPair : ResultsList) {
AnalysisKey *ID = AnalysisResultPair.first;
auto &Result = *AnalysisResultPair.second;
auto IMapI = IsResultInvalidated.find(ID);
if (IMapI != IsResultInvalidated.end())
continue;
bool Inserted =
IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, Inv)}).second;
(void)Inserted;
assert(Inserted && "Should never have already inserted this ID, likely "
"indicates a cycle!");
}
if (!IsResultInvalidated.empty()) {
for (auto I = ResultsList.begin(), E = ResultsList.end(); I != E;) {
AnalysisKey *ID = I->first;
if (!IsResultInvalidated.lookup(ID)) {
++I;
continue;
}
if (auto *PI = getCachedResult<PassInstrumentationAnalysis>(IR))
PI->runAnalysisInvalidated(this->lookUpPass(ID), IR);
I = ResultsList.erase(I);
AnalysisResults.erase({ID, &IR});
}
}
if (ResultsList.empty())
AnalysisResultLists.erase(&IR);
}
}
#endif