LLVM 19.0.0git
PassManagerImpl.h
Go to the documentation of this file.
1//===- PassManagerImpl.h - Pass management infrastructure -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// Provides implementations for PassManager and AnalysisManager template
10/// methods. These classes should be explicitly instantiated for any IR unit,
11/// and files doing the explicit instantiation should include this header.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_IR_PASSMANAGERIMPL_H
16#define LLVM_IR_PASSMANAGERIMPL_H
17
18#include "llvm/IR/Function.h"
20#include "llvm/IR/PassManager.h"
23
25
26namespace llvm {
27
28template <typename IRUnitT, typename AnalysisManagerT, typename... ExtraArgTs>
30 IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs) {
31 class StackTraceEntry : public PrettyStackTraceEntry {
32 const PassInstrumentation &PI;
34 IRUnitT &IR;
35
36 public:
37 explicit StackTraceEntry(const PassInstrumentation &PI, PassConceptT &Pass,
38 IRUnitT &IR)
39 : PI(PI), Pass(Pass), IR(IR) {}
40
41 void print(raw_ostream &OS) const override {
42 OS << "Running pass \"";
43 Pass.printPipeline(OS, [this](StringRef ClassName) {
44 auto PassName = PI.getPassNameForClassName(ClassName);
45 return PassName.empty() ? ClassName : PassName;
46 });
47 OS << "\" on ";
49 OS << "\n";
50 }
51 };
52
54
55 // Request PassInstrumentation from analysis manager, will use it to run
56 // instrumenting callbacks for the passes later.
57 // Here we use std::tuple wrapper over getResult which helps to extract
58 // AnalysisManager's arguments out of the whole ExtraArgs set.
60 detail::getAnalysisResult<PassInstrumentationAnalysis>(
61 AM, IR, std::tuple<ExtraArgTs...>(ExtraArgs...));
62
63 // RemoveDIs: if requested, convert debug-info to DbgRecord representation
64 // for duration of these passes.
66
67 for (auto &Pass : Passes) {
68 // Check the PassInstrumentation's BeforePass callbacks before running the
69 // pass, skip its execution completely if asked to (callback returns
70 // false).
71 if (!PI.runBeforePass<IRUnitT>(*Pass, IR))
72 continue;
73
74 StackTraceEntry Entry(PI, *Pass, IR);
75 PreservedAnalyses PassPA = Pass->run(IR, AM, ExtraArgs...);
76
77 // Update the analysis manager as each pass runs and potentially
78 // invalidates analyses.
79 AM.invalidate(IR, PassPA);
80
81 // Call onto PassInstrumentation's AfterPass callbacks immediately after
82 // running the pass.
83 PI.runAfterPass<IRUnitT>(*Pass, IR, PassPA);
84
85 // Finally, intersect the preserved analyses to compute the aggregate
86 // preserved set for this pass manager.
87 PA.intersect(std::move(PassPA));
88 }
89
90 // Invalidation was handled after each pass in the above loop for the
91 // current unit of IR. Therefore, the remaining analysis results in the
92 // AnalysisManager are preserved. We mark this with a set so that we don't
93 // need to inspect each one individually.
95
96 return PA;
97}
98
99template <typename IRUnitT, typename... ExtraArgTs>
101
102template <typename IRUnitT, typename... ExtraArgTs>
104 AnalysisManager &&) = default;
105
106template <typename IRUnitT, typename... ExtraArgTs>
107inline AnalysisManager<IRUnitT, ExtraArgTs...> &
109 default;
110
111template <typename IRUnitT, typename... ExtraArgTs>
112inline void
115 if (auto *PI = getCachedResult<PassInstrumentationAnalysis>(IR))
116 PI->runAnalysesCleared(Name);
117
118 auto ResultsListI = AnalysisResultLists.find(&IR);
119 if (ResultsListI == AnalysisResultLists.end())
120 return;
121 // Delete the map entries that point into the results list.
122 for (auto &IDAndResult : ResultsListI->second)
123 AnalysisResults.erase({IDAndResult.first, &IR});
124
125 // And actually destroy and erase the results associated with this IR.
126 AnalysisResultLists.erase(ResultsListI);
127}
128
129template <typename IRUnitT, typename... ExtraArgTs>
130inline typename AnalysisManager<IRUnitT, ExtraArgTs...>::ResultConceptT &
132 AnalysisKey *ID, IRUnitT &IR, ExtraArgTs... ExtraArgs) {
133 typename AnalysisResultMapT::iterator RI;
134 bool Inserted;
135 std::tie(RI, Inserted) = AnalysisResults.insert(std::make_pair(
136 std::make_pair(ID, &IR), typename AnalysisResultListT::iterator()));
137
138 // If we don't have a cached result for this function, look up the pass and
139 // run it to produce a result, which we then add to the cache.
140 if (Inserted) {
141 auto &P = this->lookUpPass(ID);
142
145 PI = getResult<PassInstrumentationAnalysis>(IR, ExtraArgs...);
147 }
148
149 AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
150 ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
151
152 PI.runAfterAnalysis(P, IR);
153
154 // P.run may have inserted elements into AnalysisResults and invalidated
155 // RI.
156 RI = AnalysisResults.find({ID, &IR});
157 assert(RI != AnalysisResults.end() && "we just inserted it!");
158
159 RI->second = std::prev(ResultList.end());
160 }
161
162 return *RI->second->second;
163}
164
165template <typename IRUnitT, typename... ExtraArgTs>
167 IRUnitT &IR, const PreservedAnalyses &PA) {
168 // We're done if all analyses on this IR unit are preserved.
170 return;
171
172 // Track whether each analysis's result is invalidated in
173 // IsResultInvalidated.
174 SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
175 Invalidator Inv(IsResultInvalidated, AnalysisResults);
176 AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
177 for (auto &AnalysisResultPair : ResultsList) {
178 // This is basically the same thing as Invalidator::invalidate, but we
179 // can't call it here because we're operating on the type-erased result.
180 // Moreover if we instead called invalidate() directly, it would do an
181 // unnecessary look up in ResultsList.
182 AnalysisKey *ID = AnalysisResultPair.first;
183 auto &Result = *AnalysisResultPair.second;
184
185 auto IMapI = IsResultInvalidated.find(ID);
186 if (IMapI != IsResultInvalidated.end())
187 // This result was already handled via the Invalidator.
188 continue;
189
190 // Try to invalidate the result, giving it the Invalidator so it can
191 // recursively query for any dependencies it has and record the result.
192 // Note that we cannot reuse 'IMapI' here or pre-insert the ID, as
193 // Result.invalidate may insert things into the map, invalidating our
194 // iterator.
195 bool Inserted =
196 IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, Inv)}).second;
197 (void)Inserted;
198 assert(Inserted && "Should never have already inserted this ID, likely "
199 "indicates a cycle!");
200 }
201
202 // Now erase the results that were marked above as invalidated.
203 if (!IsResultInvalidated.empty()) {
204 for (auto I = ResultsList.begin(), E = ResultsList.end(); I != E;) {
205 AnalysisKey *ID = I->first;
206 if (!IsResultInvalidated.lookup(ID)) {
207 ++I;
208 continue;
209 }
210
211 if (auto *PI = getCachedResult<PassInstrumentationAnalysis>(IR))
212 PI->runAnalysisInvalidated(this->lookUpPass(ID), IR);
213
214 I = ResultsList.erase(I);
215 AnalysisResults.erase({ID, &IR});
216 }
217 }
218
219 if (ResultsList.empty())
220 AnalysisResultLists.erase(&IR);
221}
222} // end namespace llvm
223
224#endif // LLVM_IR_PASSMANAGERIMPL_H
aarch64 AArch64 CCMP Pass
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::string Name
Legalize the Machine IR a function s Machine IR
Definition: Legalizer.cpp:81
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
const char * Passes
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
llvm::cl::opt< bool > UseNewDbgInfoFormat
This header defines various interfaces for pass management in LLVM.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
static const char PassName[]
This templated class represents "all analyses that operate over <a particular IR unit>" (e....
Definition: Analysis.h:49
API to communicate dependencies between analyses during invalidation.
Definition: PassManager.h:292
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
AnalysisManager()
Construct an empty analysis manager.
void clear()
Clear all analysis results cached by this AnalysisManager.
Definition: PassManager.h:396
AnalysisManager & operator=(AnalysisManager &&)
void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Invalidate cached analyses for an IR unit.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:202
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
bool empty() const
Definition: DenseMap.h:98
iterator end()
Definition: DenseMap.h:84
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:220
This class provides instrumentation entry points for the Pass Manager, doing calls to callbacks regis...
void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const
BeforeAnalysis instrumentation point - takes Analysis instance to be executed and constant reference ...
void runAnalysisInvalidated(const PassT &Analysis, const IRUnitT &IR) const
AnalysisInvalidated instrumentation point - takes Analysis instance that has just been invalidated an...
StringRef getPassNameForClassName(StringRef ClassName) const
Get the pass name for a given pass class name.
void runAfterPass(const PassT &Pass, const IRUnitT &IR, const PreservedAnalyses &PA) const
AfterPass instrumentation point - takes Pass instance that has just been executed and constant refere...
void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const
AfterAnalysis instrumentation point - takes Analysis instance that has just been executed and constan...
bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const
BeforePass instrumentation point - takes Pass instance to be executed and constant reference to IR it...
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)
Run all of the passes in this manager over the given unit of IR.
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:94
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
bool allAnalysesInSetPreserved() const
Directly test whether a set of analyses is preserved.
Definition: Analysis.h:289
void intersect(const PreservedAnalyses &Arg)
Intersect this set with another in place.
Definition: Analysis.h:182
void preserveSet()
Mark an analysis set as preserved.
Definition: Analysis.h:146
PrettyStackTraceEntry - This class is used to represent a frame of the "pretty" stack trace that is d...
Used to temporarily set the debug info format of a function, module, or basic block for the duration ...
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void printIRUnitNameForStackTrace(raw_ostream &OS, const IRUnitT &IR)
static AnalysisKey * ID()
Returns an opaque, unique ID for this analysis type.
Definition: PassManager.h:108
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:28