13bab7e1aSChandler Carruth //===- LoopPassManager.cpp - Loop pass management -------------------------===//
23bab7e1aSChandler Carruth //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63bab7e1aSChandler Carruth //
73bab7e1aSChandler Carruth //===----------------------------------------------------------------------===//
83bab7e1aSChandler Carruth
93bab7e1aSChandler Carruth #include "llvm/Transforms/Scalar/LoopPassManager.h"
109ed8e0caSdfukalov #include "llvm/Analysis/AssumptionCache.h"
119ed8e0caSdfukalov #include "llvm/Analysis/BlockFrequencyInfo.h"
12452714f8SAnna Thomas #include "llvm/Analysis/BranchProbabilityInfo.h"
139ed8e0caSdfukalov #include "llvm/Analysis/MemorySSA.h"
1471c3a551Sserge-sans-paille #include "llvm/Analysis/ScalarEvolution.h"
159ed8e0caSdfukalov #include "llvm/Analysis/TargetLibraryInfo.h"
16a494ae43Sserge-sans-paille #include "llvm/Analysis/TargetTransformInfo.h"
179ed8e0caSdfukalov #include "llvm/Support/TimeProfiler.h"
183bab7e1aSChandler Carruth
193bab7e1aSChandler Carruth using namespace llvm;
203bab7e1aSChandler Carruth
213bab7e1aSChandler Carruth namespace llvm {
223bab7e1aSChandler Carruth
233bab7e1aSChandler Carruth /// Explicitly specialize the pass manager's run method to handle loop nest
243bab7e1aSChandler Carruth /// structure updates.
253bab7e1aSChandler Carruth PreservedAnalyses
263bab7e1aSChandler Carruth PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
run(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)273bab7e1aSChandler Carruth LPMUpdater &>::run(Loop &L, LoopAnalysisManager &AM,
283bab7e1aSChandler Carruth LoopStandardAnalysisResults &AR, LPMUpdater &U) {
29fa3693adSWhitney Tsang // Runs loop-nest passes only when the current loop is a top-level one.
30fa3693adSWhitney Tsang PreservedAnalyses PA = (L.isOutermost() && !LoopNestPasses.empty())
31fa3693adSWhitney Tsang ? runWithLoopNestPasses(L, AM, AR, U)
32fa3693adSWhitney Tsang : runWithoutLoopNestPasses(L, AM, AR, U);
333bab7e1aSChandler Carruth
343bab7e1aSChandler Carruth // Invalidation for the current loop should be handled above, and other loop
353bab7e1aSChandler Carruth // analysis results shouldn't be impacted by runs over this loop. Therefore,
363bab7e1aSChandler Carruth // the remaining analysis results in the AnalysisManager are preserved. We
373bab7e1aSChandler Carruth // mark this with a set so that we don't need to inspect each one
383bab7e1aSChandler Carruth // individually.
393bab7e1aSChandler Carruth // FIXME: This isn't correct! This loop and all nested loops' analyses should
403bab7e1aSChandler Carruth // be preserved, but unrolling should invalidate the parent loop's analyses.
413bab7e1aSChandler Carruth PA.preserveSet<AllAnalysesOn<Loop>>();
423bab7e1aSChandler Carruth
433bab7e1aSChandler Carruth return PA;
443bab7e1aSChandler Carruth }
45fa3693adSWhitney Tsang
46304f2bd2SMarkus Lavin void PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
printPipeline(raw_ostream & OS,function_ref<StringRef (StringRef)> MapClassName2PassName)47304f2bd2SMarkus Lavin LPMUpdater &>::printPipeline(raw_ostream &OS,
48304f2bd2SMarkus Lavin function_ref<StringRef(StringRef)>
49304f2bd2SMarkus Lavin MapClassName2PassName) {
50ce22b7f1SMarkus Lavin assert(LoopPasses.size() + LoopNestPasses.size() == IsLoopNestPass.size());
51ce22b7f1SMarkus Lavin
52ce22b7f1SMarkus Lavin unsigned IdxLP = 0, IdxLNP = 0;
53ce22b7f1SMarkus Lavin for (unsigned Idx = 0, Size = IsLoopNestPass.size(); Idx != Size; ++Idx) {
54ce22b7f1SMarkus Lavin if (IsLoopNestPass[Idx]) {
55ce22b7f1SMarkus Lavin auto *P = LoopNestPasses[IdxLNP++].get();
56304f2bd2SMarkus Lavin P->printPipeline(OS, MapClassName2PassName);
57ce22b7f1SMarkus Lavin } else {
58ce22b7f1SMarkus Lavin auto *P = LoopPasses[IdxLP++].get();
59ce22b7f1SMarkus Lavin P->printPipeline(OS, MapClassName2PassName);
60ce22b7f1SMarkus Lavin }
61304f2bd2SMarkus Lavin if (Idx + 1 < Size)
62304f2bd2SMarkus Lavin OS << ",";
63304f2bd2SMarkus Lavin }
64304f2bd2SMarkus Lavin }
65304f2bd2SMarkus Lavin
66fa3693adSWhitney Tsang // Run both loop passes and loop-nest passes on top-level loop \p L.
67fa3693adSWhitney Tsang PreservedAnalyses
runWithLoopNestPasses(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)68fa3693adSWhitney Tsang LoopPassManager::runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
69fa3693adSWhitney Tsang LoopStandardAnalysisResults &AR,
70fa3693adSWhitney Tsang LPMUpdater &U) {
71fa3693adSWhitney Tsang assert(L.isOutermost() &&
72fa3693adSWhitney Tsang "Loop-nest passes should only run on top-level loops.");
73fa3693adSWhitney Tsang PreservedAnalyses PA = PreservedAnalyses::all();
74fa3693adSWhitney Tsang
75fa3693adSWhitney Tsang // Request PassInstrumentation from analysis manager, will use it to run
76fa3693adSWhitney Tsang // instrumenting callbacks for the passes later.
77fa3693adSWhitney Tsang PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
78fa3693adSWhitney Tsang
79fa3693adSWhitney Tsang unsigned LoopPassIndex = 0, LoopNestPassIndex = 0;
80fa3693adSWhitney Tsang
81fa3693adSWhitney Tsang // `LoopNestPtr` points to the `LoopNest` object for the current top-level
82fa3693adSWhitney Tsang // loop and `IsLoopNestPtrValid` indicates whether the pointer is still valid.
83fa3693adSWhitney Tsang // The `LoopNest` object will have to be re-constructed if the pointer is
84fa3693adSWhitney Tsang // invalid when encountering a loop-nest pass.
85fa3693adSWhitney Tsang std::unique_ptr<LoopNest> LoopNestPtr;
86fa3693adSWhitney Tsang bool IsLoopNestPtrValid = false;
87fa3693adSWhitney Tsang
88fa3693adSWhitney Tsang for (size_t I = 0, E = IsLoopNestPass.size(); I != E; ++I) {
89fa3693adSWhitney Tsang Optional<PreservedAnalyses> PassPA;
90fa3693adSWhitney Tsang if (!IsLoopNestPass[I]) {
91fa3693adSWhitney Tsang // The `I`-th pass is a loop pass.
92fa3693adSWhitney Tsang auto &Pass = LoopPasses[LoopPassIndex++];
93fa3693adSWhitney Tsang PassPA = runSinglePass(L, Pass, AM, AR, U, PI);
94fa3693adSWhitney Tsang } else {
95fa3693adSWhitney Tsang // The `I`-th pass is a loop-nest pass.
96fa3693adSWhitney Tsang auto &Pass = LoopNestPasses[LoopNestPassIndex++];
97fa3693adSWhitney Tsang
98fa3693adSWhitney Tsang // If the loop-nest object calculated before is no longer valid,
99fa3693adSWhitney Tsang // re-calculate it here before running the loop-nest pass.
100fa3693adSWhitney Tsang if (!IsLoopNestPtrValid) {
101fa3693adSWhitney Tsang LoopNestPtr = LoopNest::getLoopNest(L, AR.SE);
102fa3693adSWhitney Tsang IsLoopNestPtrValid = true;
1033bab7e1aSChandler Carruth }
104fa3693adSWhitney Tsang PassPA = runSinglePass(*LoopNestPtr, Pass, AM, AR, U, PI);
105fa3693adSWhitney Tsang }
106fa3693adSWhitney Tsang
107fa3693adSWhitney Tsang // `PassPA` is `None` means that the before-pass callbacks in
108fa3693adSWhitney Tsang // `PassInstrumentation` return false. The pass does not run in this case,
109fa3693adSWhitney Tsang // so we can skip the following procedure.
110fa3693adSWhitney Tsang if (!PassPA)
111fa3693adSWhitney Tsang continue;
112fa3693adSWhitney Tsang
113fa3693adSWhitney Tsang // If the loop was deleted, abort the run and return to the outer walk.
114fa3693adSWhitney Tsang if (U.skipCurrentLoop()) {
115fa3693adSWhitney Tsang PA.intersect(std::move(*PassPA));
116fa3693adSWhitney Tsang break;
117fa3693adSWhitney Tsang }
118fa3693adSWhitney Tsang
119fa3693adSWhitney Tsang // Update the analysis manager as each pass runs and potentially
120fa3693adSWhitney Tsang // invalidates analyses.
121fa3693adSWhitney Tsang AM.invalidate(L, *PassPA);
122fa3693adSWhitney Tsang
123fa3693adSWhitney Tsang // Finally, we intersect the final preserved analyses to compute the
124fa3693adSWhitney Tsang // aggregate preserved set for this pass manager.
125fa3693adSWhitney Tsang PA.intersect(std::move(*PassPA));
126fa3693adSWhitney Tsang
127fa3693adSWhitney Tsang // Check if the current pass preserved the loop-nest object or not.
128fa3693adSWhitney Tsang IsLoopNestPtrValid &= PassPA->getChecker<LoopNestAnalysis>().preserved();
129fa3693adSWhitney Tsang
130f70cdc5bSTa-Wei Tu // After running the loop pass, the parent loop might change and we need to
131f70cdc5bSTa-Wei Tu // notify the updater, otherwise U.ParentL might gets outdated and triggers
132f70cdc5bSTa-Wei Tu // assertion failures in addSiblingLoops and addChildLoops.
133f70cdc5bSTa-Wei Tu U.setParentLoop(L.getParentLoop());
134fa3693adSWhitney Tsang }
135fa3693adSWhitney Tsang return PA;
136fa3693adSWhitney Tsang }
137fa3693adSWhitney Tsang
138fa3693adSWhitney Tsang // Run all loop passes on loop \p L. Loop-nest passes don't run either because
139fa3693adSWhitney Tsang // \p L is not a top-level one or simply because there are no loop-nest passes
140fa3693adSWhitney Tsang // in the pass manager at all.
141fa3693adSWhitney Tsang PreservedAnalyses
runWithoutLoopNestPasses(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)142fa3693adSWhitney Tsang LoopPassManager::runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,
143fa3693adSWhitney Tsang LoopStandardAnalysisResults &AR,
144fa3693adSWhitney Tsang LPMUpdater &U) {
145fa3693adSWhitney Tsang PreservedAnalyses PA = PreservedAnalyses::all();
146fa3693adSWhitney Tsang
147fa3693adSWhitney Tsang // Request PassInstrumentation from analysis manager, will use it to run
148fa3693adSWhitney Tsang // instrumenting callbacks for the passes later.
149fa3693adSWhitney Tsang PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
150fa3693adSWhitney Tsang for (auto &Pass : LoopPasses) {
151fa3693adSWhitney Tsang Optional<PreservedAnalyses> PassPA = runSinglePass(L, Pass, AM, AR, U, PI);
152fa3693adSWhitney Tsang
153fa3693adSWhitney Tsang // `PassPA` is `None` means that the before-pass callbacks in
154fa3693adSWhitney Tsang // `PassInstrumentation` return false. The pass does not run in this case,
155fa3693adSWhitney Tsang // so we can skip the following procedure.
156fa3693adSWhitney Tsang if (!PassPA)
157fa3693adSWhitney Tsang continue;
158fa3693adSWhitney Tsang
159fa3693adSWhitney Tsang // If the loop was deleted, abort the run and return to the outer walk.
160fa3693adSWhitney Tsang if (U.skipCurrentLoop()) {
161fa3693adSWhitney Tsang PA.intersect(std::move(*PassPA));
162fa3693adSWhitney Tsang break;
163fa3693adSWhitney Tsang }
164fa3693adSWhitney Tsang
165fa3693adSWhitney Tsang // Update the analysis manager as each pass runs and potentially
166fa3693adSWhitney Tsang // invalidates analyses.
167fa3693adSWhitney Tsang AM.invalidate(L, *PassPA);
168fa3693adSWhitney Tsang
169fa3693adSWhitney Tsang // Finally, we intersect the final preserved analyses to compute the
170fa3693adSWhitney Tsang // aggregate preserved set for this pass manager.
171fa3693adSWhitney Tsang PA.intersect(std::move(*PassPA));
172fa3693adSWhitney Tsang
173f70cdc5bSTa-Wei Tu // After running the loop pass, the parent loop might change and we need to
174f70cdc5bSTa-Wei Tu // notify the updater, otherwise U.ParentL might gets outdated and triggers
175f70cdc5bSTa-Wei Tu // assertion failures in addSiblingLoops and addChildLoops.
176f70cdc5bSTa-Wei Tu U.setParentLoop(L.getParentLoop());
177fa3693adSWhitney Tsang }
178fa3693adSWhitney Tsang return PA;
179fa3693adSWhitney Tsang }
180fa3693adSWhitney Tsang } // namespace llvm
1813bab7e1aSChandler Carruth
printPipeline(raw_ostream & OS,function_ref<StringRef (StringRef)> MapClassName2PassName)182304f2bd2SMarkus Lavin void FunctionToLoopPassAdaptor::printPipeline(
183304f2bd2SMarkus Lavin raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
184304f2bd2SMarkus Lavin OS << (UseMemorySSA ? "loop-mssa(" : "loop(");
185304f2bd2SMarkus Lavin Pass->printPipeline(OS, MapClassName2PassName);
186304f2bd2SMarkus Lavin OS << ")";
187304f2bd2SMarkus Lavin }
run(Function & F,FunctionAnalysisManager & AM)1887f6f9f4cSArthur Eubanks PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
1897f6f9f4cSArthur Eubanks FunctionAnalysisManager &AM) {
1907f6f9f4cSArthur Eubanks // Before we even compute any loop analyses, first run a miniature function
1917f6f9f4cSArthur Eubanks // pass pipeline to put loops into their canonical form. Note that we can
1927f6f9f4cSArthur Eubanks // directly build up function analyses after this as the function pass
1937f6f9f4cSArthur Eubanks // manager handles all the invalidation at that layer.
1947f6f9f4cSArthur Eubanks PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(F);
1957f6f9f4cSArthur Eubanks
1967f6f9f4cSArthur Eubanks PreservedAnalyses PA = PreservedAnalyses::all();
1977f6f9f4cSArthur Eubanks // Check the PassInstrumentation's BeforePass callbacks before running the
1987f6f9f4cSArthur Eubanks // canonicalization pipeline.
1997f6f9f4cSArthur Eubanks if (PI.runBeforePass<Function>(LoopCanonicalizationFPM, F)) {
2007f6f9f4cSArthur Eubanks PA = LoopCanonicalizationFPM.run(F, AM);
2017f6f9f4cSArthur Eubanks PI.runAfterPass<Function>(LoopCanonicalizationFPM, F, PA);
2027f6f9f4cSArthur Eubanks }
2037f6f9f4cSArthur Eubanks
2047f6f9f4cSArthur Eubanks // Get the loop structure for this function
2057f6f9f4cSArthur Eubanks LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
2067f6f9f4cSArthur Eubanks
2077f6f9f4cSArthur Eubanks // If there are no loops, there is nothing to do here.
2087f6f9f4cSArthur Eubanks if (LI.empty())
2097f6f9f4cSArthur Eubanks return PA;
2107f6f9f4cSArthur Eubanks
2117f6f9f4cSArthur Eubanks // Get the analysis results needed by loop passes.
2127f6f9f4cSArthur Eubanks MemorySSA *MSSA =
2137f6f9f4cSArthur Eubanks UseMemorySSA ? (&AM.getResult<MemorySSAAnalysis>(F).getMSSA()) : nullptr;
2147f6f9f4cSArthur Eubanks BlockFrequencyInfo *BFI = UseBlockFrequencyInfo && F.hasProfileData()
2157f6f9f4cSArthur Eubanks ? (&AM.getResult<BlockFrequencyAnalysis>(F))
2167f6f9f4cSArthur Eubanks : nullptr;
217452714f8SAnna Thomas BranchProbabilityInfo *BPI =
218452714f8SAnna Thomas UseBranchProbabilityInfo && F.hasProfileData()
219452714f8SAnna Thomas ? (&AM.getResult<BranchProbabilityAnalysis>(F))
220452714f8SAnna Thomas : nullptr;
2217f6f9f4cSArthur Eubanks LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),
2227f6f9f4cSArthur Eubanks AM.getResult<AssumptionAnalysis>(F),
2237f6f9f4cSArthur Eubanks AM.getResult<DominatorTreeAnalysis>(F),
2247f6f9f4cSArthur Eubanks AM.getResult<LoopAnalysis>(F),
2257f6f9f4cSArthur Eubanks AM.getResult<ScalarEvolutionAnalysis>(F),
2267f6f9f4cSArthur Eubanks AM.getResult<TargetLibraryAnalysis>(F),
2277f6f9f4cSArthur Eubanks AM.getResult<TargetIRAnalysis>(F),
2287f6f9f4cSArthur Eubanks BFI,
229452714f8SAnna Thomas BPI,
2307f6f9f4cSArthur Eubanks MSSA};
2317f6f9f4cSArthur Eubanks
2327f6f9f4cSArthur Eubanks // Setup the loop analysis manager from its proxy. It is important that
2337f6f9f4cSArthur Eubanks // this is only done when there are loops to process and we have built the
2347f6f9f4cSArthur Eubanks // LoopStandardAnalysisResults object. The loop analyses cached in this
2357f6f9f4cSArthur Eubanks // manager have access to those analysis results and so it must invalidate
2367f6f9f4cSArthur Eubanks // itself when they go away.
2377f6f9f4cSArthur Eubanks auto &LAMFP = AM.getResult<LoopAnalysisManagerFunctionProxy>(F);
2387f6f9f4cSArthur Eubanks if (UseMemorySSA)
2397f6f9f4cSArthur Eubanks LAMFP.markMSSAUsed();
2407f6f9f4cSArthur Eubanks LoopAnalysisManager &LAM = LAMFP.getManager();
2417f6f9f4cSArthur Eubanks
2427f6f9f4cSArthur Eubanks // A postorder worklist of loops to process.
2437f6f9f4cSArthur Eubanks SmallPriorityWorklist<Loop *, 4> Worklist;
2447f6f9f4cSArthur Eubanks
2457f6f9f4cSArthur Eubanks // Register the worklist and loop analysis manager so that loop passes can
2467f6f9f4cSArthur Eubanks // update them when they mutate the loop nest structure.
247d7a6f3a1STa-Wei Tu LPMUpdater Updater(Worklist, LAM, LoopNestMode);
2487f6f9f4cSArthur Eubanks
2497f6f9f4cSArthur Eubanks // Add the loop nests in the reverse order of LoopInfo. See method
2507f6f9f4cSArthur Eubanks // declaration.
251d7a6f3a1STa-Wei Tu if (!LoopNestMode) {
2527f6f9f4cSArthur Eubanks appendLoopsToWorklist(LI, Worklist);
253d7a6f3a1STa-Wei Tu } else {
254d7a6f3a1STa-Wei Tu for (Loop *L : LI)
255d7a6f3a1STa-Wei Tu Worklist.insert(L);
256d7a6f3a1STa-Wei Tu }
2577f6f9f4cSArthur Eubanks
2587f6f9f4cSArthur Eubanks #ifndef NDEBUG
2597f6f9f4cSArthur Eubanks PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) {
2607f6f9f4cSArthur Eubanks if (isSpecialPass(PassID, {"PassManager"}))
2617f6f9f4cSArthur Eubanks return;
262fa3693adSWhitney Tsang assert(any_isa<const Loop *>(IR) || any_isa<const LoopNest *>(IR));
263fa3693adSWhitney Tsang const Loop *L = any_isa<const Loop *>(IR)
264fa3693adSWhitney Tsang ? any_cast<const Loop *>(IR)
265fa3693adSWhitney Tsang : &any_cast<const LoopNest *>(IR)->getOutermostLoop();
2667f6f9f4cSArthur Eubanks assert(L && "Loop should be valid for printing");
2677f6f9f4cSArthur Eubanks
2687f6f9f4cSArthur Eubanks // Verify the loop structure and LCSSA form before visiting the loop.
2697f6f9f4cSArthur Eubanks L->verifyLoop();
2707f6f9f4cSArthur Eubanks assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) &&
2717f6f9f4cSArthur Eubanks "Loops must remain in LCSSA form!");
2727f6f9f4cSArthur Eubanks });
2737f6f9f4cSArthur Eubanks #endif
2747f6f9f4cSArthur Eubanks
2757f6f9f4cSArthur Eubanks do {
2767f6f9f4cSArthur Eubanks Loop *L = Worklist.pop_back_val();
277d7a6f3a1STa-Wei Tu assert(!(LoopNestMode && L->getParentLoop()) &&
278d7a6f3a1STa-Wei Tu "L should be a top-level loop in loop-nest mode.");
2797f6f9f4cSArthur Eubanks
2807f6f9f4cSArthur Eubanks // Reset the update structure for this loop.
2817f6f9f4cSArthur Eubanks Updater.CurrentL = L;
2827f6f9f4cSArthur Eubanks Updater.SkipCurrentLoop = false;
2837f6f9f4cSArthur Eubanks
2847f6f9f4cSArthur Eubanks #ifndef NDEBUG
2857f6f9f4cSArthur Eubanks // Save a parent loop pointer for asserts.
2867f6f9f4cSArthur Eubanks Updater.ParentL = L->getParentLoop();
2877f6f9f4cSArthur Eubanks #endif
2887f6f9f4cSArthur Eubanks // Check the PassInstrumentation's BeforePass callbacks before running the
2897f6f9f4cSArthur Eubanks // pass, skip its execution completely if asked to (callback returns
2907f6f9f4cSArthur Eubanks // false).
2917f6f9f4cSArthur Eubanks if (!PI.runBeforePass<Loop>(*Pass, *L))
2927f6f9f4cSArthur Eubanks continue;
2937f6f9f4cSArthur Eubanks
2947f6f9f4cSArthur Eubanks PreservedAnalyses PassPA;
2957f6f9f4cSArthur Eubanks {
2967f6f9f4cSArthur Eubanks TimeTraceScope TimeScope(Pass->name());
2977f6f9f4cSArthur Eubanks PassPA = Pass->run(*L, LAM, LAR, Updater);
2987f6f9f4cSArthur Eubanks }
2997f6f9f4cSArthur Eubanks
3007f6f9f4cSArthur Eubanks // Do not pass deleted Loop into the instrumentation.
3017f6f9f4cSArthur Eubanks if (Updater.skipCurrentLoop())
3027f6f9f4cSArthur Eubanks PI.runAfterPassInvalidated<Loop>(*Pass, PassPA);
3037f6f9f4cSArthur Eubanks else
3047f6f9f4cSArthur Eubanks PI.runAfterPass<Loop>(*Pass, *L, PassPA);
3057f6f9f4cSArthur Eubanks
3060afd10b4SNikita Popov if (LAR.MSSA && !PassPA.getChecker<MemorySSAAnalysis>().preserved())
3070afd10b4SNikita Popov report_fatal_error("Loop pass manager using MemorySSA contains a pass "
3080afd10b4SNikita Popov "that does not preserve MemorySSA");
3090afd10b4SNikita Popov
310a17394dcSArthur Eubanks #ifndef NDEBUG
311a17394dcSArthur Eubanks // LoopAnalysisResults should always be valid.
312a17394dcSArthur Eubanks if (VerifyDomInfo)
313a17394dcSArthur Eubanks LAR.DT.verify();
314a17394dcSArthur Eubanks if (VerifyLoopInfo)
315a17394dcSArthur Eubanks LAR.LI.verify(LAR.DT);
316*d1e880acSNikita Popov if (VerifySCEV)
317*d1e880acSNikita Popov LAR.SE.verify();
318a17394dcSArthur Eubanks if (LAR.MSSA && VerifyMemorySSA)
319a17394dcSArthur Eubanks LAR.MSSA->verifyMemorySSA();
320a17394dcSArthur Eubanks #endif
3217f6f9f4cSArthur Eubanks
3227f6f9f4cSArthur Eubanks // If the loop hasn't been deleted, we need to handle invalidation here.
3237f6f9f4cSArthur Eubanks if (!Updater.skipCurrentLoop())
3247f6f9f4cSArthur Eubanks // We know that the loop pass couldn't have invalidated any other
3257f6f9f4cSArthur Eubanks // loop's analyses (that's the contract of a loop pass), so directly
3267f6f9f4cSArthur Eubanks // handle the loop analysis manager's invalidation here.
3277f6f9f4cSArthur Eubanks LAM.invalidate(*L, PassPA);
3287f6f9f4cSArthur Eubanks
3297f6f9f4cSArthur Eubanks // Then intersect the preserved set so that invalidation of module
3307f6f9f4cSArthur Eubanks // analyses will eventually occur when the module pass completes.
3317f6f9f4cSArthur Eubanks PA.intersect(std::move(PassPA));
3327f6f9f4cSArthur Eubanks } while (!Worklist.empty());
3337f6f9f4cSArthur Eubanks
3347f6f9f4cSArthur Eubanks #ifndef NDEBUG
3357f6f9f4cSArthur Eubanks PI.popBeforeNonSkippedPassCallback();
3367f6f9f4cSArthur Eubanks #endif
3377f6f9f4cSArthur Eubanks
3387f6f9f4cSArthur Eubanks // By definition we preserve the proxy. We also preserve all analyses on
3397f6f9f4cSArthur Eubanks // Loops. This precludes *any* invalidation of loop analyses by the proxy,
3407f6f9f4cSArthur Eubanks // but that's OK because we've taken care to invalidate analyses in the
3417f6f9f4cSArthur Eubanks // loop analysis manager incrementally above.
3427f6f9f4cSArthur Eubanks PA.preserveSet<AllAnalysesOn<Loop>>();
3437f6f9f4cSArthur Eubanks PA.preserve<LoopAnalysisManagerFunctionProxy>();
3447f6f9f4cSArthur Eubanks // We also preserve the set of standard analyses.
3457f6f9f4cSArthur Eubanks PA.preserve<DominatorTreeAnalysis>();
3467f6f9f4cSArthur Eubanks PA.preserve<LoopAnalysis>();
3477f6f9f4cSArthur Eubanks PA.preserve<ScalarEvolutionAnalysis>();
3487f6f9f4cSArthur Eubanks if (UseBlockFrequencyInfo && F.hasProfileData())
3497f6f9f4cSArthur Eubanks PA.preserve<BlockFrequencyAnalysis>();
350452714f8SAnna Thomas if (UseBranchProbabilityInfo && F.hasProfileData())
351452714f8SAnna Thomas PA.preserve<BranchProbabilityAnalysis>();
3527f6f9f4cSArthur Eubanks if (UseMemorySSA)
3537f6f9f4cSArthur Eubanks PA.preserve<MemorySSAAnalysis>();
3547f6f9f4cSArthur Eubanks return PA;
3557f6f9f4cSArthur Eubanks }
3567f6f9f4cSArthur Eubanks
PrintLoopPass()3573bab7e1aSChandler Carruth PrintLoopPass::PrintLoopPass() : OS(dbgs()) {}
PrintLoopPass(raw_ostream & OS,const std::string & Banner)3583bab7e1aSChandler Carruth PrintLoopPass::PrintLoopPass(raw_ostream &OS, const std::string &Banner)
3593bab7e1aSChandler Carruth : OS(OS), Banner(Banner) {}
3603bab7e1aSChandler Carruth
run(Loop & L,LoopAnalysisManager &,LoopStandardAnalysisResults &,LPMUpdater &)3613bab7e1aSChandler Carruth PreservedAnalyses PrintLoopPass::run(Loop &L, LoopAnalysisManager &,
3623bab7e1aSChandler Carruth LoopStandardAnalysisResults &,
3633bab7e1aSChandler Carruth LPMUpdater &) {
3643bab7e1aSChandler Carruth printLoop(L, OS, Banner);
3653bab7e1aSChandler Carruth return PreservedAnalyses::all();
3663bab7e1aSChandler Carruth }
367