xref: /src/contrib/llvm-project/llvm/lib/Transforms/Scalar/LoopPassManager.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1581a6d85SDimitry Andric //===- LoopPassManager.cpp - Loop pass management -------------------------===//
2581a6d85SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6581a6d85SDimitry Andric //
7581a6d85SDimitry Andric //===----------------------------------------------------------------------===//
8581a6d85SDimitry Andric 
9581a6d85SDimitry Andric #include "llvm/Transforms/Scalar/LoopPassManager.h"
10b60736ecSDimitry Andric #include "llvm/Analysis/AssumptionCache.h"
11b60736ecSDimitry Andric #include "llvm/Analysis/BlockFrequencyInfo.h"
12c0981da4SDimitry Andric #include "llvm/Analysis/BranchProbabilityInfo.h"
13b60736ecSDimitry Andric #include "llvm/Analysis/MemorySSA.h"
14145449b1SDimitry Andric #include "llvm/Analysis/ScalarEvolution.h"
15b60736ecSDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h"
16145449b1SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
17b60736ecSDimitry Andric #include "llvm/Support/TimeProfiler.h"
18581a6d85SDimitry Andric 
19581a6d85SDimitry Andric using namespace llvm;
20581a6d85SDimitry Andric 
21581a6d85SDimitry Andric namespace llvm {
22581a6d85SDimitry Andric 
23581a6d85SDimitry Andric /// Explicitly specialize the pass manager's run method to handle loop nest
24581a6d85SDimitry Andric /// structure updates.
25581a6d85SDimitry Andric PreservedAnalyses
26581a6d85SDimitry Andric PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
run(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)27581a6d85SDimitry Andric             LPMUpdater &>::run(Loop &L, LoopAnalysisManager &AM,
28581a6d85SDimitry Andric                                LoopStandardAnalysisResults &AR, LPMUpdater &U) {
29b60736ecSDimitry Andric   // Runs loop-nest passes only when the current loop is a top-level one.
30b60736ecSDimitry Andric   PreservedAnalyses PA = (L.isOutermost() && !LoopNestPasses.empty())
31b60736ecSDimitry Andric                              ? runWithLoopNestPasses(L, AM, AR, U)
32b60736ecSDimitry Andric                              : runWithoutLoopNestPasses(L, AM, AR, U);
33581a6d85SDimitry Andric 
34581a6d85SDimitry Andric   // Invalidation for the current loop should be handled above, and other loop
35581a6d85SDimitry Andric   // analysis results shouldn't be impacted by runs over this loop. Therefore,
36581a6d85SDimitry Andric   // the remaining analysis results in the AnalysisManager are preserved. We
37581a6d85SDimitry Andric   // mark this with a set so that we don't need to inspect each one
38581a6d85SDimitry Andric   // individually.
39581a6d85SDimitry Andric   // FIXME: This isn't correct! This loop and all nested loops' analyses should
40581a6d85SDimitry Andric   // be preserved, but unrolling should invalidate the parent loop's analyses.
41581a6d85SDimitry Andric   PA.preserveSet<AllAnalysesOn<Loop>>();
42581a6d85SDimitry Andric 
43581a6d85SDimitry Andric   return PA;
44581a6d85SDimitry Andric }
45b60736ecSDimitry Andric 
46c0981da4SDimitry Andric void PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
printPipeline(raw_ostream & OS,function_ref<StringRef (StringRef)> MapClassName2PassName)47c0981da4SDimitry Andric                  LPMUpdater &>::printPipeline(raw_ostream &OS,
48c0981da4SDimitry Andric                                               function_ref<StringRef(StringRef)>
49c0981da4SDimitry Andric                                                   MapClassName2PassName) {
50f65dcba8SDimitry Andric   assert(LoopPasses.size() + LoopNestPasses.size() == IsLoopNestPass.size());
51f65dcba8SDimitry Andric 
52f65dcba8SDimitry Andric   unsigned IdxLP = 0, IdxLNP = 0;
53f65dcba8SDimitry Andric   for (unsigned Idx = 0, Size = IsLoopNestPass.size(); Idx != Size; ++Idx) {
54f65dcba8SDimitry Andric     if (IsLoopNestPass[Idx]) {
55f65dcba8SDimitry Andric       auto *P = LoopNestPasses[IdxLNP++].get();
56c0981da4SDimitry Andric       P->printPipeline(OS, MapClassName2PassName);
57f65dcba8SDimitry Andric     } else {
58f65dcba8SDimitry Andric       auto *P = LoopPasses[IdxLP++].get();
59f65dcba8SDimitry Andric       P->printPipeline(OS, MapClassName2PassName);
60f65dcba8SDimitry Andric     }
61c0981da4SDimitry Andric     if (Idx + 1 < Size)
627fa27ce4SDimitry Andric       OS << ',';
63c0981da4SDimitry Andric   }
64c0981da4SDimitry Andric }
65c0981da4SDimitry Andric 
66b60736ecSDimitry Andric // Run both loop passes and loop-nest passes on top-level loop \p L.
67b60736ecSDimitry Andric PreservedAnalyses
runWithLoopNestPasses(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)68b60736ecSDimitry Andric LoopPassManager::runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
69b60736ecSDimitry Andric                                        LoopStandardAnalysisResults &AR,
70b60736ecSDimitry Andric                                        LPMUpdater &U) {
71b60736ecSDimitry Andric   assert(L.isOutermost() &&
72b60736ecSDimitry Andric          "Loop-nest passes should only run on top-level loops.");
73b60736ecSDimitry Andric   PreservedAnalyses PA = PreservedAnalyses::all();
74b60736ecSDimitry Andric 
75b60736ecSDimitry Andric   // Request PassInstrumentation from analysis manager, will use it to run
76b60736ecSDimitry Andric   // instrumenting callbacks for the passes later.
77b60736ecSDimitry Andric   PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
78b60736ecSDimitry Andric 
79b60736ecSDimitry Andric   unsigned LoopPassIndex = 0, LoopNestPassIndex = 0;
80b60736ecSDimitry Andric 
81b60736ecSDimitry Andric   // `LoopNestPtr` points to the `LoopNest` object for the current top-level
82b60736ecSDimitry Andric   // loop and `IsLoopNestPtrValid` indicates whether the pointer is still valid.
83b60736ecSDimitry Andric   // The `LoopNest` object will have to be re-constructed if the pointer is
84b60736ecSDimitry Andric   // invalid when encountering a loop-nest pass.
85b60736ecSDimitry Andric   std::unique_ptr<LoopNest> LoopNestPtr;
86b60736ecSDimitry Andric   bool IsLoopNestPtrValid = false;
87e3b55780SDimitry Andric   Loop *OuterMostLoop = &L;
88b60736ecSDimitry Andric 
89b60736ecSDimitry Andric   for (size_t I = 0, E = IsLoopNestPass.size(); I != E; ++I) {
90e3b55780SDimitry Andric     std::optional<PreservedAnalyses> PassPA;
91b60736ecSDimitry Andric     if (!IsLoopNestPass[I]) {
92b60736ecSDimitry Andric       // The `I`-th pass is a loop pass.
93b60736ecSDimitry Andric       auto &Pass = LoopPasses[LoopPassIndex++];
94b60736ecSDimitry Andric       PassPA = runSinglePass(L, Pass, AM, AR, U, PI);
95b60736ecSDimitry Andric     } else {
96b60736ecSDimitry Andric       // The `I`-th pass is a loop-nest pass.
97b60736ecSDimitry Andric       auto &Pass = LoopNestPasses[LoopNestPassIndex++];
98b60736ecSDimitry Andric 
99b60736ecSDimitry Andric       // If the loop-nest object calculated before is no longer valid,
100b60736ecSDimitry Andric       // re-calculate it here before running the loop-nest pass.
101e3b55780SDimitry Andric       //
102e3b55780SDimitry Andric       // FIXME: PreservedAnalysis should not be abused to tell if the
103e3b55780SDimitry Andric       // status of loopnest has been changed. We should use and only
104e3b55780SDimitry Andric       // use LPMUpdater for this purpose.
105e3b55780SDimitry Andric       if (!IsLoopNestPtrValid || U.isLoopNestChanged()) {
106e3b55780SDimitry Andric         while (auto *ParentLoop = OuterMostLoop->getParentLoop())
107e3b55780SDimitry Andric           OuterMostLoop = ParentLoop;
108e3b55780SDimitry Andric         LoopNestPtr = LoopNest::getLoopNest(*OuterMostLoop, AR.SE);
109b60736ecSDimitry Andric         IsLoopNestPtrValid = true;
110e3b55780SDimitry Andric         U.markLoopNestChanged(false);
111b60736ecSDimitry Andric       }
112e3b55780SDimitry Andric 
113b60736ecSDimitry Andric       PassPA = runSinglePass(*LoopNestPtr, Pass, AM, AR, U, PI);
114b60736ecSDimitry Andric     }
115b60736ecSDimitry Andric 
116b60736ecSDimitry Andric     // `PassPA` is `None` means that the before-pass callbacks in
117b60736ecSDimitry Andric     // `PassInstrumentation` return false. The pass does not run in this case,
118b60736ecSDimitry Andric     // so we can skip the following procedure.
119b60736ecSDimitry Andric     if (!PassPA)
120b60736ecSDimitry Andric       continue;
121b60736ecSDimitry Andric 
122b60736ecSDimitry Andric     // If the loop was deleted, abort the run and return to the outer walk.
123b60736ecSDimitry Andric     if (U.skipCurrentLoop()) {
124b60736ecSDimitry Andric       PA.intersect(std::move(*PassPA));
125b60736ecSDimitry Andric       break;
126b60736ecSDimitry Andric     }
127b60736ecSDimitry Andric 
128b60736ecSDimitry Andric     // Update the analysis manager as each pass runs and potentially
129b60736ecSDimitry Andric     // invalidates analyses.
130e3b55780SDimitry Andric     AM.invalidate(IsLoopNestPass[I] ? *OuterMostLoop : L, *PassPA);
131b60736ecSDimitry Andric 
132b60736ecSDimitry Andric     // Finally, we intersect the final preserved analyses to compute the
133b60736ecSDimitry Andric     // aggregate preserved set for this pass manager.
134b60736ecSDimitry Andric     PA.intersect(std::move(*PassPA));
135b60736ecSDimitry Andric 
136b60736ecSDimitry Andric     // Check if the current pass preserved the loop-nest object or not.
137b60736ecSDimitry Andric     IsLoopNestPtrValid &= PassPA->getChecker<LoopNestAnalysis>().preserved();
138b60736ecSDimitry Andric 
139344a3780SDimitry Andric     // After running the loop pass, the parent loop might change and we need to
140344a3780SDimitry Andric     // notify the updater, otherwise U.ParentL might gets outdated and triggers
141344a3780SDimitry Andric     // assertion failures in addSiblingLoops and addChildLoops.
142e3b55780SDimitry Andric     U.setParentLoop((IsLoopNestPass[I] ? *OuterMostLoop : L).getParentLoop());
143b60736ecSDimitry Andric   }
144b60736ecSDimitry Andric   return PA;
145b60736ecSDimitry Andric }
146b60736ecSDimitry Andric 
147b60736ecSDimitry Andric // Run all loop passes on loop \p L. Loop-nest passes don't run either because
148b60736ecSDimitry Andric // \p L is not a top-level one or simply because there are no loop-nest passes
149b60736ecSDimitry Andric // in the pass manager at all.
150b60736ecSDimitry Andric PreservedAnalyses
runWithoutLoopNestPasses(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)151b60736ecSDimitry Andric LoopPassManager::runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
152b60736ecSDimitry Andric                                           LoopStandardAnalysisResults &AR,
153b60736ecSDimitry Andric                                           LPMUpdater &U) {
154b60736ecSDimitry Andric   PreservedAnalyses PA = PreservedAnalyses::all();
155b60736ecSDimitry Andric 
156b60736ecSDimitry Andric   // Request PassInstrumentation from analysis manager, will use it to run
157b60736ecSDimitry Andric   // instrumenting callbacks for the passes later.
158b60736ecSDimitry Andric   PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
159b60736ecSDimitry Andric   for (auto &Pass : LoopPasses) {
160e3b55780SDimitry Andric     std::optional<PreservedAnalyses> PassPA =
161e3b55780SDimitry Andric         runSinglePass(L, Pass, AM, AR, U, PI);
162b60736ecSDimitry Andric 
163b60736ecSDimitry Andric     // `PassPA` is `None` means that the before-pass callbacks in
164b60736ecSDimitry Andric     // `PassInstrumentation` return false. The pass does not run in this case,
165b60736ecSDimitry Andric     // so we can skip the following procedure.
166b60736ecSDimitry Andric     if (!PassPA)
167b60736ecSDimitry Andric       continue;
168b60736ecSDimitry Andric 
169b60736ecSDimitry Andric     // If the loop was deleted, abort the run and return to the outer walk.
170b60736ecSDimitry Andric     if (U.skipCurrentLoop()) {
171b60736ecSDimitry Andric       PA.intersect(std::move(*PassPA));
172b60736ecSDimitry Andric       break;
173b60736ecSDimitry Andric     }
174b60736ecSDimitry Andric 
175b60736ecSDimitry Andric     // Update the analysis manager as each pass runs and potentially
176b60736ecSDimitry Andric     // invalidates analyses.
177b60736ecSDimitry Andric     AM.invalidate(L, *PassPA);
178b60736ecSDimitry Andric 
179b60736ecSDimitry Andric     // Finally, we intersect the final preserved analyses to compute the
180b60736ecSDimitry Andric     // aggregate preserved set for this pass manager.
181b60736ecSDimitry Andric     PA.intersect(std::move(*PassPA));
182b60736ecSDimitry Andric 
183344a3780SDimitry Andric     // After running the loop pass, the parent loop might change and we need to
184344a3780SDimitry Andric     // notify the updater, otherwise U.ParentL might gets outdated and triggers
185344a3780SDimitry Andric     // assertion failures in addSiblingLoops and addChildLoops.
186344a3780SDimitry Andric     U.setParentLoop(L.getParentLoop());
187b60736ecSDimitry Andric   }
188b60736ecSDimitry Andric   return PA;
189b60736ecSDimitry Andric }
190b60736ecSDimitry Andric } // namespace llvm
191b60736ecSDimitry Andric 
printPipeline(raw_ostream & OS,function_ref<StringRef (StringRef)> MapClassName2PassName)192c0981da4SDimitry Andric void FunctionToLoopPassAdaptor::printPipeline(
193c0981da4SDimitry Andric     raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
194c0981da4SDimitry Andric   OS << (UseMemorySSA ? "loop-mssa(" : "loop(");
195c0981da4SDimitry Andric   Pass->printPipeline(OS, MapClassName2PassName);
1967fa27ce4SDimitry Andric   OS << ')';
197c0981da4SDimitry Andric }
run(Function & F,FunctionAnalysisManager & AM)198b60736ecSDimitry Andric PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
199b60736ecSDimitry Andric                                                  FunctionAnalysisManager &AM) {
200b60736ecSDimitry Andric   // Before we even compute any loop analyses, first run a miniature function
201b60736ecSDimitry Andric   // pass pipeline to put loops into their canonical form. Note that we can
202b60736ecSDimitry Andric   // directly build up function analyses after this as the function pass
203b60736ecSDimitry Andric   // manager handles all the invalidation at that layer.
204b60736ecSDimitry Andric   PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(F);
205b60736ecSDimitry Andric 
206b60736ecSDimitry Andric   PreservedAnalyses PA = PreservedAnalyses::all();
207b60736ecSDimitry Andric   // Check the PassInstrumentation's BeforePass callbacks before running the
208b60736ecSDimitry Andric   // canonicalization pipeline.
209b60736ecSDimitry Andric   if (PI.runBeforePass<Function>(LoopCanonicalizationFPM, F)) {
210b60736ecSDimitry Andric     PA = LoopCanonicalizationFPM.run(F, AM);
211b60736ecSDimitry Andric     PI.runAfterPass<Function>(LoopCanonicalizationFPM, F, PA);
212b60736ecSDimitry Andric   }
213b60736ecSDimitry Andric 
214b60736ecSDimitry Andric   // Get the loop structure for this function
215b60736ecSDimitry Andric   LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
216b60736ecSDimitry Andric 
217b60736ecSDimitry Andric   // If there are no loops, there is nothing to do here.
218b60736ecSDimitry Andric   if (LI.empty())
219b60736ecSDimitry Andric     return PA;
220b60736ecSDimitry Andric 
221b60736ecSDimitry Andric   // Get the analysis results needed by loop passes.
222b60736ecSDimitry Andric   MemorySSA *MSSA =
223b60736ecSDimitry Andric       UseMemorySSA ? (&AM.getResult<MemorySSAAnalysis>(F).getMSSA()) : nullptr;
224b60736ecSDimitry Andric   BlockFrequencyInfo *BFI = UseBlockFrequencyInfo && F.hasProfileData()
225b60736ecSDimitry Andric                                 ? (&AM.getResult<BlockFrequencyAnalysis>(F))
226b60736ecSDimitry Andric                                 : nullptr;
227c0981da4SDimitry Andric   BranchProbabilityInfo *BPI =
228c0981da4SDimitry Andric       UseBranchProbabilityInfo && F.hasProfileData()
229c0981da4SDimitry Andric           ? (&AM.getResult<BranchProbabilityAnalysis>(F))
230c0981da4SDimitry Andric           : nullptr;
231b60736ecSDimitry Andric   LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),
232b60736ecSDimitry Andric                                      AM.getResult<AssumptionAnalysis>(F),
233b60736ecSDimitry Andric                                      AM.getResult<DominatorTreeAnalysis>(F),
234b60736ecSDimitry Andric                                      AM.getResult<LoopAnalysis>(F),
235b60736ecSDimitry Andric                                      AM.getResult<ScalarEvolutionAnalysis>(F),
236b60736ecSDimitry Andric                                      AM.getResult<TargetLibraryAnalysis>(F),
237b60736ecSDimitry Andric                                      AM.getResult<TargetIRAnalysis>(F),
238b60736ecSDimitry Andric                                      BFI,
239c0981da4SDimitry Andric                                      BPI,
240b60736ecSDimitry Andric                                      MSSA};
241b60736ecSDimitry Andric 
242b60736ecSDimitry Andric   // Setup the loop analysis manager from its proxy. It is important that
243b60736ecSDimitry Andric   // this is only done when there are loops to process and we have built the
244b60736ecSDimitry Andric   // LoopStandardAnalysisResults object. The loop analyses cached in this
245b60736ecSDimitry Andric   // manager have access to those analysis results and so it must invalidate
246b60736ecSDimitry Andric   // itself when they go away.
247b60736ecSDimitry Andric   auto &LAMFP = AM.getResult<LoopAnalysisManagerFunctionProxy>(F);
248b60736ecSDimitry Andric   if (UseMemorySSA)
249b60736ecSDimitry Andric     LAMFP.markMSSAUsed();
250b60736ecSDimitry Andric   LoopAnalysisManager &LAM = LAMFP.getManager();
251b60736ecSDimitry Andric 
252b60736ecSDimitry Andric   // A postorder worklist of loops to process.
253b60736ecSDimitry Andric   SmallPriorityWorklist<Loop *, 4> Worklist;
254b60736ecSDimitry Andric 
255b60736ecSDimitry Andric   // Register the worklist and loop analysis manager so that loop passes can
256b60736ecSDimitry Andric   // update them when they mutate the loop nest structure.
257b60736ecSDimitry Andric   LPMUpdater Updater(Worklist, LAM, LoopNestMode);
258b60736ecSDimitry Andric 
259b60736ecSDimitry Andric   // Add the loop nests in the reverse order of LoopInfo. See method
260b60736ecSDimitry Andric   // declaration.
261b60736ecSDimitry Andric   if (!LoopNestMode) {
262b60736ecSDimitry Andric     appendLoopsToWorklist(LI, Worklist);
263b60736ecSDimitry Andric   } else {
264b60736ecSDimitry Andric     for (Loop *L : LI)
265b60736ecSDimitry Andric       Worklist.insert(L);
266b60736ecSDimitry Andric   }
267b60736ecSDimitry Andric 
268b60736ecSDimitry Andric #ifndef NDEBUG
269b60736ecSDimitry Andric   PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) {
270b60736ecSDimitry Andric     if (isSpecialPass(PassID, {"PassManager"}))
271b60736ecSDimitry Andric       return;
272b1c73532SDimitry Andric     assert(llvm::any_cast<const Loop *>(&IR) ||
273b1c73532SDimitry Andric            llvm::any_cast<const LoopNest *>(&IR));
274b1c73532SDimitry Andric     const Loop **LPtr = llvm::any_cast<const Loop *>(&IR);
275e3b55780SDimitry Andric     const Loop *L = LPtr ? *LPtr : nullptr;
276e3b55780SDimitry Andric     if (!L)
277b1c73532SDimitry Andric       L = &llvm::any_cast<const LoopNest *>(IR)->getOutermostLoop();
278b60736ecSDimitry Andric     assert(L && "Loop should be valid for printing");
279b60736ecSDimitry Andric 
280b60736ecSDimitry Andric     // Verify the loop structure and LCSSA form before visiting the loop.
281b60736ecSDimitry Andric     L->verifyLoop();
282b60736ecSDimitry Andric     assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) &&
283b60736ecSDimitry Andric            "Loops must remain in LCSSA form!");
284b60736ecSDimitry Andric   });
285b60736ecSDimitry Andric #endif
286b60736ecSDimitry Andric 
287b60736ecSDimitry Andric   do {
288b60736ecSDimitry Andric     Loop *L = Worklist.pop_back_val();
289b60736ecSDimitry Andric     assert(!(LoopNestMode && L->getParentLoop()) &&
290b60736ecSDimitry Andric            "L should be a top-level loop in loop-nest mode.");
291b60736ecSDimitry Andric 
292b60736ecSDimitry Andric     // Reset the update structure for this loop.
293b60736ecSDimitry Andric     Updater.CurrentL = L;
294b60736ecSDimitry Andric     Updater.SkipCurrentLoop = false;
295b60736ecSDimitry Andric 
296b60736ecSDimitry Andric #ifndef NDEBUG
297b60736ecSDimitry Andric     // Save a parent loop pointer for asserts.
298b60736ecSDimitry Andric     Updater.ParentL = L->getParentLoop();
299b60736ecSDimitry Andric #endif
300b60736ecSDimitry Andric     // Check the PassInstrumentation's BeforePass callbacks before running the
301b60736ecSDimitry Andric     // pass, skip its execution completely if asked to (callback returns
302b60736ecSDimitry Andric     // false).
303b60736ecSDimitry Andric     if (!PI.runBeforePass<Loop>(*Pass, *L))
304b60736ecSDimitry Andric       continue;
305b60736ecSDimitry Andric 
306e3b55780SDimitry Andric     PreservedAnalyses PassPA = Pass->run(*L, LAM, LAR, Updater);
307b60736ecSDimitry Andric 
308b60736ecSDimitry Andric     // Do not pass deleted Loop into the instrumentation.
309b60736ecSDimitry Andric     if (Updater.skipCurrentLoop())
310b60736ecSDimitry Andric       PI.runAfterPassInvalidated<Loop>(*Pass, PassPA);
311b60736ecSDimitry Andric     else
312b60736ecSDimitry Andric       PI.runAfterPass<Loop>(*Pass, *L, PassPA);
313b60736ecSDimitry Andric 
314c0981da4SDimitry Andric     if (LAR.MSSA && !PassPA.getChecker<MemorySSAAnalysis>().preserved())
315c0981da4SDimitry Andric       report_fatal_error("Loop pass manager using MemorySSA contains a pass "
316b1c73532SDimitry Andric                          "that does not preserve MemorySSA",
317b1c73532SDimitry Andric                          /*gen_crash_diag*/ false);
318c0981da4SDimitry Andric 
319344a3780SDimitry Andric #ifndef NDEBUG
320344a3780SDimitry Andric     // LoopAnalysisResults should always be valid.
321344a3780SDimitry Andric     if (VerifyDomInfo)
322344a3780SDimitry Andric       LAR.DT.verify();
323344a3780SDimitry Andric     if (VerifyLoopInfo)
324344a3780SDimitry Andric       LAR.LI.verify(LAR.DT);
325145449b1SDimitry Andric     if (VerifySCEV)
326145449b1SDimitry Andric       LAR.SE.verify();
327344a3780SDimitry Andric     if (LAR.MSSA && VerifyMemorySSA)
328344a3780SDimitry Andric       LAR.MSSA->verifyMemorySSA();
329344a3780SDimitry Andric #endif
330b60736ecSDimitry Andric 
331b60736ecSDimitry Andric     // If the loop hasn't been deleted, we need to handle invalidation here.
332b60736ecSDimitry Andric     if (!Updater.skipCurrentLoop())
333b60736ecSDimitry Andric       // We know that the loop pass couldn't have invalidated any other
334b60736ecSDimitry Andric       // loop's analyses (that's the contract of a loop pass), so directly
335b60736ecSDimitry Andric       // handle the loop analysis manager's invalidation here.
336b60736ecSDimitry Andric       LAM.invalidate(*L, PassPA);
337b60736ecSDimitry Andric 
338b60736ecSDimitry Andric     // Then intersect the preserved set so that invalidation of module
339b60736ecSDimitry Andric     // analyses will eventually occur when the module pass completes.
340b60736ecSDimitry Andric     PA.intersect(std::move(PassPA));
341b60736ecSDimitry Andric   } while (!Worklist.empty());
342b60736ecSDimitry Andric 
343b60736ecSDimitry Andric #ifndef NDEBUG
344b60736ecSDimitry Andric   PI.popBeforeNonSkippedPassCallback();
345b60736ecSDimitry Andric #endif
346b60736ecSDimitry Andric 
347b60736ecSDimitry Andric   // By definition we preserve the proxy. We also preserve all analyses on
348b60736ecSDimitry Andric   // Loops. This precludes *any* invalidation of loop analyses by the proxy,
349b60736ecSDimitry Andric   // but that's OK because we've taken care to invalidate analyses in the
350b60736ecSDimitry Andric   // loop analysis manager incrementally above.
351b60736ecSDimitry Andric   PA.preserveSet<AllAnalysesOn<Loop>>();
352b60736ecSDimitry Andric   PA.preserve<LoopAnalysisManagerFunctionProxy>();
353b60736ecSDimitry Andric   // We also preserve the set of standard analyses.
354b60736ecSDimitry Andric   PA.preserve<DominatorTreeAnalysis>();
355b60736ecSDimitry Andric   PA.preserve<LoopAnalysis>();
356b60736ecSDimitry Andric   PA.preserve<ScalarEvolutionAnalysis>();
357b60736ecSDimitry Andric   if (UseBlockFrequencyInfo && F.hasProfileData())
358b60736ecSDimitry Andric     PA.preserve<BlockFrequencyAnalysis>();
359c0981da4SDimitry Andric   if (UseBranchProbabilityInfo && F.hasProfileData())
360c0981da4SDimitry Andric     PA.preserve<BranchProbabilityAnalysis>();
361b60736ecSDimitry Andric   if (UseMemorySSA)
362b60736ecSDimitry Andric     PA.preserve<MemorySSAAnalysis>();
363b60736ecSDimitry Andric   return PA;
364581a6d85SDimitry Andric }
365581a6d85SDimitry Andric 
PrintLoopPass()366581a6d85SDimitry Andric PrintLoopPass::PrintLoopPass() : OS(dbgs()) {}
PrintLoopPass(raw_ostream & OS,const std::string & Banner)367581a6d85SDimitry Andric PrintLoopPass::PrintLoopPass(raw_ostream &OS, const std::string &Banner)
368581a6d85SDimitry Andric     : OS(OS), Banner(Banner) {}
369581a6d85SDimitry Andric 
run(Loop & L,LoopAnalysisManager &,LoopStandardAnalysisResults &,LPMUpdater &)370581a6d85SDimitry Andric PreservedAnalyses PrintLoopPass::run(Loop &L, LoopAnalysisManager &,
371581a6d85SDimitry Andric                                      LoopStandardAnalysisResults &,
372581a6d85SDimitry Andric                                      LPMUpdater &) {
373581a6d85SDimitry Andric   printLoop(L, OS, Banner);
374581a6d85SDimitry Andric   return PreservedAnalyses::all();
375581a6d85SDimitry Andric }
376