================ @@ -0,0 +1,419 @@ +//===------ PhaseManager.cpp ------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "polly/Pass/PhaseManager.h" +#include "polly/CodeGen/CodeGeneration.h" +#include "polly/CodeGen/IslAst.h" +#include "polly/CodePreparation.h" +#include "polly/DeLICM.h" +#include "polly/DeadCodeElimination.h" +#include "polly/DependenceInfo.h" +#include "polly/FlattenSchedule.h" +#include "polly/ForwardOpTree.h" +#include "polly/JSONExporter.h" +#include "polly/MaximalStaticExpansion.h" +#include "polly/PruneUnprofitable.h" +#include "polly/ScheduleOptimizer.h" +#include "polly/ScopDetection.h" +#include "polly/ScopDetectionDiagnostic.h" +#include "polly/ScopGraphPrinter.h" +#include "polly/ScopInfo.h" +#include "polly/Simplify.h" +#include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" +#include "llvm/IR/Module.h" + +#define DEBUG_TYPE "polly-pass" + +using namespace polly; +using namespace llvm; + +namespace { + +/// Recurse through all subregions and all regions and add them to RQ. +static void addRegionIntoQueue(Region &R, SmallVector<Region *> &RQ) { + RQ.push_back(&R); + for (const auto &E : R) + addRegionIntoQueue(*E, RQ); +} + +/// The phase pipeline of Polly to be embedded into another pass manager than +/// runs passes on functions. +/// +/// Polly holds state besides LLVM-IR (RegionInfo and ScopInfo) between phases +/// that LLVM pass managers do not consider when scheduling analyses and passes. +/// That is, the ScopInfo must persist between phases that a pass manager must +/// not invalidate to recompute later. +class PhaseManager { +private: + Function &F; + FunctionAnalysisManager &FAM; + PollyPassOptions Opts; + +public: + PhaseManager(Function &F, FunctionAnalysisManager &FAM, PollyPassOptions Opts) + : F(F), FAM(FAM), Opts(std::move(Opts)) {} + + /// Execute Polly's phases as indicated by the options. + bool run() { + // Get analyses from the function pass manager. + // These must be preserved during all phases so that if processing one SCoP + // has finished, the next SCoP can still use them. Recomputing is not an + // option because ScopDetection stores references to the old results. + // TODO: CodePreparation doesn't actually need these analysis, it just keeps + // them up-to-date. If they are not computed yet, can also compute after the + // prepare phase. + auto &LI = FAM.getResult<LoopAnalysis>(F); + auto &DT = FAM.getResult<DominatorTreeAnalysis>(F); + bool ModifiedIR = false; + + // Phase: prepare + // TODO: Setting ModifiedIR will invalidate any anlysis, even if DT, LI are + // preserved. + if (Opts.isPhaseEnabled(PassPhase::Prepare)) + ModifiedIR |= runCodePreparation(F, &DT, &LI, nullptr); + + // Can't do anything without detection + if (!Opts.isPhaseEnabled(PassPhase::Detection)) + return false; + + auto &AA = FAM.getResult<AAManager>(F); + auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(F); + auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F); + + // ScopDetection is modifying RegionInfo, do not cache it, nor use a cached + // version. + RegionInfo RI = RegionInfoAnalysis().run(F, FAM); + + // Phase: detection + ScopDetection SD(DT, SE, LI, RI, AA, ORE); + SD.detect(F); + if (Opts.isPhaseEnabled(PassPhase::PrintDetect)) { + outs() << "Detected Scops in Function " << F.getName() << "\n"; + for (const Region *R : SD.ValidRegions) + outs() << "Valid Region for Scop: " << R->getNameStr() << '\n'; + outs() << "\n"; + } + + if (Opts.isPhaseEnabled(PassPhase::DotScops)) + printGraphForFunction(F, &SD, "scops", false); + if (Opts.isPhaseEnabled(PassPhase::DotScopsOnly)) + printGraphForFunction(F, &SD, "scopsonly", true); + + auto ViewScops = [&](const char *Name, bool IsSimply) { + if (Opts.ViewFilter.empty() && !F.getName().count(Opts.ViewFilter)) + return; + + if (Opts.ViewAll || std::distance(SD.begin(), SD.end()) > 0) + viewGraphForFunction(F, &SD, Name, IsSimply); + }; + if (Opts.isPhaseEnabled(PassPhase::ViewScops)) + ViewScops("scops", false); + if (Opts.isPhaseEnabled(PassPhase::ViewScopsOnly)) + ViewScops("scopsonly", true); + + // Phase: scops + auto &AC = FAM.getResult<AssumptionAnalysis>(F); + const DataLayout &DL = F.getParent()->getDataLayout(); + ScopInfo Info(DL, SD, SE, LI, AA, DT, AC, ORE); ---------------- Meinersbur wrote:
Can you clarify? ScopS there iterated over twice: 1. For `-print-scops`: This PR's code reuses the LPM did: https://github.com/llvm/llvm-project/blob/5a91ecf5f004d9defce3ba5f7b08015a1f2073f9/polly/lib/Pass/PhaseManager.cpp#L131 vs https://github.com/llvm/llvm-project/blob/4504e775509483ec20912bc1d805717eecb311ca/llvm/lib/Analysis/RegionPass.cpp#L62 2. For the phase pipeline itself it resuses the code from the NPM/FunctionToScopPassAdaptor: https://github.com/llvm/llvm-project/blob/5a91ecf5f004d9defce3ba5f7b08015a1f2073f9/polly/lib/Pass/PhaseManager.cpp#L148-L158 vs https://github.com/llvm/llvm-project/blob/4504e775509483ec20912bc1d805717eecb311ca/polly/include/polly/ScopPass.h#L238-L259 https://github.com/llvm/llvm-project/pull/125442 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits