LLVM 24.0.0git
LoopPassManager.cpp
Go to the documentation of this file.
1//===- LoopPassManager.cpp - Loop pass management -------------------------===//
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
15
16using namespace llvm;
17
18/// Explicitly specialize the pass manager's run method to handle loop nest
19/// structure updates.
22 LPMUpdater &>::run(Loop &L, LoopAnalysisManager &AM,
24 // Runs loop-nest passes only when the current loop is a top-level one.
25 PreservedAnalyses PA = (L.isOutermost() && !LoopNestPasses.empty())
26 ? runWithLoopNestPasses(L, AM, AR, U)
27 : runWithoutLoopNestPasses(L, AM, AR, U);
28
29 // Invalidation for the current loop should be handled above, and other loop
30 // analysis results shouldn't be impacted by runs over this loop. Therefore,
31 // the remaining analysis results in the AnalysisManager are preserved. We
32 // mark this with a set so that we don't need to inspect each one
33 // individually.
34 // FIXME: This isn't correct! This loop and all nested loops' analyses should
35 // be preserved, but unrolling should invalidate the parent loop's analyses.
37
38 return PA;
39}
40
42 LPMUpdater &>::printPipeline(raw_ostream &OS,
44 MapClassName2PassName) {
45 assert(LoopPasses.size() + LoopNestPasses.size() == IsLoopNestPass.size());
46
47 unsigned IdxLP = 0, IdxLNP = 0;
48 for (unsigned Idx = 0, Size = IsLoopNestPass.size(); Idx != Size; ++Idx) {
49 if (IsLoopNestPass[Idx]) {
50 auto *P = LoopNestPasses[IdxLNP++].get();
51 P->printPipeline(OS, MapClassName2PassName);
52 } else {
53 auto *P = LoopPasses[IdxLP++].get();
54 P->printPipeline(OS, MapClassName2PassName);
55 }
56 if (Idx + 1 < Size)
57 OS << ',';
58 }
59}
60
61// Run both loop passes and loop-nest passes on top-level loop \p L.
63LoopPassManager::runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
65 LPMUpdater &U) {
66 assert(L.isOutermost() &&
67 "Loop-nest passes should only run on top-level loops.");
68 PreservedAnalyses PA = PreservedAnalyses::all();
69
70 // Request PassInstrumentation from analysis manager, will use it to run
71 // instrumenting callbacks for the passes later.
72 PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
73
74 unsigned LoopPassIndex = 0, LoopNestPassIndex = 0;
75
76 // `LoopNestPtr` points to the `LoopNest` object for the current top-level
77 // loop and `IsLoopNestPtrValid` indicates whether the pointer is still valid.
78 // The `LoopNest` object will have to be re-constructed if the pointer is
79 // invalid when encountering a loop-nest pass.
80 std::unique_ptr<LoopNest> LoopNestPtr;
81 bool IsLoopNestPtrValid = false;
82 Loop *OuterMostLoop = &L;
83
84 for (size_t I = 0, E = IsLoopNestPass.size(); I != E; ++I) {
85 std::optional<PreservedAnalyses> PassPA;
86 if (!IsLoopNestPass[I]) {
87 // The `I`-th pass is a loop pass.
88 auto &Pass = LoopPasses[LoopPassIndex++];
89 PassPA = runSinglePass(L, Pass, AM, AR, U, PI);
90 } else {
91 // The `I`-th pass is a loop-nest pass.
92 auto &Pass = LoopNestPasses[LoopNestPassIndex++];
93
94 // If the loop-nest object calculated before is no longer valid,
95 // re-calculate it here before running the loop-nest pass.
96 //
97 // FIXME: PreservedAnalysis should not be abused to tell if the
98 // status of loopnest has been changed. We should use and only
99 // use LPMUpdater for this purpose.
100 if (!IsLoopNestPtrValid || U.isLoopNestChanged()) {
101 while (auto *ParentLoop = OuterMostLoop->getParentLoop())
102 OuterMostLoop = ParentLoop;
103 LoopNestPtr = LoopNest::getLoopNest(*OuterMostLoop, AR.SE);
104 IsLoopNestPtrValid = true;
105 U.markLoopNestChanged(false);
106 }
107
108 PassPA = runSinglePass(*LoopNestPtr, Pass, AM, AR, U, PI);
109 }
110
111 // `PassPA` is `None` means that the before-pass callbacks in
112 // `PassInstrumentation` return false. The pass does not run in this case,
113 // so we can skip the following procedure.
114 if (!PassPA)
115 continue;
116
117 // If the loop was deleted, abort the run and return to the outer walk.
118 if (U.skipCurrentLoop()) {
119 PA.intersect(std::move(*PassPA));
120 break;
121 }
122
123 // Update the analysis manager as each pass runs and potentially
124 // invalidates analyses.
125 AM.invalidate(IsLoopNestPass[I] ? *OuterMostLoop : L, *PassPA);
126
127 // Finally, we intersect the final preserved analyses to compute the
128 // aggregate preserved set for this pass manager.
129 PA.intersect(std::move(*PassPA));
130
131 // Check if the current pass preserved the loop-nest object or not.
132 IsLoopNestPtrValid &= PassPA->getChecker<LoopNestAnalysis>().preserved();
133
134 // After running the loop pass, the parent loop might change and we need to
135 // notify the updater, otherwise U.ParentL might gets outdated and triggers
136 // assertion failures in addSiblingLoops and addChildLoops.
137 U.setParentLoop((IsLoopNestPass[I] ? *OuterMostLoop : L).getParentLoop());
138 }
139 return PA;
140}
141
142// Run all loop passes on loop \p L. Loop-nest passes don't run either because
143// \p L is not a top-level one or simply because there are no loop-nest passes
144// in the pass manager at all.
146LoopPassManager::runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
148 LPMUpdater &U) {
149 PreservedAnalyses PA = PreservedAnalyses::all();
150
151 // Request PassInstrumentation from analysis manager, will use it to run
152 // instrumenting callbacks for the passes later.
153 PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
154 for (auto &Pass : LoopPasses) {
155 std::optional<PreservedAnalyses> PassPA =
156 runSinglePass(L, Pass, AM, AR, U, PI);
157
158 // `PassPA` is `None` means that the before-pass callbacks in
159 // `PassInstrumentation` return false. The pass does not run in this case,
160 // so we can skip the following procedure.
161 if (!PassPA)
162 continue;
163
164 // If the loop was deleted, abort the run and return to the outer walk.
165 if (U.skipCurrentLoop()) {
166 PA.intersect(std::move(*PassPA));
167 break;
168 }
169
170 // Update the analysis manager as each pass runs and potentially
171 // invalidates analyses.
172 AM.invalidate(L, *PassPA);
173
174 // Finally, we intersect the final preserved analyses to compute the
175 // aggregate preserved set for this pass manager.
176 PA.intersect(std::move(*PassPA));
177
178 // After running the loop pass, the parent loop might change and we need to
179 // notify the updater, otherwise U.ParentL might gets outdated and triggers
180 // assertion failures in addSiblingLoops and addChildLoops.
181 U.setParentLoop(L.getParentLoop());
182 }
183 return PA;
184}
185
187 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
188 OS << (UseMemorySSA ? "loop-mssa(" : "loop(");
189 Pass->printPipeline(OS, MapClassName2PassName);
190 OS << ')';
191}
192
196 // If there are no loops, there's no need to run any loop passes or construct
197 // the required analyses.
198 if (AM.getResult<LoopAnalysis>(F).empty())
199 return PA;
200
201 // Before we even compute any loop analyses, first run a miniature function
202 // pass pipeline to put loops into their canonical form. Note that we can
203 // directly build up function analyses after this as the function pass
204 // manager handles all the invalidation at that layer.
206
207 // Check the PassInstrumentation's BeforePass callbacks before running the
208 // canonicalization pipeline.
209 if (PI.runBeforePass<Function>(LoopCanonicalizationFPM, F)) {
210 PA = LoopCanonicalizationFPM.run(F, AM);
211 PI.runAfterPass<Function>(LoopCanonicalizationFPM, F, PA);
212 }
213
214 // Get the loop structure for this function
215 LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
216
217 // Get the analysis results needed by loop passes.
218 MemorySSA *MSSA =
219 UseMemorySSA ? (&AM.getResult<MemorySSAAnalysis>(F).getMSSA()) : nullptr;
227 MSSA};
228
229 // Setup the loop analysis manager from its proxy. It is important that
230 // this is only done when there are loops to process and we have built the
231 // LoopStandardAnalysisResults object. The loop analyses cached in this
232 // manager have access to those analysis results and so it must invalidate
233 // itself when they go away.
234 auto &LAMFP = AM.getResult<LoopAnalysisManagerFunctionProxy>(F);
235 if (UseMemorySSA)
236 LAMFP.markMSSAUsed();
237 LoopAnalysisManager &LAM = LAMFP.getManager();
238
239 // A postorder worklist of loops to process.
241
242 // Register the worklist and loop analysis manager so that loop passes can
243 // update them when they mutate the loop nest structure.
244 LPMUpdater Updater(Worklist, LAM, LoopNestMode);
245
246 // Add the loop nests in the reverse order of LoopInfo. See method
247 // declaration.
248 if (!LoopNestMode) {
249 appendLoopsToWorklist(LI, Worklist);
250 } else {
251 for (Loop *L : LI)
252 Worklist.insert(L);
253 }
254
255#ifndef NDEBUG
256 PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID,
257 IRUnitRef IR) {
258 if (isSpecialPass(PassID, {"PassManager"}))
259 return;
260 const Loop *L = cast<Loop>(IR);
261
262 // Verify the loop structure and LCSSA form before visiting the loop.
263 L->verifyLoop();
264 assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) &&
265 "Loops must remain in LCSSA form!");
266 });
267#endif
268
269 do {
270 Loop *L = Worklist.pop_back_val();
271 assert(!(LoopNestMode && L->getParentLoop()) &&
272 "L should be a top-level loop in loop-nest mode.");
273
274 // Reset the update structure for this loop.
275 Updater.CurrentL = L;
276 Updater.SkipCurrentLoop = false;
277
278#if LLVM_ENABLE_ABI_BREAKING_CHECKS
279 // Save a parent loop pointer for asserts.
280 Updater.ParentL = L->getParentLoop();
281#endif
282 // Check the PassInstrumentation's BeforePass callbacks before running the
283 // pass, skip its execution completely if asked to (callback returns
284 // false).
285 if (!PI.runBeforePass<Loop>(*Pass, *L))
286 continue;
287
288 PreservedAnalyses PassPA = Pass->run(*L, LAM, LAR, Updater);
289
290 // Do not pass deleted Loop into the instrumentation.
291 if (Updater.skipCurrentLoop())
292 PI.runAfterPassInvalidated<Loop>(*Pass, PassPA);
293 else
294 PI.runAfterPass<Loop>(*Pass, *L, PassPA);
295
296 if (LAR.MSSA && !PassPA.getChecker<MemorySSAAnalysis>().preserved())
297 reportFatalUsageError("Loop pass manager using MemorySSA contains a pass "
298 "that does not preserve MemorySSA");
299
300#ifndef NDEBUG
301 // LoopAnalysisResults should always be valid.
302 if (VerifyDomInfo)
303 LAR.DT.verify();
304 if (VerifyLoopInfo)
305 LAR.LI.verify();
306 if (VerifySCEV)
307 LAR.SE.verify();
308 if (LAR.MSSA && VerifyMemorySSA)
309 LAR.MSSA->verifyMemorySSA();
310#endif
311
312 // If the loop hasn't been deleted, we need to handle invalidation here.
313 if (!Updater.skipCurrentLoop())
314 // We know that the loop pass couldn't have invalidated any other
315 // loop's analyses (that's the contract of a loop pass), so directly
316 // handle the loop analysis manager's invalidation here.
317 LAM.invalidate(*L, PassPA);
318
319 // Then intersect the preserved set so that invalidation of module
320 // analyses will eventually occur when the module pass completes.
321 PA.intersect(std::move(PassPA));
322 } while (!Worklist.empty());
323
324#ifndef NDEBUG
326#endif
327
328 // By definition we preserve the proxy. We also preserve all analyses on
329 // Loops. This precludes *any* invalidation of loop analyses by the proxy,
330 // but that's OK because we've taken care to invalidate analyses in the
331 // loop analysis manager incrementally above.
333 PA.preserve<LoopAnalysisManagerFunctionProxy>();
334 // We also preserve the set of standard analyses.
338 if (UseMemorySSA)
340 return PA;
341}
342
344PrintLoopPass::PrintLoopPass(raw_ostream &OS, const std::string &Banner)
345 : OS(OS), Banner(Banner) {}
346
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Legalize the Machine IR a function s Machine IR
Definition Legalizer.cpp:81
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
print mir2vec MIR2Vec Vocabulary Printer Pass
Definition MIR2Vec.cpp:621
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
#define P(N)
LoopAnalysisManager LAM
This pass exposes codegen information to IR-level passes.
A manager for alias analyses.
This templated class represents "all analyses that operate over <aparticular IR unit>" (e....
Definition Analysis.h:50
void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Invalidate cached analyses for an IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
A function analysis which provides an AssumptionCache.
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Runs the loop passes across every loop in the function.
A type-erased reference to the IR unit a pass or analysis is running on, together with the kind of IR...
Definition IRUnitRef.h:60
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
bool skipCurrentLoop() const
This can be queried by loop passes which run other loop passes (like pass managers) to know whether t...
Analysis pass that exposes the LoopInfo for a function.
Definition LoopInfo.h:587
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
static std::unique_ptr< LoopNest > getLoopNest(Loop &Root, ScalarEvolution &SE)
Construct a LoopNest object.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
An analysis that produces MemorySSA for a function.
Definition MemorySSA.h:922
Encapsulates MemorySSA, including all data associated with memory accesses.
Definition MemorySSA.h:702
LLVM_ABI void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
Pseudo-analysis pass that exposes the PassInstrumentation to pass managers.
This class provides instrumentation entry points for the Pass Manager, doing calls to callbacks regis...
void runAfterPassInvalidated(const PassT &Pass, const PreservedAnalyses &PA) const
AfterPassInvalidated instrumentation point - takes Pass instance that has just been executed.
void pushBeforeNonSkippedPassCallback(CallableT C)
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...
bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const
BeforePass instrumentation point - takes Pass instance to be executed and constant reference to IR it...
Manages a sequence of passes over a particular unit of IR.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
void intersect(const PreservedAnalyses &Arg)
Intersect this set with another in place.
Definition Analysis.h:193
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
Definition Analysis.h:275
LLVM_ABI PreservedAnalyses run(Loop &L, LoopAnalysisManager &, LoopStandardAnalysisResults &, LPMUpdater &)
bool empty() const
Determine if the PriorityWorklist is empty or not.
bool insert(const T &X)
Insert a new element into the PriorityWorklist.
Analysis pass that exposes the ScalarEvolution for a function.
LLVM_ABI void verify() const
A version of PriorityWorklist that selects small size optimized data structures for the vector and ma...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool VerifySCEV
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_TEMPLATE_ABI void appendLoopsToWorklist(RangeT &&, SmallPriorityWorklist< Loop *, 4 > &)
Utility that implements appending of loops onto a worklist given a range.
LLVM_ABI bool isSpecialPass(StringRef PassID, const std::vector< StringRef > &Specials)
LLVM_ABI bool VerifyLoopInfo
Enable verification of loop info.
Definition LoopInfo.cpp:53
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
Definition MemorySSA.cpp:85
LLVM_ABI void printLoop(const Loop &L, raw_ostream &OS, const std::string &Banner="")
Function to print a loop's contents as LLVM's text IR assembly.
LLVM_ABI bool VerifyDomInfo
Enables verification of dominator trees.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...