Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
35266 views
//===- LoopPassManager.cpp - Loop pass management -------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/Transforms/Scalar/LoopPassManager.h"9#include "llvm/Analysis/AssumptionCache.h"10#include "llvm/Analysis/BlockFrequencyInfo.h"11#include "llvm/Analysis/BranchProbabilityInfo.h"12#include "llvm/Analysis/MemorySSA.h"13#include "llvm/Analysis/ScalarEvolution.h"14#include "llvm/Analysis/TargetLibraryInfo.h"15#include "llvm/Analysis/TargetTransformInfo.h"16#include "llvm/Support/TimeProfiler.h"1718using namespace llvm;1920namespace llvm {2122/// Explicitly specialize the pass manager's run method to handle loop nest23/// structure updates.24PreservedAnalyses25PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,26LPMUpdater &>::run(Loop &L, LoopAnalysisManager &AM,27LoopStandardAnalysisResults &AR, LPMUpdater &U) {28// Runs loop-nest passes only when the current loop is a top-level one.29PreservedAnalyses PA = (L.isOutermost() && !LoopNestPasses.empty())30? runWithLoopNestPasses(L, AM, AR, U)31: runWithoutLoopNestPasses(L, AM, AR, U);3233// Invalidation for the current loop should be handled above, and other loop34// analysis results shouldn't be impacted by runs over this loop. Therefore,35// the remaining analysis results in the AnalysisManager are preserved. We36// mark this with a set so that we don't need to inspect each one37// individually.38// FIXME: This isn't correct! This loop and all nested loops' analyses should39// be preserved, but unrolling should invalidate the parent loop's analyses.40PA.preserveSet<AllAnalysesOn<Loop>>();4142return PA;43}4445void PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,46LPMUpdater &>::printPipeline(raw_ostream &OS,47function_ref<StringRef(StringRef)>48MapClassName2PassName) {49assert(LoopPasses.size() + LoopNestPasses.size() == IsLoopNestPass.size());5051unsigned IdxLP = 0, IdxLNP = 0;52for (unsigned Idx = 0, Size = IsLoopNestPass.size(); Idx != Size; ++Idx) {53if (IsLoopNestPass[Idx]) {54auto *P = LoopNestPasses[IdxLNP++].get();55P->printPipeline(OS, MapClassName2PassName);56} else {57auto *P = LoopPasses[IdxLP++].get();58P->printPipeline(OS, MapClassName2PassName);59}60if (Idx + 1 < Size)61OS << ',';62}63}6465// Run both loop passes and loop-nest passes on top-level loop \p L.66PreservedAnalyses67LoopPassManager::runWithLoopNestPasses(Loop &L, LoopAnalysisManager &AM,68LoopStandardAnalysisResults &AR,69LPMUpdater &U) {70assert(L.isOutermost() &&71"Loop-nest passes should only run on top-level loops.");72PreservedAnalyses PA = PreservedAnalyses::all();7374// Request PassInstrumentation from analysis manager, will use it to run75// instrumenting callbacks for the passes later.76PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);7778unsigned LoopPassIndex = 0, LoopNestPassIndex = 0;7980// `LoopNestPtr` points to the `LoopNest` object for the current top-level81// loop and `IsLoopNestPtrValid` indicates whether the pointer is still valid.82// The `LoopNest` object will have to be re-constructed if the pointer is83// invalid when encountering a loop-nest pass.84std::unique_ptr<LoopNest> LoopNestPtr;85bool IsLoopNestPtrValid = false;86Loop *OuterMostLoop = &L;8788for (size_t I = 0, E = IsLoopNestPass.size(); I != E; ++I) {89std::optional<PreservedAnalyses> PassPA;90if (!IsLoopNestPass[I]) {91// The `I`-th pass is a loop pass.92auto &Pass = LoopPasses[LoopPassIndex++];93PassPA = runSinglePass(L, Pass, AM, AR, U, PI);94} else {95// The `I`-th pass is a loop-nest pass.96auto &Pass = LoopNestPasses[LoopNestPassIndex++];9798// If the loop-nest object calculated before is no longer valid,99// re-calculate it here before running the loop-nest pass.100//101// FIXME: PreservedAnalysis should not be abused to tell if the102// status of loopnest has been changed. We should use and only103// use LPMUpdater for this purpose.104if (!IsLoopNestPtrValid || U.isLoopNestChanged()) {105while (auto *ParentLoop = OuterMostLoop->getParentLoop())106OuterMostLoop = ParentLoop;107LoopNestPtr = LoopNest::getLoopNest(*OuterMostLoop, AR.SE);108IsLoopNestPtrValid = true;109U.markLoopNestChanged(false);110}111112PassPA = runSinglePass(*LoopNestPtr, Pass, AM, AR, U, PI);113}114115// `PassPA` is `None` means that the before-pass callbacks in116// `PassInstrumentation` return false. The pass does not run in this case,117// so we can skip the following procedure.118if (!PassPA)119continue;120121// If the loop was deleted, abort the run and return to the outer walk.122if (U.skipCurrentLoop()) {123PA.intersect(std::move(*PassPA));124break;125}126127// Update the analysis manager as each pass runs and potentially128// invalidates analyses.129AM.invalidate(IsLoopNestPass[I] ? *OuterMostLoop : L, *PassPA);130131// Finally, we intersect the final preserved analyses to compute the132// aggregate preserved set for this pass manager.133PA.intersect(std::move(*PassPA));134135// Check if the current pass preserved the loop-nest object or not.136IsLoopNestPtrValid &= PassPA->getChecker<LoopNestAnalysis>().preserved();137138// After running the loop pass, the parent loop might change and we need to139// notify the updater, otherwise U.ParentL might gets outdated and triggers140// assertion failures in addSiblingLoops and addChildLoops.141U.setParentLoop((IsLoopNestPass[I] ? *OuterMostLoop : L).getParentLoop());142}143return PA;144}145146// Run all loop passes on loop \p L. Loop-nest passes don't run either because147// \p L is not a top-level one or simply because there are no loop-nest passes148// in the pass manager at all.149PreservedAnalyses150LoopPassManager::runWithoutLoopNestPasses(Loop &L, LoopAnalysisManager &AM,151LoopStandardAnalysisResults &AR,152LPMUpdater &U) {153PreservedAnalyses PA = PreservedAnalyses::all();154155// Request PassInstrumentation from analysis manager, will use it to run156// instrumenting callbacks for the passes later.157PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);158for (auto &Pass : LoopPasses) {159std::optional<PreservedAnalyses> PassPA =160runSinglePass(L, Pass, AM, AR, U, PI);161162// `PassPA` is `None` means that the before-pass callbacks in163// `PassInstrumentation` return false. The pass does not run in this case,164// so we can skip the following procedure.165if (!PassPA)166continue;167168// If the loop was deleted, abort the run and return to the outer walk.169if (U.skipCurrentLoop()) {170PA.intersect(std::move(*PassPA));171break;172}173174// Update the analysis manager as each pass runs and potentially175// invalidates analyses.176AM.invalidate(L, *PassPA);177178// Finally, we intersect the final preserved analyses to compute the179// aggregate preserved set for this pass manager.180PA.intersect(std::move(*PassPA));181182// After running the loop pass, the parent loop might change and we need to183// notify the updater, otherwise U.ParentL might gets outdated and triggers184// assertion failures in addSiblingLoops and addChildLoops.185U.setParentLoop(L.getParentLoop());186}187return PA;188}189} // namespace llvm190191void FunctionToLoopPassAdaptor::printPipeline(192raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {193OS << (UseMemorySSA ? "loop-mssa(" : "loop(");194Pass->printPipeline(OS, MapClassName2PassName);195OS << ')';196}197PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,198FunctionAnalysisManager &AM) {199// Before we even compute any loop analyses, first run a miniature function200// pass pipeline to put loops into their canonical form. Note that we can201// directly build up function analyses after this as the function pass202// manager handles all the invalidation at that layer.203PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(F);204205PreservedAnalyses PA = PreservedAnalyses::all();206// Check the PassInstrumentation's BeforePass callbacks before running the207// canonicalization pipeline.208if (PI.runBeforePass<Function>(LoopCanonicalizationFPM, F)) {209PA = LoopCanonicalizationFPM.run(F, AM);210PI.runAfterPass<Function>(LoopCanonicalizationFPM, F, PA);211}212213// Get the loop structure for this function214LoopInfo &LI = AM.getResult<LoopAnalysis>(F);215216// If there are no loops, there is nothing to do here.217if (LI.empty())218return PA;219220// Get the analysis results needed by loop passes.221MemorySSA *MSSA =222UseMemorySSA ? (&AM.getResult<MemorySSAAnalysis>(F).getMSSA()) : nullptr;223BlockFrequencyInfo *BFI = UseBlockFrequencyInfo && F.hasProfileData()224? (&AM.getResult<BlockFrequencyAnalysis>(F))225: nullptr;226BranchProbabilityInfo *BPI =227UseBranchProbabilityInfo && F.hasProfileData()228? (&AM.getResult<BranchProbabilityAnalysis>(F))229: nullptr;230LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),231AM.getResult<AssumptionAnalysis>(F),232AM.getResult<DominatorTreeAnalysis>(F),233AM.getResult<LoopAnalysis>(F),234AM.getResult<ScalarEvolutionAnalysis>(F),235AM.getResult<TargetLibraryAnalysis>(F),236AM.getResult<TargetIRAnalysis>(F),237BFI,238BPI,239MSSA};240241// Setup the loop analysis manager from its proxy. It is important that242// this is only done when there are loops to process and we have built the243// LoopStandardAnalysisResults object. The loop analyses cached in this244// manager have access to those analysis results and so it must invalidate245// itself when they go away.246auto &LAMFP = AM.getResult<LoopAnalysisManagerFunctionProxy>(F);247if (UseMemorySSA)248LAMFP.markMSSAUsed();249LoopAnalysisManager &LAM = LAMFP.getManager();250251// A postorder worklist of loops to process.252SmallPriorityWorklist<Loop *, 4> Worklist;253254// Register the worklist and loop analysis manager so that loop passes can255// update them when they mutate the loop nest structure.256LPMUpdater Updater(Worklist, LAM, LoopNestMode);257258// Add the loop nests in the reverse order of LoopInfo. See method259// declaration.260if (!LoopNestMode) {261appendLoopsToWorklist(LI, Worklist);262} else {263for (Loop *L : LI)264Worklist.insert(L);265}266267#ifndef NDEBUG268PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) {269if (isSpecialPass(PassID, {"PassManager"}))270return;271assert(llvm::any_cast<const Loop *>(&IR) ||272llvm::any_cast<const LoopNest *>(&IR));273const Loop **LPtr = llvm::any_cast<const Loop *>(&IR);274const Loop *L = LPtr ? *LPtr : nullptr;275if (!L)276L = &llvm::any_cast<const LoopNest *>(IR)->getOutermostLoop();277assert(L && "Loop should be valid for printing");278279// Verify the loop structure and LCSSA form before visiting the loop.280L->verifyLoop();281assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) &&282"Loops must remain in LCSSA form!");283});284#endif285286do {287Loop *L = Worklist.pop_back_val();288assert(!(LoopNestMode && L->getParentLoop()) &&289"L should be a top-level loop in loop-nest mode.");290291// Reset the update structure for this loop.292Updater.CurrentL = L;293Updater.SkipCurrentLoop = false;294295#ifndef NDEBUG296// Save a parent loop pointer for asserts.297Updater.ParentL = L->getParentLoop();298#endif299// Check the PassInstrumentation's BeforePass callbacks before running the300// pass, skip its execution completely if asked to (callback returns301// false).302if (!PI.runBeforePass<Loop>(*Pass, *L))303continue;304305PreservedAnalyses PassPA = Pass->run(*L, LAM, LAR, Updater);306307// Do not pass deleted Loop into the instrumentation.308if (Updater.skipCurrentLoop())309PI.runAfterPassInvalidated<Loop>(*Pass, PassPA);310else311PI.runAfterPass<Loop>(*Pass, *L, PassPA);312313if (LAR.MSSA && !PassPA.getChecker<MemorySSAAnalysis>().preserved())314report_fatal_error("Loop pass manager using MemorySSA contains a pass "315"that does not preserve MemorySSA",316/*gen_crash_diag*/ false);317318#ifndef NDEBUG319// LoopAnalysisResults should always be valid.320if (VerifyDomInfo)321LAR.DT.verify();322if (VerifyLoopInfo)323LAR.LI.verify(LAR.DT);324if (VerifySCEV)325LAR.SE.verify();326if (LAR.MSSA && VerifyMemorySSA)327LAR.MSSA->verifyMemorySSA();328#endif329330// If the loop hasn't been deleted, we need to handle invalidation here.331if (!Updater.skipCurrentLoop())332// We know that the loop pass couldn't have invalidated any other333// loop's analyses (that's the contract of a loop pass), so directly334// handle the loop analysis manager's invalidation here.335LAM.invalidate(*L, PassPA);336337// Then intersect the preserved set so that invalidation of module338// analyses will eventually occur when the module pass completes.339PA.intersect(std::move(PassPA));340} while (!Worklist.empty());341342#ifndef NDEBUG343PI.popBeforeNonSkippedPassCallback();344#endif345346// By definition we preserve the proxy. We also preserve all analyses on347// Loops. This precludes *any* invalidation of loop analyses by the proxy,348// but that's OK because we've taken care to invalidate analyses in the349// loop analysis manager incrementally above.350PA.preserveSet<AllAnalysesOn<Loop>>();351PA.preserve<LoopAnalysisManagerFunctionProxy>();352// We also preserve the set of standard analyses.353PA.preserve<DominatorTreeAnalysis>();354PA.preserve<LoopAnalysis>();355PA.preserve<ScalarEvolutionAnalysis>();356if (UseBlockFrequencyInfo && F.hasProfileData())357PA.preserve<BlockFrequencyAnalysis>();358if (UseBranchProbabilityInfo && F.hasProfileData())359PA.preserve<BranchProbabilityAnalysis>();360if (UseMemorySSA)361PA.preserve<MemorySSAAnalysis>();362return PA;363}364365PrintLoopPass::PrintLoopPass() : OS(dbgs()) {}366PrintLoopPass::PrintLoopPass(raw_ostream &OS, const std::string &Banner)367: OS(OS), Banner(Banner) {}368369PreservedAnalyses PrintLoopPass::run(Loop &L, LoopAnalysisManager &,370LoopStandardAnalysisResults &,371LPMUpdater &) {372printLoop(L, OS, Banner);373return PreservedAnalyses::all();374}375376377