File indexing completed on 2026-05-10 08:44:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_IR_PASSMANAGERIMPL_H
0016 #define LLVM_IR_PASSMANAGERIMPL_H
0017
0018 #include "llvm/IR/Function.h"
0019 #include "llvm/IR/PassInstrumentation.h"
0020 #include "llvm/IR/PassManager.h"
0021 #include "llvm/Support/CommandLine.h"
0022 #include "llvm/Support/PrettyStackTrace.h"
0023
0024 extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
0025
0026 namespace llvm {
0027
0028 template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
0029 PreservedAnalyses PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...>::run(
0030 IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs) {
0031 class StackTraceEntry : public PrettyStackTraceEntry {
0032 const PassInstrumentation &PI;
0033 IRUnitT &IR;
0034 PassConceptT *Pass = nullptr;
0035
0036 public:
0037 explicit StackTraceEntry(const PassInstrumentation &PI, IRUnitT &IR)
0038 : PI(PI), IR(IR) {}
0039
0040 void setPass(PassConceptT *P) { Pass = P; }
0041
0042 void print(raw_ostream &OS) const override {
0043 OS << "Running pass \"";
0044 if (Pass)
0045 Pass->printPipeline(OS, [this](StringRef ClassName) {
0046 auto PassName = PI.getPassNameForClassName(ClassName);
0047 return PassName.empty() ? ClassName : PassName;
0048 });
0049 else
0050 OS << "unknown";
0051 OS << "\" on ";
0052 printIRUnitNameForStackTrace(OS, IR);
0053 OS << "\n";
0054 }
0055 };
0056
0057 PreservedAnalyses PA = PreservedAnalyses::all();
0058
0059
0060
0061
0062
0063 PassInstrumentation PI =
0064 detail::getAnalysisResult<PassInstrumentationAnalysis>(
0065 AM, IR, std::tuple<ExtraArgTs...>(ExtraArgs...));
0066
0067
0068
0069 ScopedDbgInfoFormatSetter FormatSetter(IR, UseNewDbgInfoFormat);
0070
0071 StackTraceEntry Entry(PI, IR);
0072 for (auto &Pass : Passes) {
0073 Entry.setPass(&*Pass);
0074
0075
0076
0077
0078 if (!PI.runBeforePass<IRUnitT>(*Pass, IR))
0079 continue;
0080
0081 PreservedAnalyses PassPA = Pass->run(IR, AM, ExtraArgs...);
0082
0083
0084
0085 AM.invalidate(IR, PassPA);
0086
0087
0088
0089 PI.runAfterPass<IRUnitT>(*Pass, IR, PassPA);
0090
0091
0092
0093 PA.intersect(std::move(PassPA));
0094 }
0095
0096
0097
0098
0099
0100 PA.preserveSet<AllAnalysesOn<IRUnitT>>();
0101
0102 return PA;
0103 }
0104
0105 template <typename IRUnitT, typename... ExtraArgTs>
0106 inline AnalysisManager<IRUnitT, ExtraArgTs...>::AnalysisManager() = default;
0107
0108 template <typename IRUnitT, typename... ExtraArgTs>
0109 inline AnalysisManager<IRUnitT, ExtraArgTs...>::AnalysisManager(
0110 AnalysisManager &&) = default;
0111
0112 template <typename IRUnitT, typename... ExtraArgTs>
0113 inline AnalysisManager<IRUnitT, ExtraArgTs...> &
0114 AnalysisManager<IRUnitT, ExtraArgTs...>::operator=(AnalysisManager &&) =
0115 default;
0116
0117 template <typename IRUnitT, typename... ExtraArgTs>
0118 inline void
0119 AnalysisManager<IRUnitT, ExtraArgTs...>::clear(IRUnitT &IR,
0120 llvm::StringRef Name) {
0121 if (auto *PI = getCachedResult<PassInstrumentationAnalysis>(IR))
0122 PI->runAnalysesCleared(Name);
0123
0124 auto ResultsListI = AnalysisResultLists.find(&IR);
0125 if (ResultsListI == AnalysisResultLists.end())
0126 return;
0127
0128 for (auto &IDAndResult : ResultsListI->second)
0129 AnalysisResults.erase({IDAndResult.first, &IR});
0130
0131
0132 AnalysisResultLists.erase(ResultsListI);
0133 }
0134
0135 template <typename IRUnitT, typename... ExtraArgTs>
0136 inline typename AnalysisManager<IRUnitT, ExtraArgTs...>::ResultConceptT &
0137 AnalysisManager<IRUnitT, ExtraArgTs...>::getResultImpl(
0138 AnalysisKey *ID, IRUnitT &IR, ExtraArgTs... ExtraArgs) {
0139 typename AnalysisResultMapT::iterator RI;
0140 bool Inserted;
0141 std::tie(RI, Inserted) = AnalysisResults.insert(std::make_pair(
0142 std::make_pair(ID, &IR), typename AnalysisResultListT::iterator()));
0143
0144
0145
0146 if (Inserted) {
0147 auto &P = this->lookUpPass(ID);
0148
0149 PassInstrumentation PI;
0150 if (ID != PassInstrumentationAnalysis::ID()) {
0151 PI = getResult<PassInstrumentationAnalysis>(IR, ExtraArgs...);
0152 PI.runBeforeAnalysis(P, IR);
0153 }
0154
0155 AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
0156 ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
0157
0158 PI.runAfterAnalysis(P, IR);
0159
0160
0161
0162 RI = AnalysisResults.find({ID, &IR});
0163 assert(RI != AnalysisResults.end() && "we just inserted it!");
0164
0165 RI->second = std::prev(ResultList.end());
0166 }
0167
0168 return *RI->second->second;
0169 }
0170
0171 template <typename IRUnitT, typename... ExtraArgTs>
0172 inline void AnalysisManager<IRUnitT, ExtraArgTs...>::invalidate(
0173 IRUnitT &IR, const PreservedAnalyses &PA) {
0174
0175 if (PA.allAnalysesInSetPreserved<AllAnalysesOn<IRUnitT>>())
0176 return;
0177
0178
0179
0180 SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
0181 Invalidator Inv(IsResultInvalidated, AnalysisResults);
0182 AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
0183 for (auto &AnalysisResultPair : ResultsList) {
0184
0185
0186
0187
0188 AnalysisKey *ID = AnalysisResultPair.first;
0189 auto &Result = *AnalysisResultPair.second;
0190
0191 auto IMapI = IsResultInvalidated.find(ID);
0192 if (IMapI != IsResultInvalidated.end())
0193
0194 continue;
0195
0196
0197
0198
0199
0200
0201 bool Inserted =
0202 IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, Inv)}).second;
0203 (void)Inserted;
0204 assert(Inserted && "Should never have already inserted this ID, likely "
0205 "indicates a cycle!");
0206 }
0207
0208
0209 if (!IsResultInvalidated.empty()) {
0210 for (auto I = ResultsList.begin(), E = ResultsList.end(); I != E;) {
0211 AnalysisKey *ID = I->first;
0212 if (!IsResultInvalidated.lookup(ID)) {
0213 ++I;
0214 continue;
0215 }
0216
0217 if (auto *PI = getCachedResult<PassInstrumentationAnalysis>(IR))
0218 PI->runAnalysisInvalidated(this->lookUpPass(ID), IR);
0219
0220 I = ResultsList.erase(I);
0221 AnalysisResults.erase({ID, &IR});
0222 }
0223 }
0224
0225 if (ResultsList.empty())
0226 AnalysisResultLists.erase(&IR);
0227 }
0228 }
0229
0230 #endif