10b57cec5SDimitry Andric //===- LoopPassManager.cpp - Loop pass management -------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/LoopPassManager.h" 10e8d8bef9SDimitry Andric #include "llvm/Analysis/AssumptionCache.h" 11e8d8bef9SDimitry Andric #include "llvm/Analysis/BlockFrequencyInfo.h" 12349cc55cSDimitry Andric #include "llvm/Analysis/BranchProbabilityInfo.h" 13e8d8bef9SDimitry Andric #include "llvm/Analysis/MemorySSA.h" 1481ad6265SDimitry Andric #include "llvm/Analysis/ScalarEvolution.h" 15e8d8bef9SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h" 1681ad6265SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h" 17e8d8bef9SDimitry Andric #include "llvm/Support/TimeProfiler.h" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric using namespace llvm; 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric /// Explicitly specialize the pass manager's run method to handle loop nest 240b57cec5SDimitry Andric /// structure updates. 250b57cec5SDimitry Andric PreservedAnalyses 260b57cec5SDimitry Andric PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, 270b57cec5SDimitry Andric LPMUpdater &>::run(Loop &L, LoopAnalysisManager &AM, 280b57cec5SDimitry Andric LoopStandardAnalysisResults &AR, LPMUpdater &U) { 29e8d8bef9SDimitry Andric // Runs loop-nest passes only when the current loop is a top-level one. 30e8d8bef9SDimitry Andric PreservedAnalyses PA = (L.isOutermost() && !LoopNestPasses.empty()) 31e8d8bef9SDimitry Andric ? runWithLoopNestPasses(L, AM, AR, U) 32e8d8bef9SDimitry Andric : runWithoutLoopNestPasses(L, AM, AR, U); 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric // Invalidation for the current loop should be handled above, and other loop 350b57cec5SDimitry Andric // analysis results shouldn't be impacted by runs over this loop. Therefore, 360b57cec5SDimitry Andric // the remaining analysis results in the AnalysisManager are preserved. We 370b57cec5SDimitry Andric // mark this with a set so that we don't need to inspect each one 380b57cec5SDimitry Andric // individually. 390b57cec5SDimitry Andric // FIXME: This isn't correct! This loop and all nested loops' analyses should 400b57cec5SDimitry Andric // be preserved, but unrolling should invalidate the parent loop's analyses. 410b57cec5SDimitry Andric PA.preserveSet<AllAnalysesOn<Loop>>(); 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric return PA; 440b57cec5SDimitry Andric } 45e8d8bef9SDimitry Andric 46349cc55cSDimitry Andric void PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, 47349cc55cSDimitry Andric LPMUpdater &>::printPipeline(raw_ostream &OS, 48349cc55cSDimitry Andric function_ref<StringRef(StringRef)> 49349cc55cSDimitry Andric MapClassName2PassName) { 504824e7fdSDimitry Andric assert(LoopPasses.size() + LoopNestPasses.size() == IsLoopNestPass.size()); 514824e7fdSDimitry Andric 524824e7fdSDimitry Andric unsigned IdxLP = 0, IdxLNP = 0; 534824e7fdSDimitry Andric for (unsigned Idx = 0, Size = IsLoopNestPass.size(); Idx != Size; ++Idx) { 544824e7fdSDimitry Andric if (IsLoopNestPass[Idx]) { 554824e7fdSDimitry Andric auto *P = LoopNestPasses[IdxLNP++].get(); 56349cc55cSDimitry Andric P->printPipeline(OS, MapClassName2PassName); 574824e7fdSDimitry Andric } else { 584824e7fdSDimitry Andric auto *P = LoopPasses[IdxLP++].get(); 594824e7fdSDimitry Andric P->printPipeline(OS, MapClassName2PassName); 604824e7fdSDimitry Andric } 61349cc55cSDimitry Andric if (Idx + 1 < Size) 6206c3fb27SDimitry Andric OS << ','; 63349cc55cSDimitry Andric } 64349cc55cSDimitry Andric } 65349cc55cSDimitry Andric 66e8d8bef9SDimitry Andric // Run both loop passes and loop-nest passes on top-level loop \p L. 67e8d8bef9SDimitry Andric PreservedAnalyses 68e8d8bef9SDimitry Andric LoopPassManager::runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM, 69e8d8bef9SDimitry Andric LoopStandardAnalysisResults &AR, 70e8d8bef9SDimitry Andric LPMUpdater &U) { 71e8d8bef9SDimitry Andric assert(L.isOutermost() && 72e8d8bef9SDimitry Andric "Loop-nest passes should only run on top-level loops."); 73e8d8bef9SDimitry Andric PreservedAnalyses PA = PreservedAnalyses::all(); 74e8d8bef9SDimitry Andric 75e8d8bef9SDimitry Andric // Request PassInstrumentation from analysis manager, will use it to run 76e8d8bef9SDimitry Andric // instrumenting callbacks for the passes later. 77e8d8bef9SDimitry Andric PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR); 78e8d8bef9SDimitry Andric 79e8d8bef9SDimitry Andric unsigned LoopPassIndex = 0, LoopNestPassIndex = 0; 80e8d8bef9SDimitry Andric 81e8d8bef9SDimitry Andric // `LoopNestPtr` points to the `LoopNest` object for the current top-level 82e8d8bef9SDimitry Andric // loop and `IsLoopNestPtrValid` indicates whether the pointer is still valid. 83e8d8bef9SDimitry Andric // The `LoopNest` object will have to be re-constructed if the pointer is 84e8d8bef9SDimitry Andric // invalid when encountering a loop-nest pass. 85e8d8bef9SDimitry Andric std::unique_ptr<LoopNest> LoopNestPtr; 86e8d8bef9SDimitry Andric bool IsLoopNestPtrValid = false; 87bdd1243dSDimitry Andric Loop *OuterMostLoop = &L; 88e8d8bef9SDimitry Andric 89e8d8bef9SDimitry Andric for (size_t I = 0, E = IsLoopNestPass.size(); I != E; ++I) { 90bdd1243dSDimitry Andric std::optional<PreservedAnalyses> PassPA; 91e8d8bef9SDimitry Andric if (!IsLoopNestPass[I]) { 92e8d8bef9SDimitry Andric // The `I`-th pass is a loop pass. 93e8d8bef9SDimitry Andric auto &Pass = LoopPasses[LoopPassIndex++]; 94e8d8bef9SDimitry Andric PassPA = runSinglePass(L, Pass, AM, AR, U, PI); 95e8d8bef9SDimitry Andric } else { 96e8d8bef9SDimitry Andric // The `I`-th pass is a loop-nest pass. 97e8d8bef9SDimitry Andric auto &Pass = LoopNestPasses[LoopNestPassIndex++]; 98e8d8bef9SDimitry Andric 99e8d8bef9SDimitry Andric // If the loop-nest object calculated before is no longer valid, 100e8d8bef9SDimitry Andric // re-calculate it here before running the loop-nest pass. 101bdd1243dSDimitry Andric // 102bdd1243dSDimitry Andric // FIXME: PreservedAnalysis should not be abused to tell if the 103bdd1243dSDimitry Andric // status of loopnest has been changed. We should use and only 104bdd1243dSDimitry Andric // use LPMUpdater for this purpose. 105bdd1243dSDimitry Andric if (!IsLoopNestPtrValid || U.isLoopNestChanged()) { 106bdd1243dSDimitry Andric while (auto *ParentLoop = OuterMostLoop->getParentLoop()) 107bdd1243dSDimitry Andric OuterMostLoop = ParentLoop; 108bdd1243dSDimitry Andric LoopNestPtr = LoopNest::getLoopNest(*OuterMostLoop, AR.SE); 109e8d8bef9SDimitry Andric IsLoopNestPtrValid = true; 110bdd1243dSDimitry Andric U.markLoopNestChanged(false); 111e8d8bef9SDimitry Andric } 112bdd1243dSDimitry Andric 113e8d8bef9SDimitry Andric PassPA = runSinglePass(*LoopNestPtr, Pass, AM, AR, U, PI); 114e8d8bef9SDimitry Andric } 115e8d8bef9SDimitry Andric 116e8d8bef9SDimitry Andric // `PassPA` is `None` means that the before-pass callbacks in 117e8d8bef9SDimitry Andric // `PassInstrumentation` return false. The pass does not run in this case, 118e8d8bef9SDimitry Andric // so we can skip the following procedure. 119e8d8bef9SDimitry Andric if (!PassPA) 120e8d8bef9SDimitry Andric continue; 121e8d8bef9SDimitry Andric 122e8d8bef9SDimitry Andric // If the loop was deleted, abort the run and return to the outer walk. 123e8d8bef9SDimitry Andric if (U.skipCurrentLoop()) { 124e8d8bef9SDimitry Andric PA.intersect(std::move(*PassPA)); 125e8d8bef9SDimitry Andric break; 126e8d8bef9SDimitry Andric } 127e8d8bef9SDimitry Andric 128e8d8bef9SDimitry Andric // Update the analysis manager as each pass runs and potentially 129e8d8bef9SDimitry Andric // invalidates analyses. 130bdd1243dSDimitry Andric AM.invalidate(IsLoopNestPass[I] ? *OuterMostLoop : L, *PassPA); 131e8d8bef9SDimitry Andric 132e8d8bef9SDimitry Andric // Finally, we intersect the final preserved analyses to compute the 133e8d8bef9SDimitry Andric // aggregate preserved set for this pass manager. 134e8d8bef9SDimitry Andric PA.intersect(std::move(*PassPA)); 135e8d8bef9SDimitry Andric 136e8d8bef9SDimitry Andric // Check if the current pass preserved the loop-nest object or not. 137e8d8bef9SDimitry Andric IsLoopNestPtrValid &= PassPA->getChecker<LoopNestAnalysis>().preserved(); 138e8d8bef9SDimitry Andric 139fe6060f1SDimitry Andric // After running the loop pass, the parent loop might change and we need to 140fe6060f1SDimitry Andric // notify the updater, otherwise U.ParentL might gets outdated and triggers 141fe6060f1SDimitry Andric // assertion failures in addSiblingLoops and addChildLoops. 142bdd1243dSDimitry Andric U.setParentLoop((IsLoopNestPass[I] ? *OuterMostLoop : L).getParentLoop()); 143e8d8bef9SDimitry Andric } 144e8d8bef9SDimitry Andric return PA; 145e8d8bef9SDimitry Andric } 146e8d8bef9SDimitry Andric 147e8d8bef9SDimitry Andric // Run all loop passes on loop \p L. Loop-nest passes don't run either because 148e8d8bef9SDimitry Andric // \p L is not a top-level one or simply because there are no loop-nest passes 149e8d8bef9SDimitry Andric // in the pass manager at all. 150e8d8bef9SDimitry Andric PreservedAnalyses 151e8d8bef9SDimitry Andric LoopPassManager::runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM, 152e8d8bef9SDimitry Andric LoopStandardAnalysisResults &AR, 153e8d8bef9SDimitry Andric LPMUpdater &U) { 154e8d8bef9SDimitry Andric PreservedAnalyses PA = PreservedAnalyses::all(); 155e8d8bef9SDimitry Andric 156e8d8bef9SDimitry Andric // Request PassInstrumentation from analysis manager, will use it to run 157e8d8bef9SDimitry Andric // instrumenting callbacks for the passes later. 158e8d8bef9SDimitry Andric PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR); 159e8d8bef9SDimitry Andric for (auto &Pass : LoopPasses) { 160bdd1243dSDimitry Andric std::optional<PreservedAnalyses> PassPA = 161bdd1243dSDimitry Andric runSinglePass(L, Pass, AM, AR, U, PI); 162e8d8bef9SDimitry Andric 163e8d8bef9SDimitry Andric // `PassPA` is `None` means that the before-pass callbacks in 164e8d8bef9SDimitry Andric // `PassInstrumentation` return false. The pass does not run in this case, 165e8d8bef9SDimitry Andric // so we can skip the following procedure. 166e8d8bef9SDimitry Andric if (!PassPA) 167e8d8bef9SDimitry Andric continue; 168e8d8bef9SDimitry Andric 169e8d8bef9SDimitry Andric // If the loop was deleted, abort the run and return to the outer walk. 170e8d8bef9SDimitry Andric if (U.skipCurrentLoop()) { 171e8d8bef9SDimitry Andric PA.intersect(std::move(*PassPA)); 172e8d8bef9SDimitry Andric break; 173e8d8bef9SDimitry Andric } 174e8d8bef9SDimitry Andric 175e8d8bef9SDimitry Andric // Update the analysis manager as each pass runs and potentially 176e8d8bef9SDimitry Andric // invalidates analyses. 177e8d8bef9SDimitry Andric AM.invalidate(L, *PassPA); 178e8d8bef9SDimitry Andric 179e8d8bef9SDimitry Andric // Finally, we intersect the final preserved analyses to compute the 180e8d8bef9SDimitry Andric // aggregate preserved set for this pass manager. 181e8d8bef9SDimitry Andric PA.intersect(std::move(*PassPA)); 182e8d8bef9SDimitry Andric 183fe6060f1SDimitry Andric // After running the loop pass, the parent loop might change and we need to 184fe6060f1SDimitry Andric // notify the updater, otherwise U.ParentL might gets outdated and triggers 185fe6060f1SDimitry Andric // assertion failures in addSiblingLoops and addChildLoops. 186fe6060f1SDimitry Andric U.setParentLoop(L.getParentLoop()); 187e8d8bef9SDimitry Andric } 188e8d8bef9SDimitry Andric return PA; 189e8d8bef9SDimitry Andric } 190e8d8bef9SDimitry Andric } // namespace llvm 191e8d8bef9SDimitry Andric 192349cc55cSDimitry Andric void FunctionToLoopPassAdaptor::printPipeline( 193349cc55cSDimitry Andric raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) { 194349cc55cSDimitry Andric OS << (UseMemorySSA ? "loop-mssa(" : "loop("); 195349cc55cSDimitry Andric Pass->printPipeline(OS, MapClassName2PassName); 19606c3fb27SDimitry Andric OS << ')'; 197349cc55cSDimitry Andric } 198e8d8bef9SDimitry Andric PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F, 199e8d8bef9SDimitry Andric FunctionAnalysisManager &AM) { 200e8d8bef9SDimitry Andric // Before we even compute any loop analyses, first run a miniature function 201e8d8bef9SDimitry Andric // pass pipeline to put loops into their canonical form. Note that we can 202e8d8bef9SDimitry Andric // directly build up function analyses after this as the function pass 203e8d8bef9SDimitry Andric // manager handles all the invalidation at that layer. 204e8d8bef9SDimitry Andric PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(F); 205e8d8bef9SDimitry Andric 206e8d8bef9SDimitry Andric PreservedAnalyses PA = PreservedAnalyses::all(); 207e8d8bef9SDimitry Andric // Check the PassInstrumentation's BeforePass callbacks before running the 208e8d8bef9SDimitry Andric // canonicalization pipeline. 209e8d8bef9SDimitry Andric if (PI.runBeforePass<Function>(LoopCanonicalizationFPM, F)) { 210e8d8bef9SDimitry Andric PA = LoopCanonicalizationFPM.run(F, AM); 211e8d8bef9SDimitry Andric PI.runAfterPass<Function>(LoopCanonicalizationFPM, F, PA); 212e8d8bef9SDimitry Andric } 213e8d8bef9SDimitry Andric 214e8d8bef9SDimitry Andric // Get the loop structure for this function 215e8d8bef9SDimitry Andric LoopInfo &LI = AM.getResult<LoopAnalysis>(F); 216e8d8bef9SDimitry Andric 217e8d8bef9SDimitry Andric // If there are no loops, there is nothing to do here. 218e8d8bef9SDimitry Andric if (LI.empty()) 219e8d8bef9SDimitry Andric return PA; 220e8d8bef9SDimitry Andric 221e8d8bef9SDimitry Andric // Get the analysis results needed by loop passes. 222e8d8bef9SDimitry Andric MemorySSA *MSSA = 223e8d8bef9SDimitry Andric UseMemorySSA ? (&AM.getResult<MemorySSAAnalysis>(F).getMSSA()) : nullptr; 224e8d8bef9SDimitry Andric BlockFrequencyInfo *BFI = UseBlockFrequencyInfo && F.hasProfileData() 225e8d8bef9SDimitry Andric ? (&AM.getResult<BlockFrequencyAnalysis>(F)) 226e8d8bef9SDimitry Andric : nullptr; 227349cc55cSDimitry Andric BranchProbabilityInfo *BPI = 228349cc55cSDimitry Andric UseBranchProbabilityInfo && F.hasProfileData() 229349cc55cSDimitry Andric ? (&AM.getResult<BranchProbabilityAnalysis>(F)) 230349cc55cSDimitry Andric : nullptr; 231e8d8bef9SDimitry Andric LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F), 232e8d8bef9SDimitry Andric AM.getResult<AssumptionAnalysis>(F), 233e8d8bef9SDimitry Andric AM.getResult<DominatorTreeAnalysis>(F), 234e8d8bef9SDimitry Andric AM.getResult<LoopAnalysis>(F), 235e8d8bef9SDimitry Andric AM.getResult<ScalarEvolutionAnalysis>(F), 236e8d8bef9SDimitry Andric AM.getResult<TargetLibraryAnalysis>(F), 237e8d8bef9SDimitry Andric AM.getResult<TargetIRAnalysis>(F), 238e8d8bef9SDimitry Andric BFI, 239349cc55cSDimitry Andric BPI, 240e8d8bef9SDimitry Andric MSSA}; 241e8d8bef9SDimitry Andric 242e8d8bef9SDimitry Andric // Setup the loop analysis manager from its proxy. It is important that 243e8d8bef9SDimitry Andric // this is only done when there are loops to process and we have built the 244e8d8bef9SDimitry Andric // LoopStandardAnalysisResults object. The loop analyses cached in this 245e8d8bef9SDimitry Andric // manager have access to those analysis results and so it must invalidate 246e8d8bef9SDimitry Andric // itself when they go away. 247e8d8bef9SDimitry Andric auto &LAMFP = AM.getResult<LoopAnalysisManagerFunctionProxy>(F); 248e8d8bef9SDimitry Andric if (UseMemorySSA) 249e8d8bef9SDimitry Andric LAMFP.markMSSAUsed(); 250e8d8bef9SDimitry Andric LoopAnalysisManager &LAM = LAMFP.getManager(); 251e8d8bef9SDimitry Andric 252e8d8bef9SDimitry Andric // A postorder worklist of loops to process. 253e8d8bef9SDimitry Andric SmallPriorityWorklist<Loop *, 4> Worklist; 254e8d8bef9SDimitry Andric 255e8d8bef9SDimitry Andric // Register the worklist and loop analysis manager so that loop passes can 256e8d8bef9SDimitry Andric // update them when they mutate the loop nest structure. 257e8d8bef9SDimitry Andric LPMUpdater Updater(Worklist, LAM, LoopNestMode); 258e8d8bef9SDimitry Andric 259e8d8bef9SDimitry Andric // Add the loop nests in the reverse order of LoopInfo. See method 260e8d8bef9SDimitry Andric // declaration. 261e8d8bef9SDimitry Andric if (!LoopNestMode) { 262e8d8bef9SDimitry Andric appendLoopsToWorklist(LI, Worklist); 263e8d8bef9SDimitry Andric } else { 264e8d8bef9SDimitry Andric for (Loop *L : LI) 265e8d8bef9SDimitry Andric Worklist.insert(L); 266e8d8bef9SDimitry Andric } 267e8d8bef9SDimitry Andric 268e8d8bef9SDimitry Andric #ifndef NDEBUG 269e8d8bef9SDimitry Andric PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) { 270e8d8bef9SDimitry Andric if (isSpecialPass(PassID, {"PassManager"})) 271e8d8bef9SDimitry Andric return; 272*5f757f3fSDimitry Andric assert(llvm::any_cast<const Loop *>(&IR) || 273*5f757f3fSDimitry Andric llvm::any_cast<const LoopNest *>(&IR)); 274*5f757f3fSDimitry Andric const Loop **LPtr = llvm::any_cast<const Loop *>(&IR); 275bdd1243dSDimitry Andric const Loop *L = LPtr ? *LPtr : nullptr; 276bdd1243dSDimitry Andric if (!L) 277*5f757f3fSDimitry Andric L = &llvm::any_cast<const LoopNest *>(IR)->getOutermostLoop(); 278e8d8bef9SDimitry Andric assert(L && "Loop should be valid for printing"); 279e8d8bef9SDimitry Andric 280e8d8bef9SDimitry Andric // Verify the loop structure and LCSSA form before visiting the loop. 281e8d8bef9SDimitry Andric L->verifyLoop(); 282e8d8bef9SDimitry Andric assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) && 283e8d8bef9SDimitry Andric "Loops must remain in LCSSA form!"); 284e8d8bef9SDimitry Andric }); 285e8d8bef9SDimitry Andric #endif 286e8d8bef9SDimitry Andric 287e8d8bef9SDimitry Andric do { 288e8d8bef9SDimitry Andric Loop *L = Worklist.pop_back_val(); 289e8d8bef9SDimitry Andric assert(!(LoopNestMode && L->getParentLoop()) && 290e8d8bef9SDimitry Andric "L should be a top-level loop in loop-nest mode."); 291e8d8bef9SDimitry Andric 292e8d8bef9SDimitry Andric // Reset the update structure for this loop. 293e8d8bef9SDimitry Andric Updater.CurrentL = L; 294e8d8bef9SDimitry Andric Updater.SkipCurrentLoop = false; 295e8d8bef9SDimitry Andric 296e8d8bef9SDimitry Andric #ifndef NDEBUG 297e8d8bef9SDimitry Andric // Save a parent loop pointer for asserts. 298e8d8bef9SDimitry Andric Updater.ParentL = L->getParentLoop(); 299e8d8bef9SDimitry Andric #endif 300e8d8bef9SDimitry Andric // Check the PassInstrumentation's BeforePass callbacks before running the 301e8d8bef9SDimitry Andric // pass, skip its execution completely if asked to (callback returns 302e8d8bef9SDimitry Andric // false). 303e8d8bef9SDimitry Andric if (!PI.runBeforePass<Loop>(*Pass, *L)) 304e8d8bef9SDimitry Andric continue; 305e8d8bef9SDimitry Andric 306bdd1243dSDimitry Andric PreservedAnalyses PassPA = Pass->run(*L, LAM, LAR, Updater); 307e8d8bef9SDimitry Andric 308e8d8bef9SDimitry Andric // Do not pass deleted Loop into the instrumentation. 309e8d8bef9SDimitry Andric if (Updater.skipCurrentLoop()) 310e8d8bef9SDimitry Andric PI.runAfterPassInvalidated<Loop>(*Pass, PassPA); 311e8d8bef9SDimitry Andric else 312e8d8bef9SDimitry Andric PI.runAfterPass<Loop>(*Pass, *L, PassPA); 313e8d8bef9SDimitry Andric 314349cc55cSDimitry Andric if (LAR.MSSA && !PassPA.getChecker<MemorySSAAnalysis>().preserved()) 315349cc55cSDimitry Andric report_fatal_error("Loop pass manager using MemorySSA contains a pass " 316*5f757f3fSDimitry Andric "that does not preserve MemorySSA", 317*5f757f3fSDimitry Andric /*gen_crash_diag*/ false); 318349cc55cSDimitry Andric 319fe6060f1SDimitry Andric #ifndef NDEBUG 320fe6060f1SDimitry Andric // LoopAnalysisResults should always be valid. 321fe6060f1SDimitry Andric if (VerifyDomInfo) 322fe6060f1SDimitry Andric LAR.DT.verify(); 323fe6060f1SDimitry Andric if (VerifyLoopInfo) 324fe6060f1SDimitry Andric LAR.LI.verify(LAR.DT); 32581ad6265SDimitry Andric if (VerifySCEV) 32681ad6265SDimitry Andric LAR.SE.verify(); 327fe6060f1SDimitry Andric if (LAR.MSSA && VerifyMemorySSA) 328fe6060f1SDimitry Andric LAR.MSSA->verifyMemorySSA(); 329fe6060f1SDimitry Andric #endif 330e8d8bef9SDimitry Andric 331e8d8bef9SDimitry Andric // If the loop hasn't been deleted, we need to handle invalidation here. 332e8d8bef9SDimitry Andric if (!Updater.skipCurrentLoop()) 333e8d8bef9SDimitry Andric // We know that the loop pass couldn't have invalidated any other 334e8d8bef9SDimitry Andric // loop's analyses (that's the contract of a loop pass), so directly 335e8d8bef9SDimitry Andric // handle the loop analysis manager's invalidation here. 336e8d8bef9SDimitry Andric LAM.invalidate(*L, PassPA); 337e8d8bef9SDimitry Andric 338e8d8bef9SDimitry Andric // Then intersect the preserved set so that invalidation of module 339e8d8bef9SDimitry Andric // analyses will eventually occur when the module pass completes. 340e8d8bef9SDimitry Andric PA.intersect(std::move(PassPA)); 341e8d8bef9SDimitry Andric } while (!Worklist.empty()); 342e8d8bef9SDimitry Andric 343e8d8bef9SDimitry Andric #ifndef NDEBUG 344e8d8bef9SDimitry Andric PI.popBeforeNonSkippedPassCallback(); 345e8d8bef9SDimitry Andric #endif 346e8d8bef9SDimitry Andric 347e8d8bef9SDimitry Andric // By definition we preserve the proxy. We also preserve all analyses on 348e8d8bef9SDimitry Andric // Loops. This precludes *any* invalidation of loop analyses by the proxy, 349e8d8bef9SDimitry Andric // but that's OK because we've taken care to invalidate analyses in the 350e8d8bef9SDimitry Andric // loop analysis manager incrementally above. 351e8d8bef9SDimitry Andric PA.preserveSet<AllAnalysesOn<Loop>>(); 352e8d8bef9SDimitry Andric PA.preserve<LoopAnalysisManagerFunctionProxy>(); 353e8d8bef9SDimitry Andric // We also preserve the set of standard analyses. 354e8d8bef9SDimitry Andric PA.preserve<DominatorTreeAnalysis>(); 355e8d8bef9SDimitry Andric PA.preserve<LoopAnalysis>(); 356e8d8bef9SDimitry Andric PA.preserve<ScalarEvolutionAnalysis>(); 357e8d8bef9SDimitry Andric if (UseBlockFrequencyInfo && F.hasProfileData()) 358e8d8bef9SDimitry Andric PA.preserve<BlockFrequencyAnalysis>(); 359349cc55cSDimitry Andric if (UseBranchProbabilityInfo && F.hasProfileData()) 360349cc55cSDimitry Andric PA.preserve<BranchProbabilityAnalysis>(); 361e8d8bef9SDimitry Andric if (UseMemorySSA) 362e8d8bef9SDimitry Andric PA.preserve<MemorySSAAnalysis>(); 363e8d8bef9SDimitry Andric return PA; 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric PrintLoopPass::PrintLoopPass() : OS(dbgs()) {} 3670b57cec5SDimitry Andric PrintLoopPass::PrintLoopPass(raw_ostream &OS, const std::string &Banner) 3680b57cec5SDimitry Andric : OS(OS), Banner(Banner) {} 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric PreservedAnalyses PrintLoopPass::run(Loop &L, LoopAnalysisManager &, 3710b57cec5SDimitry Andric LoopStandardAnalysisResults &, 3720b57cec5SDimitry Andric LPMUpdater &) { 3730b57cec5SDimitry Andric printLoop(L, OS, Banner); 3740b57cec5SDimitry Andric return PreservedAnalyses::all(); 3750b57cec5SDimitry Andric } 376