xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/LegacyPassManager.cpp (revision 62987288060ff68c817b7056815aa9fb8ba8ecd7)
10b57cec5SDimitry Andric //===- LegacyPassManager.cpp - LLVM Pass Infrastructure Implementation ----===//
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 // This file implements the legacy LLVM Pass Manager infrastructure.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
140b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h"
150b57cec5SDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
160b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
170b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
180b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManagers.h"
190b57cec5SDimitry Andric #include "llvm/IR/Module.h"
200b57cec5SDimitry Andric #include "llvm/IR/PassTimingInfo.h"
21e8d8bef9SDimitry Andric #include "llvm/IR/PrintPasses.h"
220b57cec5SDimitry Andric #include "llvm/Support/Chrono.h"
230b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
240b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
250b57cec5SDimitry Andric #include "llvm/Support/Error.h"
260b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
270b57cec5SDimitry Andric #include "llvm/Support/TimeProfiler.h"
280b57cec5SDimitry Andric #include "llvm/Support/Timer.h"
290b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
300b57cec5SDimitry Andric #include <algorithm>
311fd87a68SDimitry Andric 
320b57cec5SDimitry Andric using namespace llvm;
330b57cec5SDimitry Andric 
345f757f3fSDimitry Andric extern cl::opt<bool> UseNewDbgInfoFormat;
350b57cec5SDimitry Andric // See PassManagers.h for Pass Manager infrastructure overview.
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
380b57cec5SDimitry Andric // Pass debugging information.  Often it is useful to find out what pass is
390b57cec5SDimitry Andric // running when a crash occurs in a utility.  When this library is compiled with
400b57cec5SDimitry Andric // debugging on, a command line option (--debug-pass) is enabled that causes the
410b57cec5SDimitry Andric // pass name to be printed before it executes.
420b57cec5SDimitry Andric //
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric namespace {
450b57cec5SDimitry Andric // Different debug levels that can be enabled...
460b57cec5SDimitry Andric enum PassDebugLevel {
470b57cec5SDimitry Andric   Disabled, Arguments, Structure, Executions, Details
480b57cec5SDimitry Andric };
49e8d8bef9SDimitry Andric } // namespace
500b57cec5SDimitry Andric 
51fe6060f1SDimitry Andric static cl::opt<enum PassDebugLevel> PassDebugging(
52fe6060f1SDimitry Andric     "debug-pass", cl::Hidden,
53fe6060f1SDimitry Andric     cl::desc("Print legacy PassManager debugging information"),
54fe6060f1SDimitry Andric     cl::values(clEnumVal(Disabled, "disable debug output"),
550b57cec5SDimitry Andric                clEnumVal(Arguments, "print pass arguments to pass to 'opt'"),
560b57cec5SDimitry Andric                clEnumVal(Structure, "print pass structure before run()"),
570b57cec5SDimitry Andric                clEnumVal(Executions, "print pass name before it is executed"),
580b57cec5SDimitry Andric                clEnumVal(Details, "print pass details when it is executed")));
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
610b57cec5SDimitry Andric /// or higher is specified.
620b57cec5SDimitry Andric bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
630b57cec5SDimitry Andric   return PassDebugging >= Executions;
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric unsigned PMDataManager::initSizeRemarkInfo(
670b57cec5SDimitry Andric     Module &M, StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount) {
680b57cec5SDimitry Andric   // Only calculate getInstructionCount if the size-info remark is requested.
690b57cec5SDimitry Andric   unsigned InstrCount = 0;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   // Collect instruction counts for every function. We'll use this to emit
720b57cec5SDimitry Andric   // per-function size remarks later.
730b57cec5SDimitry Andric   for (Function &F : M) {
740b57cec5SDimitry Andric     unsigned FCount = F.getInstructionCount();
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric     // Insert a record into FunctionToInstrCount keeping track of the current
770b57cec5SDimitry Andric     // size of the function as the first member of a pair. Set the second
780b57cec5SDimitry Andric     // member to 0; if the function is deleted by the pass, then when we get
790b57cec5SDimitry Andric     // here, we'll be able to let the user know that F no longer contributes to
800b57cec5SDimitry Andric     // the module.
810b57cec5SDimitry Andric     FunctionToInstrCount[F.getName().str()] =
820b57cec5SDimitry Andric         std::pair<unsigned, unsigned>(FCount, 0);
830b57cec5SDimitry Andric     InstrCount += FCount;
840b57cec5SDimitry Andric   }
850b57cec5SDimitry Andric   return InstrCount;
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric void PMDataManager::emitInstrCountChangedRemark(
890b57cec5SDimitry Andric     Pass *P, Module &M, int64_t Delta, unsigned CountBefore,
900b57cec5SDimitry Andric     StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount,
910b57cec5SDimitry Andric     Function *F) {
920b57cec5SDimitry Andric   // If it's a pass manager, don't emit a remark. (This hinges on the assumption
930b57cec5SDimitry Andric   // that the only passes that return non-null with getAsPMDataManager are pass
940b57cec5SDimitry Andric   // managers.) The reason we have to do this is to avoid emitting remarks for
950b57cec5SDimitry Andric   // CGSCC passes.
960b57cec5SDimitry Andric   if (P->getAsPMDataManager())
970b57cec5SDimitry Andric     return;
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   // Set to true if this isn't a module pass or CGSCC pass.
1000b57cec5SDimitry Andric   bool CouldOnlyImpactOneFunction = (F != nullptr);
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   // Helper lambda that updates the changes to the size of some function.
1030b57cec5SDimitry Andric   auto UpdateFunctionChanges =
1040b57cec5SDimitry Andric       [&FunctionToInstrCount](Function &MaybeChangedFn) {
1050b57cec5SDimitry Andric         // Update the total module count.
1060b57cec5SDimitry Andric         unsigned FnSize = MaybeChangedFn.getInstructionCount();
1070b57cec5SDimitry Andric         auto It = FunctionToInstrCount.find(MaybeChangedFn.getName());
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric         // If we created a new function, then we need to add it to the map and
1100b57cec5SDimitry Andric         // say that it changed from 0 instructions to FnSize.
1110b57cec5SDimitry Andric         if (It == FunctionToInstrCount.end()) {
1120b57cec5SDimitry Andric           FunctionToInstrCount[MaybeChangedFn.getName()] =
1130b57cec5SDimitry Andric               std::pair<unsigned, unsigned>(0, FnSize);
1140b57cec5SDimitry Andric           return;
1150b57cec5SDimitry Andric         }
1160b57cec5SDimitry Andric         // Insert the new function size into the second member of the pair. This
1170b57cec5SDimitry Andric         // tells us whether or not this function changed in size.
1180b57cec5SDimitry Andric         It->second.second = FnSize;
1190b57cec5SDimitry Andric       };
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   // We need to initially update all of the function sizes.
1220b57cec5SDimitry Andric   // If no function was passed in, then we're either a module pass or an
1230b57cec5SDimitry Andric   // CGSCC pass.
1240b57cec5SDimitry Andric   if (!CouldOnlyImpactOneFunction)
1250b57cec5SDimitry Andric     std::for_each(M.begin(), M.end(), UpdateFunctionChanges);
1260b57cec5SDimitry Andric   else
1270b57cec5SDimitry Andric     UpdateFunctionChanges(*F);
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric   // Do we have a function we can use to emit a remark?
1300b57cec5SDimitry Andric   if (!CouldOnlyImpactOneFunction) {
1310b57cec5SDimitry Andric     // We need a function containing at least one basic block in order to output
1320b57cec5SDimitry Andric     // remarks. Since it's possible that the first function in the module
1330b57cec5SDimitry Andric     // doesn't actually contain a basic block, we have to go and find one that's
1340b57cec5SDimitry Andric     // suitable for emitting remarks.
135e8d8bef9SDimitry Andric     auto It = llvm::find_if(M, [](const Function &Fn) { return !Fn.empty(); });
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric     // Didn't find a function. Quit.
1380b57cec5SDimitry Andric     if (It == M.end())
1390b57cec5SDimitry Andric       return;
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric     // We found a function containing at least one basic block.
1420b57cec5SDimitry Andric     F = &*It;
1430b57cec5SDimitry Andric   }
1440b57cec5SDimitry Andric   int64_t CountAfter = static_cast<int64_t>(CountBefore) + Delta;
1450b57cec5SDimitry Andric   BasicBlock &BB = *F->begin();
1460b57cec5SDimitry Andric   OptimizationRemarkAnalysis R("size-info", "IRSizeChange",
1470b57cec5SDimitry Andric                                DiagnosticLocation(), &BB);
1480b57cec5SDimitry Andric   // FIXME: Move ore namespace to DiagnosticInfo so that we can use it. This
1490b57cec5SDimitry Andric   // would let us use NV instead of DiagnosticInfoOptimizationBase::Argument.
1500b57cec5SDimitry Andric   R << DiagnosticInfoOptimizationBase::Argument("Pass", P->getPassName())
1510b57cec5SDimitry Andric     << ": IR instruction count changed from "
1520b57cec5SDimitry Andric     << DiagnosticInfoOptimizationBase::Argument("IRInstrsBefore", CountBefore)
1530b57cec5SDimitry Andric     << " to "
1540b57cec5SDimitry Andric     << DiagnosticInfoOptimizationBase::Argument("IRInstrsAfter", CountAfter)
1550b57cec5SDimitry Andric     << "; Delta: "
1560b57cec5SDimitry Andric     << DiagnosticInfoOptimizationBase::Argument("DeltaInstrCount", Delta);
1570b57cec5SDimitry Andric   F->getContext().diagnose(R); // Not using ORE for layering reasons.
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric   // Emit per-function size change remarks separately.
1600b57cec5SDimitry Andric   std::string PassName = P->getPassName().str();
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   // Helper lambda that emits a remark when the size of a function has changed.
1630b57cec5SDimitry Andric   auto EmitFunctionSizeChangedRemark = [&FunctionToInstrCount, &F, &BB,
1645ffd83dbSDimitry Andric                                         &PassName](StringRef Fname) {
1650b57cec5SDimitry Andric     unsigned FnCountBefore, FnCountAfter;
1660b57cec5SDimitry Andric     std::pair<unsigned, unsigned> &Change = FunctionToInstrCount[Fname];
1670b57cec5SDimitry Andric     std::tie(FnCountBefore, FnCountAfter) = Change;
1680b57cec5SDimitry Andric     int64_t FnDelta = static_cast<int64_t>(FnCountAfter) -
1690b57cec5SDimitry Andric                       static_cast<int64_t>(FnCountBefore);
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric     if (FnDelta == 0)
1720b57cec5SDimitry Andric       return;
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric     // FIXME: We shouldn't use BB for the location here. Unfortunately, because
1750b57cec5SDimitry Andric     // the function that we're looking at could have been deleted, we can't use
1760b57cec5SDimitry Andric     // it for the source location. We *want* remarks when a function is deleted
1770b57cec5SDimitry Andric     // though, so we're kind of stuck here as is. (This remark, along with the
1780b57cec5SDimitry Andric     // whole-module size change remarks really ought not to have source
1790b57cec5SDimitry Andric     // locations at all.)
1800b57cec5SDimitry Andric     OptimizationRemarkAnalysis FR("size-info", "FunctionIRSizeChange",
1810b57cec5SDimitry Andric                                   DiagnosticLocation(), &BB);
1820b57cec5SDimitry Andric     FR << DiagnosticInfoOptimizationBase::Argument("Pass", PassName)
1830b57cec5SDimitry Andric        << ": Function: "
1840b57cec5SDimitry Andric        << DiagnosticInfoOptimizationBase::Argument("Function", Fname)
1850b57cec5SDimitry Andric        << ": IR instruction count changed from "
1860b57cec5SDimitry Andric        << DiagnosticInfoOptimizationBase::Argument("IRInstrsBefore",
1870b57cec5SDimitry Andric                                                    FnCountBefore)
1880b57cec5SDimitry Andric        << " to "
1890b57cec5SDimitry Andric        << DiagnosticInfoOptimizationBase::Argument("IRInstrsAfter",
1900b57cec5SDimitry Andric                                                    FnCountAfter)
1910b57cec5SDimitry Andric        << "; Delta: "
1920b57cec5SDimitry Andric        << DiagnosticInfoOptimizationBase::Argument("DeltaInstrCount", FnDelta);
1930b57cec5SDimitry Andric     F->getContext().diagnose(FR);
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric     // Update the function size.
1960b57cec5SDimitry Andric     Change.first = FnCountAfter;
1970b57cec5SDimitry Andric   };
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   // Are we looking at more than one function? If so, emit remarks for all of
2000b57cec5SDimitry Andric   // the functions in the module. Otherwise, only emit one remark.
2010b57cec5SDimitry Andric   if (!CouldOnlyImpactOneFunction)
2020b57cec5SDimitry Andric     std::for_each(FunctionToInstrCount.keys().begin(),
2030b57cec5SDimitry Andric                   FunctionToInstrCount.keys().end(),
2040b57cec5SDimitry Andric                   EmitFunctionSizeChangedRemark);
2050b57cec5SDimitry Andric   else
2060b57cec5SDimitry Andric     EmitFunctionSizeChangedRemark(F->getName().str());
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric void PassManagerPrettyStackEntry::print(raw_ostream &OS) const {
2100b57cec5SDimitry Andric   if (!V && !M)
2110b57cec5SDimitry Andric     OS << "Releasing pass '";
2120b57cec5SDimitry Andric   else
2130b57cec5SDimitry Andric     OS << "Running pass '";
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   OS << P->getPassName() << "'";
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   if (M) {
2180b57cec5SDimitry Andric     OS << " on module '" << M->getModuleIdentifier() << "'.\n";
2190b57cec5SDimitry Andric     return;
2200b57cec5SDimitry Andric   }
2210b57cec5SDimitry Andric   if (!V) {
2220b57cec5SDimitry Andric     OS << '\n';
2230b57cec5SDimitry Andric     return;
2240b57cec5SDimitry Andric   }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   OS << " on ";
2270b57cec5SDimitry Andric   if (isa<Function>(V))
2280b57cec5SDimitry Andric     OS << "function";
2290b57cec5SDimitry Andric   else if (isa<BasicBlock>(V))
2300b57cec5SDimitry Andric     OS << "basic block";
2310b57cec5SDimitry Andric   else
2320b57cec5SDimitry Andric     OS << "value";
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   OS << " '";
2350b57cec5SDimitry Andric   V->printAsOperand(OS, /*PrintType=*/false, M);
2360b57cec5SDimitry Andric   OS << "'\n";
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric namespace llvm {
2400b57cec5SDimitry Andric namespace legacy {
241fe6060f1SDimitry Andric bool debugPassSpecified() { return PassDebugging != Disabled; }
242fe6060f1SDimitry Andric 
2430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2440b57cec5SDimitry Andric // FunctionPassManagerImpl
2450b57cec5SDimitry Andric //
2460b57cec5SDimitry Andric /// FunctionPassManagerImpl manages FPPassManagers
2470b57cec5SDimitry Andric class FunctionPassManagerImpl : public Pass,
2480b57cec5SDimitry Andric                                 public PMDataManager,
2490b57cec5SDimitry Andric                                 public PMTopLevelManager {
2500b57cec5SDimitry Andric   virtual void anchor();
2510b57cec5SDimitry Andric private:
2520b57cec5SDimitry Andric   bool wasRun;
2530b57cec5SDimitry Andric public:
2540b57cec5SDimitry Andric   static char ID;
25504eeddc0SDimitry Andric   explicit FunctionPassManagerImpl()
25604eeddc0SDimitry Andric       : Pass(PT_PassManager, ID), PMTopLevelManager(new FPPassManager()),
25704eeddc0SDimitry Andric         wasRun(false) {}
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   /// \copydoc FunctionPassManager::add()
2600b57cec5SDimitry Andric   void add(Pass *P) {
2610b57cec5SDimitry Andric     schedulePass(P);
2620b57cec5SDimitry Andric   }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   /// createPrinterPass - Get a function printer pass.
2650b57cec5SDimitry Andric   Pass *createPrinterPass(raw_ostream &O,
2660b57cec5SDimitry Andric                           const std::string &Banner) const override {
2670b57cec5SDimitry Andric     return createPrintFunctionPass(O, Banner);
2680b57cec5SDimitry Andric   }
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric   // Prepare for running an on the fly pass, freeing memory if needed
2710b57cec5SDimitry Andric   // from a previous run.
2720b57cec5SDimitry Andric   void releaseMemoryOnTheFly();
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric   /// run - Execute all of the passes scheduled for execution.  Keep track of
2750b57cec5SDimitry Andric   /// whether any of the passes modifies the module, and if so, return true.
2760b57cec5SDimitry Andric   bool run(Function &F);
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric   /// doInitialization - Run all of the initializers for the function passes.
2790b57cec5SDimitry Andric   ///
2800b57cec5SDimitry Andric   bool doInitialization(Module &M) override;
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   /// doFinalization - Run all of the finalizers for the function passes.
2830b57cec5SDimitry Andric   ///
2840b57cec5SDimitry Andric   bool doFinalization(Module &M) override;
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   PMDataManager *getAsPMDataManager() override { return this; }
2880b57cec5SDimitry Andric   Pass *getAsPass() override { return this; }
2890b57cec5SDimitry Andric   PassManagerType getTopLevelPassManagerType() override {
2900b57cec5SDimitry Andric     return PMT_FunctionPassManager;
2910b57cec5SDimitry Andric   }
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   /// Pass Manager itself does not invalidate any analysis info.
2940b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &Info) const override {
2950b57cec5SDimitry Andric     Info.setPreservesAll();
2960b57cec5SDimitry Andric   }
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   FPPassManager *getContainedManager(unsigned N) {
2990b57cec5SDimitry Andric     assert(N < PassManagers.size() && "Pass number out of range!");
3000b57cec5SDimitry Andric     FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]);
3010b57cec5SDimitry Andric     return FP;
3020b57cec5SDimitry Andric   }
303480093f4SDimitry Andric 
304480093f4SDimitry Andric   void dumpPassStructure(unsigned Offset) override {
305480093f4SDimitry Andric     for (unsigned I = 0; I < getNumContainedManagers(); ++I)
306480093f4SDimitry Andric       getContainedManager(I)->dumpPassStructure(Offset);
307480093f4SDimitry Andric   }
3080b57cec5SDimitry Andric };
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric void FunctionPassManagerImpl::anchor() {}
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric char FunctionPassManagerImpl::ID = 0;
3135ffd83dbSDimitry Andric 
3145ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
3155ffd83dbSDimitry Andric // FunctionPassManagerImpl implementation
3165ffd83dbSDimitry Andric //
3175ffd83dbSDimitry Andric bool FunctionPassManagerImpl::doInitialization(Module &M) {
3185ffd83dbSDimitry Andric   bool Changed = false;
3195ffd83dbSDimitry Andric 
3205ffd83dbSDimitry Andric   dumpArguments();
3215ffd83dbSDimitry Andric   dumpPasses();
3225ffd83dbSDimitry Andric 
3235ffd83dbSDimitry Andric   for (ImmutablePass *ImPass : getImmutablePasses())
3245ffd83dbSDimitry Andric     Changed |= ImPass->doInitialization(M);
3255ffd83dbSDimitry Andric 
3265ffd83dbSDimitry Andric   for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
3275ffd83dbSDimitry Andric     Changed |= getContainedManager(Index)->doInitialization(M);
3285ffd83dbSDimitry Andric 
3295ffd83dbSDimitry Andric   return Changed;
3305ffd83dbSDimitry Andric }
3315ffd83dbSDimitry Andric 
3325ffd83dbSDimitry Andric bool FunctionPassManagerImpl::doFinalization(Module &M) {
3335ffd83dbSDimitry Andric   bool Changed = false;
3345ffd83dbSDimitry Andric 
3355ffd83dbSDimitry Andric   for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index)
3365ffd83dbSDimitry Andric     Changed |= getContainedManager(Index)->doFinalization(M);
3375ffd83dbSDimitry Andric 
3385ffd83dbSDimitry Andric   for (ImmutablePass *ImPass : getImmutablePasses())
3395ffd83dbSDimitry Andric     Changed |= ImPass->doFinalization(M);
3405ffd83dbSDimitry Andric 
3415ffd83dbSDimitry Andric   return Changed;
3425ffd83dbSDimitry Andric }
3435ffd83dbSDimitry Andric 
3445ffd83dbSDimitry Andric void FunctionPassManagerImpl::releaseMemoryOnTheFly() {
3455ffd83dbSDimitry Andric   if (!wasRun)
3465ffd83dbSDimitry Andric     return;
3475ffd83dbSDimitry Andric   for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
3485ffd83dbSDimitry Andric     FPPassManager *FPPM = getContainedManager(Index);
3495ffd83dbSDimitry Andric     for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) {
3505ffd83dbSDimitry Andric       FPPM->getContainedPass(Index)->releaseMemory();
3515ffd83dbSDimitry Andric     }
3525ffd83dbSDimitry Andric   }
3535ffd83dbSDimitry Andric   wasRun = false;
3545ffd83dbSDimitry Andric }
3555ffd83dbSDimitry Andric 
3565ffd83dbSDimitry Andric // Execute all the passes managed by this top level manager.
3575ffd83dbSDimitry Andric // Return true if any function is modified by a pass.
3585ffd83dbSDimitry Andric bool FunctionPassManagerImpl::run(Function &F) {
3595ffd83dbSDimitry Andric   bool Changed = false;
3605ffd83dbSDimitry Andric 
3615ffd83dbSDimitry Andric   initializeAllAnalysisInfo();
3625ffd83dbSDimitry Andric   for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
3635ffd83dbSDimitry Andric     Changed |= getContainedManager(Index)->runOnFunction(F);
3645ffd83dbSDimitry Andric     F.getContext().yield();
3655ffd83dbSDimitry Andric   }
3665ffd83dbSDimitry Andric 
3675ffd83dbSDimitry Andric   for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
3685ffd83dbSDimitry Andric     getContainedManager(Index)->cleanup();
3695ffd83dbSDimitry Andric 
3705ffd83dbSDimitry Andric   wasRun = true;
3715ffd83dbSDimitry Andric   return Changed;
3725ffd83dbSDimitry Andric }
3735ffd83dbSDimitry Andric } // namespace legacy
3745ffd83dbSDimitry Andric } // namespace llvm
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric namespace {
3770b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3780b57cec5SDimitry Andric // MPPassManager
3790b57cec5SDimitry Andric //
3800b57cec5SDimitry Andric /// MPPassManager manages ModulePasses and function pass managers.
3810b57cec5SDimitry Andric /// It batches all Module passes and function pass managers together and
3820b57cec5SDimitry Andric /// sequences them to process one module.
3830b57cec5SDimitry Andric class MPPassManager : public Pass, public PMDataManager {
3840b57cec5SDimitry Andric public:
3850b57cec5SDimitry Andric   static char ID;
38604eeddc0SDimitry Andric   explicit MPPassManager() : Pass(PT_PassManager, ID) {}
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   // Delete on the fly managers.
3890b57cec5SDimitry Andric   ~MPPassManager() override {
3900b57cec5SDimitry Andric     for (auto &OnTheFlyManager : OnTheFlyManagers) {
3915ffd83dbSDimitry Andric       legacy::FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
3920b57cec5SDimitry Andric       delete FPP;
3930b57cec5SDimitry Andric     }
3940b57cec5SDimitry Andric   }
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   /// createPrinterPass - Get a module printer pass.
3970b57cec5SDimitry Andric   Pass *createPrinterPass(raw_ostream &O,
3980b57cec5SDimitry Andric                           const std::string &Banner) const override {
3990b57cec5SDimitry Andric     return createPrintModulePass(O, Banner);
4000b57cec5SDimitry Andric   }
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric   /// run - Execute all of the passes scheduled for execution.  Keep track of
4030b57cec5SDimitry Andric   /// whether any of the passes modifies the module, and if so, return true.
4040b57cec5SDimitry Andric   bool runOnModule(Module &M);
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric   using llvm::Pass::doInitialization;
4070b57cec5SDimitry Andric   using llvm::Pass::doFinalization;
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric   /// Pass Manager itself does not invalidate any analysis info.
4100b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &Info) const override {
4110b57cec5SDimitry Andric     Info.setPreservesAll();
4120b57cec5SDimitry Andric   }
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   /// Add RequiredPass into list of lower level passes required by pass P.
4150b57cec5SDimitry Andric   /// RequiredPass is run on the fly by Pass Manager when P requests it
4160b57cec5SDimitry Andric   /// through getAnalysis interface.
4170b57cec5SDimitry Andric   void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) override;
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric   /// Return function pass corresponding to PassInfo PI, that is
4200b57cec5SDimitry Andric   /// required by module pass MP. Instantiate analysis pass, by using
4210b57cec5SDimitry Andric   /// its runOnFunction() for function F.
4225ffd83dbSDimitry Andric   std::tuple<Pass *, bool> getOnTheFlyPass(Pass *MP, AnalysisID PI,
4235ffd83dbSDimitry Andric                                            Function &F) override;
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric   StringRef getPassName() const override { return "Module Pass Manager"; }
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric   PMDataManager *getAsPMDataManager() override { return this; }
4280b57cec5SDimitry Andric   Pass *getAsPass() override { return this; }
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric   // Print passes managed by this manager
4310b57cec5SDimitry Andric   void dumpPassStructure(unsigned Offset) override {
4320b57cec5SDimitry Andric     dbgs().indent(Offset*2) << "ModulePass Manager\n";
4330b57cec5SDimitry Andric     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
4340b57cec5SDimitry Andric       ModulePass *MP = getContainedPass(Index);
4350b57cec5SDimitry Andric       MP->dumpPassStructure(Offset + 1);
4365ffd83dbSDimitry Andric       MapVector<Pass *, legacy::FunctionPassManagerImpl *>::const_iterator I =
4370b57cec5SDimitry Andric           OnTheFlyManagers.find(MP);
4380b57cec5SDimitry Andric       if (I != OnTheFlyManagers.end())
4390b57cec5SDimitry Andric         I->second->dumpPassStructure(Offset + 2);
4400b57cec5SDimitry Andric       dumpLastUses(MP, Offset+1);
4410b57cec5SDimitry Andric     }
4420b57cec5SDimitry Andric   }
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric   ModulePass *getContainedPass(unsigned N) {
4450b57cec5SDimitry Andric     assert(N < PassVector.size() && "Pass number out of range!");
4460b57cec5SDimitry Andric     return static_cast<ModulePass *>(PassVector[N]);
4470b57cec5SDimitry Andric   }
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric   PassManagerType getPassManagerType() const override {
4500b57cec5SDimitry Andric     return PMT_ModulePassManager;
4510b57cec5SDimitry Andric   }
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric  private:
4540b57cec5SDimitry Andric   /// Collection of on the fly FPPassManagers. These managers manage
4550b57cec5SDimitry Andric   /// function passes that are required by module passes.
4565ffd83dbSDimitry Andric    MapVector<Pass *, legacy::FunctionPassManagerImpl *> OnTheFlyManagers;
4570b57cec5SDimitry Andric };
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric char MPPassManager::ID = 0;
4600b57cec5SDimitry Andric } // End anonymous namespace
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric namespace llvm {
4630b57cec5SDimitry Andric namespace legacy {
4640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4650b57cec5SDimitry Andric // PassManagerImpl
4660b57cec5SDimitry Andric //
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric /// PassManagerImpl manages MPPassManagers
4690b57cec5SDimitry Andric class PassManagerImpl : public Pass,
4700b57cec5SDimitry Andric                         public PMDataManager,
4710b57cec5SDimitry Andric                         public PMTopLevelManager {
4720b57cec5SDimitry Andric   virtual void anchor();
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric public:
4750b57cec5SDimitry Andric   static char ID;
47604eeddc0SDimitry Andric   explicit PassManagerImpl()
47704eeddc0SDimitry Andric       : Pass(PT_PassManager, ID), PMTopLevelManager(new MPPassManager()) {}
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric   /// \copydoc PassManager::add()
4800b57cec5SDimitry Andric   void add(Pass *P) {
4810b57cec5SDimitry Andric     schedulePass(P);
4820b57cec5SDimitry Andric   }
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   /// createPrinterPass - Get a module printer pass.
4850b57cec5SDimitry Andric   Pass *createPrinterPass(raw_ostream &O,
4860b57cec5SDimitry Andric                           const std::string &Banner) const override {
4870b57cec5SDimitry Andric     return createPrintModulePass(O, Banner);
4880b57cec5SDimitry Andric   }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   /// run - Execute all of the passes scheduled for execution.  Keep track of
4910b57cec5SDimitry Andric   /// whether any of the passes modifies the module, and if so, return true.
4920b57cec5SDimitry Andric   bool run(Module &M);
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric   using llvm::Pass::doInitialization;
4950b57cec5SDimitry Andric   using llvm::Pass::doFinalization;
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric   /// Pass Manager itself does not invalidate any analysis info.
4980b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &Info) const override {
4990b57cec5SDimitry Andric     Info.setPreservesAll();
5000b57cec5SDimitry Andric   }
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   PMDataManager *getAsPMDataManager() override { return this; }
5030b57cec5SDimitry Andric   Pass *getAsPass() override { return this; }
5040b57cec5SDimitry Andric   PassManagerType getTopLevelPassManagerType() override {
5050b57cec5SDimitry Andric     return PMT_ModulePassManager;
5060b57cec5SDimitry Andric   }
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   MPPassManager *getContainedManager(unsigned N) {
5090b57cec5SDimitry Andric     assert(N < PassManagers.size() && "Pass number out of range!");
5100b57cec5SDimitry Andric     MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]);
5110b57cec5SDimitry Andric     return MP;
5120b57cec5SDimitry Andric   }
5130b57cec5SDimitry Andric };
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric void PassManagerImpl::anchor() {}
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric char PassManagerImpl::ID = 0;
5185ffd83dbSDimitry Andric 
5195ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
5205ffd83dbSDimitry Andric // PassManagerImpl implementation
5215ffd83dbSDimitry Andric 
5225ffd83dbSDimitry Andric //
5235ffd83dbSDimitry Andric /// run - Execute all of the passes scheduled for execution.  Keep track of
5245ffd83dbSDimitry Andric /// whether any of the passes modifies the module, and if so, return true.
5255ffd83dbSDimitry Andric bool PassManagerImpl::run(Module &M) {
5265ffd83dbSDimitry Andric   bool Changed = false;
5275ffd83dbSDimitry Andric 
5285ffd83dbSDimitry Andric   dumpArguments();
5295ffd83dbSDimitry Andric   dumpPasses();
5305ffd83dbSDimitry Andric 
5310fca6ea1SDimitry Andric   // RemoveDIs: if a command line flag is given, convert to the
5320fca6ea1SDimitry Andric   // DbgVariableRecord representation of debug-info for the duration of these
5330fca6ea1SDimitry Andric   // passes.
5340fca6ea1SDimitry Andric   ScopedDbgInfoFormatSetter FormatSetter(M, UseNewDbgInfoFormat);
5355f757f3fSDimitry Andric 
5365ffd83dbSDimitry Andric   for (ImmutablePass *ImPass : getImmutablePasses())
5375ffd83dbSDimitry Andric     Changed |= ImPass->doInitialization(M);
5385ffd83dbSDimitry Andric 
5395ffd83dbSDimitry Andric   initializeAllAnalysisInfo();
5405ffd83dbSDimitry Andric   for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
5415ffd83dbSDimitry Andric     Changed |= getContainedManager(Index)->runOnModule(M);
5425ffd83dbSDimitry Andric     M.getContext().yield();
5435ffd83dbSDimitry Andric   }
5445ffd83dbSDimitry Andric 
5455ffd83dbSDimitry Andric   for (ImmutablePass *ImPass : getImmutablePasses())
5465ffd83dbSDimitry Andric     Changed |= ImPass->doFinalization(M);
5475ffd83dbSDimitry Andric 
5485ffd83dbSDimitry Andric   return Changed;
5495ffd83dbSDimitry Andric }
5505ffd83dbSDimitry Andric } // namespace legacy
5515ffd83dbSDimitry Andric } // namespace llvm
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5540b57cec5SDimitry Andric // PMTopLevelManager implementation
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric /// Initialize top level manager. Create first pass manager.
5570b57cec5SDimitry Andric PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) {
5580b57cec5SDimitry Andric   PMDM->setTopLevelManager(this);
5590b57cec5SDimitry Andric   addPassManager(PMDM);
5600b57cec5SDimitry Andric   activeStack.push(PMDM);
5610b57cec5SDimitry Andric }
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric /// Set pass P as the last user of the given analysis passes.
5640b57cec5SDimitry Andric void
5650b57cec5SDimitry Andric PMTopLevelManager::setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P) {
5660b57cec5SDimitry Andric   unsigned PDepth = 0;
5670b57cec5SDimitry Andric   if (P->getResolver())
5680b57cec5SDimitry Andric     PDepth = P->getResolver()->getPMDataManager().getDepth();
5690b57cec5SDimitry Andric 
5700b57cec5SDimitry Andric   for (Pass *AP : AnalysisPasses) {
571e8d8bef9SDimitry Andric     // Record P as the new last user of AP.
572e8d8bef9SDimitry Andric     auto &LastUserOfAP = LastUser[AP];
573e8d8bef9SDimitry Andric     if (LastUserOfAP)
574e8d8bef9SDimitry Andric       InversedLastUser[LastUserOfAP].erase(AP);
575e8d8bef9SDimitry Andric     LastUserOfAP = P;
576e8d8bef9SDimitry Andric     InversedLastUser[P].insert(AP);
5770b57cec5SDimitry Andric 
5780b57cec5SDimitry Andric     if (P == AP)
5790b57cec5SDimitry Andric       continue;
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric     // Update the last users of passes that are required transitive by AP.
5820b57cec5SDimitry Andric     AnalysisUsage *AnUsage = findAnalysisUsage(AP);
5830b57cec5SDimitry Andric     const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet();
5840b57cec5SDimitry Andric     SmallVector<Pass *, 12> LastUses;
5850b57cec5SDimitry Andric     SmallVector<Pass *, 12> LastPMUses;
5860b57cec5SDimitry Andric     for (AnalysisID ID : IDs) {
5870b57cec5SDimitry Andric       Pass *AnalysisPass = findAnalysisPass(ID);
5880b57cec5SDimitry Andric       assert(AnalysisPass && "Expected analysis pass to exist.");
5890b57cec5SDimitry Andric       AnalysisResolver *AR = AnalysisPass->getResolver();
5900b57cec5SDimitry Andric       assert(AR && "Expected analysis resolver to exist.");
5910b57cec5SDimitry Andric       unsigned APDepth = AR->getPMDataManager().getDepth();
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric       if (PDepth == APDepth)
5940b57cec5SDimitry Andric         LastUses.push_back(AnalysisPass);
5950b57cec5SDimitry Andric       else if (PDepth > APDepth)
5960b57cec5SDimitry Andric         LastPMUses.push_back(AnalysisPass);
5970b57cec5SDimitry Andric     }
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric     setLastUser(LastUses, P);
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric     // If this pass has a corresponding pass manager, push higher level
6020b57cec5SDimitry Andric     // analysis to this pass manager.
6030b57cec5SDimitry Andric     if (P->getResolver())
6040b57cec5SDimitry Andric       setLastUser(LastPMUses, P->getResolver()->getPMDataManager().getAsPass());
6050b57cec5SDimitry Andric 
6060b57cec5SDimitry Andric     // If AP is the last user of other passes then make P last user of
6070b57cec5SDimitry Andric     // such passes.
608e8d8bef9SDimitry Andric     auto &LastUsedByAP = InversedLastUser[AP];
609e8d8bef9SDimitry Andric     for (Pass *L : LastUsedByAP)
610e8d8bef9SDimitry Andric       LastUser[L] = P;
611e8d8bef9SDimitry Andric     InversedLastUser[P].insert(LastUsedByAP.begin(), LastUsedByAP.end());
612e8d8bef9SDimitry Andric     LastUsedByAP.clear();
6130b57cec5SDimitry Andric   }
6140b57cec5SDimitry Andric }
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric /// Collect passes whose last user is P
6170b57cec5SDimitry Andric void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses,
6180b57cec5SDimitry Andric                                         Pass *P) {
619e8d8bef9SDimitry Andric   auto DMI = InversedLastUser.find(P);
6200b57cec5SDimitry Andric   if (DMI == InversedLastUser.end())
6210b57cec5SDimitry Andric     return;
6220b57cec5SDimitry Andric 
623e8d8bef9SDimitry Andric   auto &LU = DMI->second;
624e8d8bef9SDimitry Andric   LastUses.append(LU.begin(), LU.end());
6250b57cec5SDimitry Andric }
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) {
6280b57cec5SDimitry Andric   AnalysisUsage *AnUsage = nullptr;
6290b57cec5SDimitry Andric   auto DMI = AnUsageMap.find(P);
6300b57cec5SDimitry Andric   if (DMI != AnUsageMap.end())
6310b57cec5SDimitry Andric     AnUsage = DMI->second;
6320b57cec5SDimitry Andric   else {
6330b57cec5SDimitry Andric     // Look up the analysis usage from the pass instance (different instances
6340b57cec5SDimitry Andric     // of the same pass can produce different results), but unique the
6350b57cec5SDimitry Andric     // resulting object to reduce memory usage.  This helps to greatly reduce
6360b57cec5SDimitry Andric     // memory usage when we have many instances of only a few pass types
6370b57cec5SDimitry Andric     // (e.g. instcombine, simplifycfg, etc...) which tend to share a fixed set
6380b57cec5SDimitry Andric     // of dependencies.
6390b57cec5SDimitry Andric     AnalysisUsage AU;
6400b57cec5SDimitry Andric     P->getAnalysisUsage(AU);
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric     AUFoldingSetNode* Node = nullptr;
6430b57cec5SDimitry Andric     FoldingSetNodeID ID;
6440b57cec5SDimitry Andric     AUFoldingSetNode::Profile(ID, AU);
6450b57cec5SDimitry Andric     void *IP = nullptr;
6460b57cec5SDimitry Andric     if (auto *N = UniqueAnalysisUsages.FindNodeOrInsertPos(ID, IP))
6470b57cec5SDimitry Andric       Node = N;
6480b57cec5SDimitry Andric     else {
6490b57cec5SDimitry Andric       Node = new (AUFoldingSetNodeAllocator.Allocate()) AUFoldingSetNode(AU);
6500b57cec5SDimitry Andric       UniqueAnalysisUsages.InsertNode(Node, IP);
6510b57cec5SDimitry Andric     }
6520b57cec5SDimitry Andric     assert(Node && "cached analysis usage must be non null");
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric     AnUsageMap[P] = &Node->AU;
6550b57cec5SDimitry Andric     AnUsage = &Node->AU;
6560b57cec5SDimitry Andric   }
6570b57cec5SDimitry Andric   return AnUsage;
6580b57cec5SDimitry Andric }
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric /// Schedule pass P for execution. Make sure that passes required by
6610b57cec5SDimitry Andric /// P are run before P is run. Update analysis info maintained by
6620b57cec5SDimitry Andric /// the manager. Remove dead passes. This is a recursive function.
6630b57cec5SDimitry Andric void PMTopLevelManager::schedulePass(Pass *P) {
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric   // TODO : Allocate function manager for this pass, other wise required set
6660b57cec5SDimitry Andric   // may be inserted into previous function manager
6670b57cec5SDimitry Andric 
6680b57cec5SDimitry Andric   // Give pass a chance to prepare the stage.
6690b57cec5SDimitry Andric   P->preparePassManager(activeStack);
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric   // If P is an analysis pass and it is available then do not
6720b57cec5SDimitry Andric   // generate the analysis again. Stale analysis info should not be
6730b57cec5SDimitry Andric   // available at this point.
6740b57cec5SDimitry Andric   const PassInfo *PI = findAnalysisPassInfo(P->getPassID());
6750b57cec5SDimitry Andric   if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) {
6760b57cec5SDimitry Andric     // Remove any cached AnalysisUsage information.
6770b57cec5SDimitry Andric     AnUsageMap.erase(P);
6780b57cec5SDimitry Andric     delete P;
6790b57cec5SDimitry Andric     return;
6800b57cec5SDimitry Andric   }
6810b57cec5SDimitry Andric 
6820b57cec5SDimitry Andric   AnalysisUsage *AnUsage = findAnalysisUsage(P);
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric   bool checkAnalysis = true;
6850b57cec5SDimitry Andric   while (checkAnalysis) {
6860b57cec5SDimitry Andric     checkAnalysis = false;
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric     const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
6890b57cec5SDimitry Andric     for (const AnalysisID ID : RequiredSet) {
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric       Pass *AnalysisPass = findAnalysisPass(ID);
6920b57cec5SDimitry Andric       if (!AnalysisPass) {
6930b57cec5SDimitry Andric         const PassInfo *PI = findAnalysisPassInfo(ID);
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric         if (!PI) {
6960b57cec5SDimitry Andric           // Pass P is not in the global PassRegistry
6970b57cec5SDimitry Andric           dbgs() << "Pass '"  << P->getPassName() << "' is not initialized." << "\n";
6980b57cec5SDimitry Andric           dbgs() << "Verify if there is a pass dependency cycle." << "\n";
6990b57cec5SDimitry Andric           dbgs() << "Required Passes:" << "\n";
7000b57cec5SDimitry Andric           for (const AnalysisID ID2 : RequiredSet) {
7010b57cec5SDimitry Andric             if (ID == ID2)
7020b57cec5SDimitry Andric               break;
7030b57cec5SDimitry Andric             Pass *AnalysisPass2 = findAnalysisPass(ID2);
7040b57cec5SDimitry Andric             if (AnalysisPass2) {
7050b57cec5SDimitry Andric               dbgs() << "\t" << AnalysisPass2->getPassName() << "\n";
7060b57cec5SDimitry Andric             } else {
7070b57cec5SDimitry Andric               dbgs() << "\t"   << "Error: Required pass not found! Possible causes:"  << "\n";
7080b57cec5SDimitry Andric               dbgs() << "\t\t" << "- Pass misconfiguration (e.g.: missing macros)"    << "\n";
7090b57cec5SDimitry Andric               dbgs() << "\t\t" << "- Corruption of the global PassRegistry"           << "\n";
7100b57cec5SDimitry Andric             }
7110b57cec5SDimitry Andric           }
7120b57cec5SDimitry Andric         }
7130b57cec5SDimitry Andric 
7140b57cec5SDimitry Andric         assert(PI && "Expected required passes to be initialized");
7150b57cec5SDimitry Andric         AnalysisPass = PI->createPass();
7160b57cec5SDimitry Andric         if (P->getPotentialPassManagerType () ==
7170b57cec5SDimitry Andric             AnalysisPass->getPotentialPassManagerType())
7180b57cec5SDimitry Andric           // Schedule analysis pass that is managed by the same pass manager.
7190b57cec5SDimitry Andric           schedulePass(AnalysisPass);
7200b57cec5SDimitry Andric         else if (P->getPotentialPassManagerType () >
7210b57cec5SDimitry Andric                  AnalysisPass->getPotentialPassManagerType()) {
7220b57cec5SDimitry Andric           // Schedule analysis pass that is managed by a new manager.
7230b57cec5SDimitry Andric           schedulePass(AnalysisPass);
7240b57cec5SDimitry Andric           // Recheck analysis passes to ensure that required analyses that
7250b57cec5SDimitry Andric           // are already checked are still available.
7260b57cec5SDimitry Andric           checkAnalysis = true;
7270b57cec5SDimitry Andric         } else
7280b57cec5SDimitry Andric           // Do not schedule this analysis. Lower level analysis
7290b57cec5SDimitry Andric           // passes are run on the fly.
7300b57cec5SDimitry Andric           delete AnalysisPass;
7310b57cec5SDimitry Andric       }
7320b57cec5SDimitry Andric     }
7330b57cec5SDimitry Andric   }
7340b57cec5SDimitry Andric 
7350b57cec5SDimitry Andric   // Now all required passes are available.
7360b57cec5SDimitry Andric   if (ImmutablePass *IP = P->getAsImmutablePass()) {
7370b57cec5SDimitry Andric     // P is a immutable pass and it will be managed by this
7380b57cec5SDimitry Andric     // top level manager. Set up analysis resolver to connect them.
7390b57cec5SDimitry Andric     PMDataManager *DM = getAsPMDataManager();
7400b57cec5SDimitry Andric     AnalysisResolver *AR = new AnalysisResolver(*DM);
7410b57cec5SDimitry Andric     P->setResolver(AR);
7420b57cec5SDimitry Andric     DM->initializeAnalysisImpl(P);
7430b57cec5SDimitry Andric     addImmutablePass(IP);
7440b57cec5SDimitry Andric     DM->recordAvailableAnalysis(IP);
7450b57cec5SDimitry Andric     return;
7460b57cec5SDimitry Andric   }
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric   if (PI && !PI->isAnalysis() && shouldPrintBeforePass(PI->getPassArgument())) {
749fe6060f1SDimitry Andric     Pass *PP =
750fe6060f1SDimitry Andric         P->createPrinterPass(dbgs(), ("*** IR Dump Before " + P->getPassName() +
751fe6060f1SDimitry Andric                                       " (" + PI->getPassArgument() + ") ***")
752fe6060f1SDimitry Andric                                          .str());
7530b57cec5SDimitry Andric     PP->assignPassManager(activeStack, getTopLevelPassManagerType());
7540b57cec5SDimitry Andric   }
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric   // Add the requested pass to the best available pass manager.
7570b57cec5SDimitry Andric   P->assignPassManager(activeStack, getTopLevelPassManagerType());
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric   if (PI && !PI->isAnalysis() && shouldPrintAfterPass(PI->getPassArgument())) {
760fe6060f1SDimitry Andric     Pass *PP =
761fe6060f1SDimitry Andric         P->createPrinterPass(dbgs(), ("*** IR Dump After " + P->getPassName() +
762fe6060f1SDimitry Andric                                       " (" + PI->getPassArgument() + ") ***")
763fe6060f1SDimitry Andric                                          .str());
7640b57cec5SDimitry Andric     PP->assignPassManager(activeStack, getTopLevelPassManagerType());
7650b57cec5SDimitry Andric   }
7660b57cec5SDimitry Andric }
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric /// Find the pass that implements Analysis AID. Search immutable
7690b57cec5SDimitry Andric /// passes and all pass managers. If desired pass is not found
7700b57cec5SDimitry Andric /// then return NULL.
7710b57cec5SDimitry Andric Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
7720b57cec5SDimitry Andric   // For immutable passes we have a direct mapping from ID to pass, so check
7730b57cec5SDimitry Andric   // that first.
7740b57cec5SDimitry Andric   if (Pass *P = ImmutablePassMap.lookup(AID))
7750b57cec5SDimitry Andric     return P;
7760b57cec5SDimitry Andric 
7770b57cec5SDimitry Andric   // Check pass managers
7780b57cec5SDimitry Andric   for (PMDataManager *PassManager : PassManagers)
7790b57cec5SDimitry Andric     if (Pass *P = PassManager->findAnalysisPass(AID, false))
7800b57cec5SDimitry Andric       return P;
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric   // Check other pass managers
7830b57cec5SDimitry Andric   for (PMDataManager *IndirectPassManager : IndirectPassManagers)
7840b57cec5SDimitry Andric     if (Pass *P = IndirectPassManager->findAnalysisPass(AID, false))
7850b57cec5SDimitry Andric       return P;
7860b57cec5SDimitry Andric 
7870b57cec5SDimitry Andric   return nullptr;
7880b57cec5SDimitry Andric }
7890b57cec5SDimitry Andric 
7900b57cec5SDimitry Andric const PassInfo *PMTopLevelManager::findAnalysisPassInfo(AnalysisID AID) const {
7910b57cec5SDimitry Andric   const PassInfo *&PI = AnalysisPassInfos[AID];
7920b57cec5SDimitry Andric   if (!PI)
7930b57cec5SDimitry Andric     PI = PassRegistry::getPassRegistry()->getPassInfo(AID);
7940b57cec5SDimitry Andric   else
7950b57cec5SDimitry Andric     assert(PI == PassRegistry::getPassRegistry()->getPassInfo(AID) &&
7960b57cec5SDimitry Andric            "The pass info pointer changed for an analysis ID!");
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric   return PI;
7990b57cec5SDimitry Andric }
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric void PMTopLevelManager::addImmutablePass(ImmutablePass *P) {
8020b57cec5SDimitry Andric   P->initializePass();
8030b57cec5SDimitry Andric   ImmutablePasses.push_back(P);
8040b57cec5SDimitry Andric 
8050b57cec5SDimitry Andric   // Add this pass to the map from its analysis ID. We clobber any prior runs
8060b57cec5SDimitry Andric   // of the pass in the map so that the last one added is the one found when
8070b57cec5SDimitry Andric   // doing lookups.
8080b57cec5SDimitry Andric   AnalysisID AID = P->getPassID();
8090b57cec5SDimitry Andric   ImmutablePassMap[AID] = P;
8100b57cec5SDimitry Andric 
8110b57cec5SDimitry Andric   // Also add any interfaces implemented by the immutable pass to the map for
8120b57cec5SDimitry Andric   // fast lookup.
8130b57cec5SDimitry Andric   const PassInfo *PassInf = findAnalysisPassInfo(AID);
8140b57cec5SDimitry Andric   assert(PassInf && "Expected all immutable passes to be initialized");
8150b57cec5SDimitry Andric   for (const PassInfo *ImmPI : PassInf->getInterfacesImplemented())
8160b57cec5SDimitry Andric     ImmutablePassMap[ImmPI->getTypeInfo()] = P;
8170b57cec5SDimitry Andric }
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric // Print passes managed by this top level manager.
8200b57cec5SDimitry Andric void PMTopLevelManager::dumpPasses() const {
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric   if (PassDebugging < Structure)
8230b57cec5SDimitry Andric     return;
8240b57cec5SDimitry Andric 
8250b57cec5SDimitry Andric   // Print out the immutable passes
8260fca6ea1SDimitry Andric   for (ImmutablePass *Pass : ImmutablePasses)
8270fca6ea1SDimitry Andric     Pass->dumpPassStructure(0);
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric   // Every class that derives from PMDataManager also derives from Pass
8300b57cec5SDimitry Andric   // (sometimes indirectly), but there's no inheritance relationship
8310b57cec5SDimitry Andric   // between PMDataManager and Pass, so we have to getAsPass to get
8320b57cec5SDimitry Andric   // from a PMDataManager* to a Pass*.
8330b57cec5SDimitry Andric   for (PMDataManager *Manager : PassManagers)
8340b57cec5SDimitry Andric     Manager->getAsPass()->dumpPassStructure(1);
8350b57cec5SDimitry Andric }
8360b57cec5SDimitry Andric 
8370b57cec5SDimitry Andric void PMTopLevelManager::dumpArguments() const {
8380b57cec5SDimitry Andric 
8390b57cec5SDimitry Andric   if (PassDebugging < Arguments)
8400b57cec5SDimitry Andric     return;
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric   dbgs() << "Pass Arguments: ";
8430b57cec5SDimitry Andric   for (ImmutablePass *P : ImmutablePasses)
8440b57cec5SDimitry Andric     if (const PassInfo *PI = findAnalysisPassInfo(P->getPassID())) {
8450b57cec5SDimitry Andric       assert(PI && "Expected all immutable passes to be initialized");
8460b57cec5SDimitry Andric       if (!PI->isAnalysisGroup())
8470b57cec5SDimitry Andric         dbgs() << " -" << PI->getPassArgument();
8480b57cec5SDimitry Andric     }
8490b57cec5SDimitry Andric   for (PMDataManager *PM : PassManagers)
8500b57cec5SDimitry Andric     PM->dumpPassArguments();
8510b57cec5SDimitry Andric   dbgs() << "\n";
8520b57cec5SDimitry Andric }
8530b57cec5SDimitry Andric 
8540b57cec5SDimitry Andric void PMTopLevelManager::initializeAllAnalysisInfo() {
8550b57cec5SDimitry Andric   for (PMDataManager *PM : PassManagers)
8560b57cec5SDimitry Andric     PM->initializeAnalysisInfo();
8570b57cec5SDimitry Andric 
8580b57cec5SDimitry Andric   // Initailize other pass managers
8590b57cec5SDimitry Andric   for (PMDataManager *IPM : IndirectPassManagers)
8600b57cec5SDimitry Andric     IPM->initializeAnalysisInfo();
8610b57cec5SDimitry Andric }
8620b57cec5SDimitry Andric 
8630b57cec5SDimitry Andric /// Destructor
8640b57cec5SDimitry Andric PMTopLevelManager::~PMTopLevelManager() {
8650b57cec5SDimitry Andric   for (PMDataManager *PM : PassManagers)
8660b57cec5SDimitry Andric     delete PM;
8670b57cec5SDimitry Andric 
8680b57cec5SDimitry Andric   for (ImmutablePass *P : ImmutablePasses)
8690b57cec5SDimitry Andric     delete P;
8700b57cec5SDimitry Andric }
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8730b57cec5SDimitry Andric // PMDataManager implementation
8740b57cec5SDimitry Andric 
8750b57cec5SDimitry Andric /// Augement AvailableAnalysis by adding analysis made available by pass P.
8760b57cec5SDimitry Andric void PMDataManager::recordAvailableAnalysis(Pass *P) {
8770b57cec5SDimitry Andric   AnalysisID PI = P->getPassID();
8780b57cec5SDimitry Andric 
8790b57cec5SDimitry Andric   AvailableAnalysis[PI] = P;
8800b57cec5SDimitry Andric 
8810b57cec5SDimitry Andric   assert(!AvailableAnalysis.empty());
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric   // This pass is the current implementation of all of the interfaces it
8840b57cec5SDimitry Andric   // implements as well.
8850b57cec5SDimitry Andric   const PassInfo *PInf = TPM->findAnalysisPassInfo(PI);
8860b57cec5SDimitry Andric   if (!PInf) return;
8870eae32dcSDimitry Andric   for (const PassInfo *PI : PInf->getInterfacesImplemented())
8880eae32dcSDimitry Andric     AvailableAnalysis[PI->getTypeInfo()] = P;
8890b57cec5SDimitry Andric }
8900b57cec5SDimitry Andric 
8910b57cec5SDimitry Andric // Return true if P preserves high level analysis used by other
8920b57cec5SDimitry Andric // passes managed by this manager
8930b57cec5SDimitry Andric bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) {
8940b57cec5SDimitry Andric   AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
8950b57cec5SDimitry Andric   if (AnUsage->getPreservesAll())
8960b57cec5SDimitry Andric     return true;
8970b57cec5SDimitry Andric 
8980b57cec5SDimitry Andric   const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
8990b57cec5SDimitry Andric   for (Pass *P1 : HigherLevelAnalysis) {
9000b57cec5SDimitry Andric     if (P1->getAsImmutablePass() == nullptr &&
9010b57cec5SDimitry Andric         !is_contained(PreservedSet, P1->getPassID()))
9020b57cec5SDimitry Andric       return false;
9030b57cec5SDimitry Andric   }
9040b57cec5SDimitry Andric 
9050b57cec5SDimitry Andric   return true;
9060b57cec5SDimitry Andric }
9070b57cec5SDimitry Andric 
9080b57cec5SDimitry Andric /// verifyPreservedAnalysis -- Verify analysis preserved by pass P.
9090b57cec5SDimitry Andric void PMDataManager::verifyPreservedAnalysis(Pass *P) {
9100b57cec5SDimitry Andric   // Don't do this unless assertions are enabled.
9110b57cec5SDimitry Andric #ifdef NDEBUG
9120b57cec5SDimitry Andric   return;
9130b57cec5SDimitry Andric #endif
9140b57cec5SDimitry Andric   AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
9150b57cec5SDimitry Andric   const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
9160b57cec5SDimitry Andric 
9170b57cec5SDimitry Andric   // Verify preserved analysis
9180b57cec5SDimitry Andric   for (AnalysisID AID : PreservedSet) {
9190b57cec5SDimitry Andric     if (Pass *AP = findAnalysisPass(AID, true)) {
9200b57cec5SDimitry Andric       TimeRegion PassTimer(getPassTimer(AP));
9210b57cec5SDimitry Andric       AP->verifyAnalysis();
9220b57cec5SDimitry Andric     }
9230b57cec5SDimitry Andric   }
9240b57cec5SDimitry Andric }
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric /// Remove Analysis not preserved by Pass P
9270b57cec5SDimitry Andric void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
9280b57cec5SDimitry Andric   AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
9290b57cec5SDimitry Andric   if (AnUsage->getPreservesAll())
9300b57cec5SDimitry Andric     return;
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric   const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
9330b57cec5SDimitry Andric   for (DenseMap<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(),
9340b57cec5SDimitry Andric          E = AvailableAnalysis.end(); I != E; ) {
9350b57cec5SDimitry Andric     DenseMap<AnalysisID, Pass*>::iterator Info = I++;
9360b57cec5SDimitry Andric     if (Info->second->getAsImmutablePass() == nullptr &&
9370b57cec5SDimitry Andric         !is_contained(PreservedSet, Info->first)) {
9380b57cec5SDimitry Andric       // Remove this analysis
9390b57cec5SDimitry Andric       if (PassDebugging >= Details) {
9400b57cec5SDimitry Andric         Pass *S = Info->second;
9410b57cec5SDimitry Andric         dbgs() << " -- '" <<  P->getPassName() << "' is not preserving '";
9420b57cec5SDimitry Andric         dbgs() << S->getPassName() << "'\n";
9430b57cec5SDimitry Andric       }
9440b57cec5SDimitry Andric       AvailableAnalysis.erase(Info);
9450b57cec5SDimitry Andric     }
9460b57cec5SDimitry Andric   }
9470b57cec5SDimitry Andric 
9480b57cec5SDimitry Andric   // Check inherited analysis also. If P is not preserving analysis
9490b57cec5SDimitry Andric   // provided by parent manager then remove it here.
950fe6060f1SDimitry Andric   for (DenseMap<AnalysisID, Pass *> *IA : InheritedAnalysis) {
951fe6060f1SDimitry Andric     if (!IA)
9520b57cec5SDimitry Andric       continue;
9530b57cec5SDimitry Andric 
954fe6060f1SDimitry Andric     for (DenseMap<AnalysisID, Pass *>::iterator I = IA->begin(),
955fe6060f1SDimitry Andric                                                 E = IA->end();
956fe6060f1SDimitry Andric          I != E;) {
9570b57cec5SDimitry Andric       DenseMap<AnalysisID, Pass *>::iterator Info = I++;
9580b57cec5SDimitry Andric       if (Info->second->getAsImmutablePass() == nullptr &&
9590b57cec5SDimitry Andric           !is_contained(PreservedSet, Info->first)) {
9600b57cec5SDimitry Andric         // Remove this analysis
9610b57cec5SDimitry Andric         if (PassDebugging >= Details) {
9620b57cec5SDimitry Andric           Pass *S = Info->second;
9630b57cec5SDimitry Andric           dbgs() << " -- '" <<  P->getPassName() << "' is not preserving '";
9640b57cec5SDimitry Andric           dbgs() << S->getPassName() << "'\n";
9650b57cec5SDimitry Andric         }
966fe6060f1SDimitry Andric         IA->erase(Info);
9670b57cec5SDimitry Andric       }
9680b57cec5SDimitry Andric     }
9690b57cec5SDimitry Andric   }
9700b57cec5SDimitry Andric }
9710b57cec5SDimitry Andric 
9720b57cec5SDimitry Andric /// Remove analysis passes that are not used any longer
9730b57cec5SDimitry Andric void PMDataManager::removeDeadPasses(Pass *P, StringRef Msg,
9740b57cec5SDimitry Andric                                      enum PassDebuggingString DBG_STR) {
9750b57cec5SDimitry Andric 
9760b57cec5SDimitry Andric   SmallVector<Pass *, 12> DeadPasses;
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   // If this is a on the fly manager then it does not have TPM.
9790b57cec5SDimitry Andric   if (!TPM)
9800b57cec5SDimitry Andric     return;
9810b57cec5SDimitry Andric 
9820b57cec5SDimitry Andric   TPM->collectLastUses(DeadPasses, P);
9830b57cec5SDimitry Andric 
9840b57cec5SDimitry Andric   if (PassDebugging >= Details && !DeadPasses.empty()) {
9850b57cec5SDimitry Andric     dbgs() << " -*- '" <<  P->getPassName();
9860b57cec5SDimitry Andric     dbgs() << "' is the last user of following pass instances.";
9870b57cec5SDimitry Andric     dbgs() << " Free these instances\n";
9880b57cec5SDimitry Andric   }
9890b57cec5SDimitry Andric 
9900b57cec5SDimitry Andric   for (Pass *P : DeadPasses)
9910b57cec5SDimitry Andric     freePass(P, Msg, DBG_STR);
9920b57cec5SDimitry Andric }
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric void PMDataManager::freePass(Pass *P, StringRef Msg,
9950b57cec5SDimitry Andric                              enum PassDebuggingString DBG_STR) {
9960b57cec5SDimitry Andric   dumpPassInfo(P, FREEING_MSG, DBG_STR, Msg);
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric   {
9990b57cec5SDimitry Andric     // If the pass crashes releasing memory, remember this.
10000b57cec5SDimitry Andric     PassManagerPrettyStackEntry X(P);
10010b57cec5SDimitry Andric     TimeRegion PassTimer(getPassTimer(P));
10020b57cec5SDimitry Andric 
10030b57cec5SDimitry Andric     P->releaseMemory();
10040b57cec5SDimitry Andric   }
10050b57cec5SDimitry Andric 
10060b57cec5SDimitry Andric   AnalysisID PI = P->getPassID();
10070b57cec5SDimitry Andric   if (const PassInfo *PInf = TPM->findAnalysisPassInfo(PI)) {
10080b57cec5SDimitry Andric     // Remove the pass itself (if it is not already removed).
10090b57cec5SDimitry Andric     AvailableAnalysis.erase(PI);
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric     // Remove all interfaces this pass implements, for which it is also
10120b57cec5SDimitry Andric     // listed as the available implementation.
10130eae32dcSDimitry Andric     for (const PassInfo *PI : PInf->getInterfacesImplemented()) {
10140b57cec5SDimitry Andric       DenseMap<AnalysisID, Pass *>::iterator Pos =
10150eae32dcSDimitry Andric           AvailableAnalysis.find(PI->getTypeInfo());
10160b57cec5SDimitry Andric       if (Pos != AvailableAnalysis.end() && Pos->second == P)
10170b57cec5SDimitry Andric         AvailableAnalysis.erase(Pos);
10180b57cec5SDimitry Andric     }
10190b57cec5SDimitry Andric   }
10200b57cec5SDimitry Andric }
10210b57cec5SDimitry Andric 
10220b57cec5SDimitry Andric /// Add pass P into the PassVector. Update
10230b57cec5SDimitry Andric /// AvailableAnalysis appropriately if ProcessAnalysis is true.
10240b57cec5SDimitry Andric void PMDataManager::add(Pass *P, bool ProcessAnalysis) {
10250b57cec5SDimitry Andric   // This manager is going to manage pass P. Set up analysis resolver
10260b57cec5SDimitry Andric   // to connect them.
10270b57cec5SDimitry Andric   AnalysisResolver *AR = new AnalysisResolver(*this);
10280b57cec5SDimitry Andric   P->setResolver(AR);
10290b57cec5SDimitry Andric 
10300b57cec5SDimitry Andric   // If a FunctionPass F is the last user of ModulePass info M
10310b57cec5SDimitry Andric   // then the F's manager, not F, records itself as a last user of M.
10320b57cec5SDimitry Andric   SmallVector<Pass *, 12> TransferLastUses;
10330b57cec5SDimitry Andric 
10340b57cec5SDimitry Andric   if (!ProcessAnalysis) {
10350b57cec5SDimitry Andric     // Add pass
10360b57cec5SDimitry Andric     PassVector.push_back(P);
10370b57cec5SDimitry Andric     return;
10380b57cec5SDimitry Andric   }
10390b57cec5SDimitry Andric 
10400b57cec5SDimitry Andric   // At the moment, this pass is the last user of all required passes.
10410b57cec5SDimitry Andric   SmallVector<Pass *, 12> LastUses;
10420b57cec5SDimitry Andric   SmallVector<Pass *, 8> UsedPasses;
10430b57cec5SDimitry Andric   SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable;
10440b57cec5SDimitry Andric 
10450b57cec5SDimitry Andric   unsigned PDepth = this->getDepth();
10460b57cec5SDimitry Andric 
10470b57cec5SDimitry Andric   collectRequiredAndUsedAnalyses(UsedPasses, ReqAnalysisNotAvailable, P);
10480b57cec5SDimitry Andric   for (Pass *PUsed : UsedPasses) {
10490b57cec5SDimitry Andric     unsigned RDepth = 0;
10500b57cec5SDimitry Andric 
10510b57cec5SDimitry Andric     assert(PUsed->getResolver() && "Analysis Resolver is not set");
10520b57cec5SDimitry Andric     PMDataManager &DM = PUsed->getResolver()->getPMDataManager();
10530b57cec5SDimitry Andric     RDepth = DM.getDepth();
10540b57cec5SDimitry Andric 
10550b57cec5SDimitry Andric     if (PDepth == RDepth)
10560b57cec5SDimitry Andric       LastUses.push_back(PUsed);
10570b57cec5SDimitry Andric     else if (PDepth > RDepth) {
10580b57cec5SDimitry Andric       // Let the parent claim responsibility of last use
10590b57cec5SDimitry Andric       TransferLastUses.push_back(PUsed);
10600b57cec5SDimitry Andric       // Keep track of higher level analysis used by this manager.
10610b57cec5SDimitry Andric       HigherLevelAnalysis.push_back(PUsed);
10620b57cec5SDimitry Andric     } else
10630b57cec5SDimitry Andric       llvm_unreachable("Unable to accommodate Used Pass");
10640b57cec5SDimitry Andric   }
10650b57cec5SDimitry Andric 
10660b57cec5SDimitry Andric   // Set P as P's last user until someone starts using P.
10670b57cec5SDimitry Andric   // However, if P is a Pass Manager then it does not need
10680b57cec5SDimitry Andric   // to record its last user.
10690b57cec5SDimitry Andric   if (!P->getAsPMDataManager())
10700b57cec5SDimitry Andric     LastUses.push_back(P);
10710b57cec5SDimitry Andric   TPM->setLastUser(LastUses, P);
10720b57cec5SDimitry Andric 
10730b57cec5SDimitry Andric   if (!TransferLastUses.empty()) {
10740b57cec5SDimitry Andric     Pass *My_PM = getAsPass();
10750b57cec5SDimitry Andric     TPM->setLastUser(TransferLastUses, My_PM);
10760b57cec5SDimitry Andric     TransferLastUses.clear();
10770b57cec5SDimitry Andric   }
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric   // Now, take care of required analyses that are not available.
10800b57cec5SDimitry Andric   for (AnalysisID ID : ReqAnalysisNotAvailable) {
10810b57cec5SDimitry Andric     const PassInfo *PI = TPM->findAnalysisPassInfo(ID);
10820b57cec5SDimitry Andric     Pass *AnalysisPass = PI->createPass();
10830b57cec5SDimitry Andric     this->addLowerLevelRequiredPass(P, AnalysisPass);
10840b57cec5SDimitry Andric   }
10850b57cec5SDimitry Andric 
10860b57cec5SDimitry Andric   // Take a note of analysis required and made available by this pass.
10870b57cec5SDimitry Andric   // Remove the analysis not preserved by this pass
10880b57cec5SDimitry Andric   removeNotPreservedAnalysis(P);
10890b57cec5SDimitry Andric   recordAvailableAnalysis(P);
10900b57cec5SDimitry Andric 
10910b57cec5SDimitry Andric   // Add pass
10920b57cec5SDimitry Andric   PassVector.push_back(P);
10930b57cec5SDimitry Andric }
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric 
10960b57cec5SDimitry Andric /// Populate UP with analysis pass that are used or required by
10970b57cec5SDimitry Andric /// pass P and are available. Populate RP_NotAvail with analysis
10980b57cec5SDimitry Andric /// pass that are required by pass P but are not available.
10990b57cec5SDimitry Andric void PMDataManager::collectRequiredAndUsedAnalyses(
11000b57cec5SDimitry Andric     SmallVectorImpl<Pass *> &UP, SmallVectorImpl<AnalysisID> &RP_NotAvail,
11010b57cec5SDimitry Andric     Pass *P) {
11020b57cec5SDimitry Andric   AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric   for (const auto &UsedID : AnUsage->getUsedSet())
11050b57cec5SDimitry Andric     if (Pass *AnalysisPass = findAnalysisPass(UsedID, true))
11060b57cec5SDimitry Andric       UP.push_back(AnalysisPass);
11070b57cec5SDimitry Andric 
11080b57cec5SDimitry Andric   for (const auto &RequiredID : AnUsage->getRequiredSet())
11090b57cec5SDimitry Andric     if (Pass *AnalysisPass = findAnalysisPass(RequiredID, true))
11100b57cec5SDimitry Andric       UP.push_back(AnalysisPass);
11110b57cec5SDimitry Andric     else
11120b57cec5SDimitry Andric       RP_NotAvail.push_back(RequiredID);
11130b57cec5SDimitry Andric }
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric // All Required analyses should be available to the pass as it runs!  Here
11160b57cec5SDimitry Andric // we fill in the AnalysisImpls member of the pass so that it can
11170b57cec5SDimitry Andric // successfully use the getAnalysis() method to retrieve the
11180b57cec5SDimitry Andric // implementations it needs.
11190b57cec5SDimitry Andric //
11200b57cec5SDimitry Andric void PMDataManager::initializeAnalysisImpl(Pass *P) {
11210b57cec5SDimitry Andric   AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
11220b57cec5SDimitry Andric 
11230b57cec5SDimitry Andric   for (const AnalysisID ID : AnUsage->getRequiredSet()) {
11240b57cec5SDimitry Andric     Pass *Impl = findAnalysisPass(ID, true);
11250b57cec5SDimitry Andric     if (!Impl)
11260b57cec5SDimitry Andric       // This may be analysis pass that is initialized on the fly.
11270b57cec5SDimitry Andric       // If that is not the case then it will raise an assert when it is used.
11280b57cec5SDimitry Andric       continue;
11290b57cec5SDimitry Andric     AnalysisResolver *AR = P->getResolver();
11300b57cec5SDimitry Andric     assert(AR && "Analysis Resolver is not set");
11310b57cec5SDimitry Andric     AR->addAnalysisImplsPair(ID, Impl);
11320b57cec5SDimitry Andric   }
11330b57cec5SDimitry Andric }
11340b57cec5SDimitry Andric 
11350b57cec5SDimitry Andric /// Find the pass that implements Analysis AID. If desired pass is not found
11360b57cec5SDimitry Andric /// then return NULL.
11370b57cec5SDimitry Andric Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) {
11380b57cec5SDimitry Andric 
11390b57cec5SDimitry Andric   // Check if AvailableAnalysis map has one entry.
11400b57cec5SDimitry Andric   DenseMap<AnalysisID, Pass*>::const_iterator I =  AvailableAnalysis.find(AID);
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric   if (I != AvailableAnalysis.end())
11430b57cec5SDimitry Andric     return I->second;
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric   // Search Parents through TopLevelManager
11460b57cec5SDimitry Andric   if (SearchParent)
11470b57cec5SDimitry Andric     return TPM->findAnalysisPass(AID);
11480b57cec5SDimitry Andric 
11490b57cec5SDimitry Andric   return nullptr;
11500b57cec5SDimitry Andric }
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric // Print list of passes that are last used by P.
11530b57cec5SDimitry Andric void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{
1154e8d8bef9SDimitry Andric   if (PassDebugging < Details)
1155e8d8bef9SDimitry Andric     return;
11560b57cec5SDimitry Andric 
11570b57cec5SDimitry Andric   SmallVector<Pass *, 12> LUses;
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric   // If this is a on the fly manager then it does not have TPM.
11600b57cec5SDimitry Andric   if (!TPM)
11610b57cec5SDimitry Andric     return;
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric   TPM->collectLastUses(LUses, P);
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric   for (Pass *P : LUses) {
11660b57cec5SDimitry Andric     dbgs() << "--" << std::string(Offset*2, ' ');
11670b57cec5SDimitry Andric     P->dumpPassStructure(0);
11680b57cec5SDimitry Andric   }
11690b57cec5SDimitry Andric }
11700b57cec5SDimitry Andric 
11710b57cec5SDimitry Andric void PMDataManager::dumpPassArguments() const {
11720b57cec5SDimitry Andric   for (Pass *P : PassVector) {
11730b57cec5SDimitry Andric     if (PMDataManager *PMD = P->getAsPMDataManager())
11740b57cec5SDimitry Andric       PMD->dumpPassArguments();
11750b57cec5SDimitry Andric     else
11760b57cec5SDimitry Andric       if (const PassInfo *PI =
11770b57cec5SDimitry Andric             TPM->findAnalysisPassInfo(P->getPassID()))
11780b57cec5SDimitry Andric         if (!PI->isAnalysisGroup())
11790b57cec5SDimitry Andric           dbgs() << " -" << PI->getPassArgument();
11800b57cec5SDimitry Andric   }
11810b57cec5SDimitry Andric }
11820b57cec5SDimitry Andric 
11830b57cec5SDimitry Andric void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1,
11840b57cec5SDimitry Andric                                  enum PassDebuggingString S2,
11850b57cec5SDimitry Andric                                  StringRef Msg) {
11860b57cec5SDimitry Andric   if (PassDebugging < Executions)
11870b57cec5SDimitry Andric     return;
11880b57cec5SDimitry Andric   dbgs() << "[" << std::chrono::system_clock::now() << "] " << (void *)this
11890b57cec5SDimitry Andric          << std::string(getDepth() * 2 + 1, ' ');
11900b57cec5SDimitry Andric   switch (S1) {
11910b57cec5SDimitry Andric   case EXECUTION_MSG:
11920b57cec5SDimitry Andric     dbgs() << "Executing Pass '" << P->getPassName();
11930b57cec5SDimitry Andric     break;
11940b57cec5SDimitry Andric   case MODIFICATION_MSG:
11950b57cec5SDimitry Andric     dbgs() << "Made Modification '" << P->getPassName();
11960b57cec5SDimitry Andric     break;
11970b57cec5SDimitry Andric   case FREEING_MSG:
11980b57cec5SDimitry Andric     dbgs() << " Freeing Pass '" << P->getPassName();
11990b57cec5SDimitry Andric     break;
12000b57cec5SDimitry Andric   default:
12010b57cec5SDimitry Andric     break;
12020b57cec5SDimitry Andric   }
12030b57cec5SDimitry Andric   switch (S2) {
12040b57cec5SDimitry Andric   case ON_FUNCTION_MSG:
12050b57cec5SDimitry Andric     dbgs() << "' on Function '" << Msg << "'...\n";
12060b57cec5SDimitry Andric     break;
12070b57cec5SDimitry Andric   case ON_MODULE_MSG:
12080b57cec5SDimitry Andric     dbgs() << "' on Module '"  << Msg << "'...\n";
12090b57cec5SDimitry Andric     break;
12100b57cec5SDimitry Andric   case ON_REGION_MSG:
12110b57cec5SDimitry Andric     dbgs() << "' on Region '"  << Msg << "'...\n";
12120b57cec5SDimitry Andric     break;
12130b57cec5SDimitry Andric   case ON_LOOP_MSG:
12140b57cec5SDimitry Andric     dbgs() << "' on Loop '" << Msg << "'...\n";
12150b57cec5SDimitry Andric     break;
12160b57cec5SDimitry Andric   case ON_CG_MSG:
12170b57cec5SDimitry Andric     dbgs() << "' on Call Graph Nodes '" << Msg << "'...\n";
12180b57cec5SDimitry Andric     break;
12190b57cec5SDimitry Andric   default:
12200b57cec5SDimitry Andric     break;
12210b57cec5SDimitry Andric   }
12220b57cec5SDimitry Andric }
12230b57cec5SDimitry Andric 
12240b57cec5SDimitry Andric void PMDataManager::dumpRequiredSet(const Pass *P) const {
12250b57cec5SDimitry Andric   if (PassDebugging < Details)
12260b57cec5SDimitry Andric     return;
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric   AnalysisUsage analysisUsage;
12290b57cec5SDimitry Andric   P->getAnalysisUsage(analysisUsage);
12300b57cec5SDimitry Andric   dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet());
12310b57cec5SDimitry Andric }
12320b57cec5SDimitry Andric 
12330b57cec5SDimitry Andric void PMDataManager::dumpPreservedSet(const Pass *P) const {
12340b57cec5SDimitry Andric   if (PassDebugging < Details)
12350b57cec5SDimitry Andric     return;
12360b57cec5SDimitry Andric 
12370b57cec5SDimitry Andric   AnalysisUsage analysisUsage;
12380b57cec5SDimitry Andric   P->getAnalysisUsage(analysisUsage);
12390b57cec5SDimitry Andric   dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet());
12400b57cec5SDimitry Andric }
12410b57cec5SDimitry Andric 
12420b57cec5SDimitry Andric void PMDataManager::dumpUsedSet(const Pass *P) const {
12430b57cec5SDimitry Andric   if (PassDebugging < Details)
12440b57cec5SDimitry Andric     return;
12450b57cec5SDimitry Andric 
12460b57cec5SDimitry Andric   AnalysisUsage analysisUsage;
12470b57cec5SDimitry Andric   P->getAnalysisUsage(analysisUsage);
12480b57cec5SDimitry Andric   dumpAnalysisUsage("Used", P, analysisUsage.getUsedSet());
12490b57cec5SDimitry Andric }
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
12520b57cec5SDimitry Andric                                    const AnalysisUsage::VectorType &Set) const {
12530b57cec5SDimitry Andric   assert(PassDebugging >= Details);
12540b57cec5SDimitry Andric   if (Set.empty())
12550b57cec5SDimitry Andric     return;
12560b57cec5SDimitry Andric   dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:";
12570b57cec5SDimitry Andric   for (unsigned i = 0; i != Set.size(); ++i) {
12580b57cec5SDimitry Andric     if (i) dbgs() << ',';
12590b57cec5SDimitry Andric     const PassInfo *PInf = TPM->findAnalysisPassInfo(Set[i]);
12600b57cec5SDimitry Andric     if (!PInf) {
12610b57cec5SDimitry Andric       // Some preserved passes, such as AliasAnalysis, may not be initialized by
12620b57cec5SDimitry Andric       // all drivers.
12630b57cec5SDimitry Andric       dbgs() << " Uninitialized Pass";
12640b57cec5SDimitry Andric       continue;
12650b57cec5SDimitry Andric     }
12660b57cec5SDimitry Andric     dbgs() << ' ' << PInf->getPassName();
12670b57cec5SDimitry Andric   }
12680b57cec5SDimitry Andric   dbgs() << '\n';
12690b57cec5SDimitry Andric }
12700b57cec5SDimitry Andric 
12710b57cec5SDimitry Andric /// Add RequiredPass into list of lower level passes required by pass P.
12720b57cec5SDimitry Andric /// RequiredPass is run on the fly by Pass Manager when P requests it
12730b57cec5SDimitry Andric /// through getAnalysis interface.
12740b57cec5SDimitry Andric /// This should be handled by specific pass manager.
12750b57cec5SDimitry Andric void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
12760b57cec5SDimitry Andric   if (TPM) {
12770b57cec5SDimitry Andric     TPM->dumpArguments();
12780b57cec5SDimitry Andric     TPM->dumpPasses();
12790b57cec5SDimitry Andric   }
12800b57cec5SDimitry Andric 
12810b57cec5SDimitry Andric   // Module Level pass may required Function Level analysis info
12820b57cec5SDimitry Andric   // (e.g. dominator info). Pass manager uses on the fly function pass manager
12830b57cec5SDimitry Andric   // to provide this on demand. In that case, in Pass manager terminology,
12840b57cec5SDimitry Andric   // module level pass is requiring lower level analysis info managed by
12850b57cec5SDimitry Andric   // lower level pass manager.
12860b57cec5SDimitry Andric 
12870b57cec5SDimitry Andric   // When Pass manager is not able to order required analysis info, Pass manager
12880b57cec5SDimitry Andric   // checks whether any lower level manager will be able to provide this
12890b57cec5SDimitry Andric   // analysis info on demand or not.
12900b57cec5SDimitry Andric #ifndef NDEBUG
12910b57cec5SDimitry Andric   dbgs() << "Unable to schedule '" << RequiredPass->getPassName();
12920b57cec5SDimitry Andric   dbgs() << "' required by '" << P->getPassName() << "'\n";
12930b57cec5SDimitry Andric #endif
12940b57cec5SDimitry Andric   llvm_unreachable("Unable to schedule pass");
12950b57cec5SDimitry Andric }
12960b57cec5SDimitry Andric 
12975ffd83dbSDimitry Andric std::tuple<Pass *, bool> PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI,
12985ffd83dbSDimitry Andric                                                         Function &F) {
12990b57cec5SDimitry Andric   llvm_unreachable("Unable to find on the fly pass");
13000b57cec5SDimitry Andric }
13010b57cec5SDimitry Andric 
13020b57cec5SDimitry Andric // Destructor
13030b57cec5SDimitry Andric PMDataManager::~PMDataManager() {
13040b57cec5SDimitry Andric   for (Pass *P : PassVector)
13050b57cec5SDimitry Andric     delete P;
13060b57cec5SDimitry Andric }
13070b57cec5SDimitry Andric 
13080b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13090b57cec5SDimitry Andric // NOTE: Is this the right place to define this method ?
13100b57cec5SDimitry Andric // getAnalysisIfAvailable - Return analysis result or null if it doesn't exist.
1311e8d8bef9SDimitry Andric Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID) const {
1312e8d8bef9SDimitry Andric   return PM.findAnalysisPass(ID, true);
13130b57cec5SDimitry Andric }
13140b57cec5SDimitry Andric 
13155ffd83dbSDimitry Andric std::tuple<Pass *, bool>
13165ffd83dbSDimitry Andric AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, Function &F) {
13170b57cec5SDimitry Andric   return PM.getOnTheFlyPass(P, AnalysisPI, F);
13180b57cec5SDimitry Andric }
13190b57cec5SDimitry Andric 
13205ffd83dbSDimitry Andric namespace llvm {
13215ffd83dbSDimitry Andric namespace legacy {
13225ffd83dbSDimitry Andric 
13230b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13240b57cec5SDimitry Andric // FunctionPassManager implementation
13250b57cec5SDimitry Andric 
13260b57cec5SDimitry Andric /// Create new Function pass manager
13270b57cec5SDimitry Andric FunctionPassManager::FunctionPassManager(Module *m) : M(m) {
13285ffd83dbSDimitry Andric   FPM = new legacy::FunctionPassManagerImpl();
13290b57cec5SDimitry Andric   // FPM is the top level manager.
13300b57cec5SDimitry Andric   FPM->setTopLevelManager(FPM);
13310b57cec5SDimitry Andric 
13320b57cec5SDimitry Andric   AnalysisResolver *AR = new AnalysisResolver(*FPM);
13330b57cec5SDimitry Andric   FPM->setResolver(AR);
13340b57cec5SDimitry Andric }
13350b57cec5SDimitry Andric 
13360b57cec5SDimitry Andric FunctionPassManager::~FunctionPassManager() {
13370b57cec5SDimitry Andric   delete FPM;
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric void FunctionPassManager::add(Pass *P) {
13410b57cec5SDimitry Andric   FPM->add(P);
13420b57cec5SDimitry Andric }
13430b57cec5SDimitry Andric 
13440b57cec5SDimitry Andric /// run - Execute all of the passes scheduled for execution.  Keep
13450b57cec5SDimitry Andric /// track of whether any of the passes modifies the function, and if
13460b57cec5SDimitry Andric /// so, return true.
13470b57cec5SDimitry Andric ///
13480b57cec5SDimitry Andric bool FunctionPassManager::run(Function &F) {
13490b57cec5SDimitry Andric   handleAllErrors(F.materialize(), [&](ErrorInfoBase &EIB) {
1350349cc55cSDimitry Andric     report_fatal_error(Twine("Error reading bitcode file: ") + EIB.message());
13510b57cec5SDimitry Andric   });
13520b57cec5SDimitry Andric   return FPM->run(F);
13530b57cec5SDimitry Andric }
13540b57cec5SDimitry Andric 
13550b57cec5SDimitry Andric 
13560b57cec5SDimitry Andric /// doInitialization - Run all of the initializers for the function passes.
13570b57cec5SDimitry Andric ///
13580b57cec5SDimitry Andric bool FunctionPassManager::doInitialization() {
13590b57cec5SDimitry Andric   return FPM->doInitialization(*M);
13600b57cec5SDimitry Andric }
13610b57cec5SDimitry Andric 
13620b57cec5SDimitry Andric /// doFinalization - Run all of the finalizers for the function passes.
13630b57cec5SDimitry Andric ///
13640b57cec5SDimitry Andric bool FunctionPassManager::doFinalization() {
13650b57cec5SDimitry Andric   return FPM->doFinalization(*M);
13660b57cec5SDimitry Andric }
13675ffd83dbSDimitry Andric } // namespace legacy
13685ffd83dbSDimitry Andric } // namespace llvm
13690b57cec5SDimitry Andric 
13700b57cec5SDimitry Andric /// cleanup - After running all passes, clean up pass manager cache.
13710b57cec5SDimitry Andric void FPPassManager::cleanup() {
13720b57cec5SDimitry Andric  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
13730b57cec5SDimitry Andric     FunctionPass *FP = getContainedPass(Index);
13740b57cec5SDimitry Andric     AnalysisResolver *AR = FP->getResolver();
13750b57cec5SDimitry Andric     assert(AR && "Analysis Resolver is not set");
13760b57cec5SDimitry Andric     AR->clearAnalysisImpls();
13770b57cec5SDimitry Andric  }
13780b57cec5SDimitry Andric }
13790b57cec5SDimitry Andric 
13800b57cec5SDimitry Andric 
13810b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13820b57cec5SDimitry Andric // FPPassManager implementation
13830b57cec5SDimitry Andric 
13840b57cec5SDimitry Andric char FPPassManager::ID = 0;
13850b57cec5SDimitry Andric /// Print passes managed by this manager
13860b57cec5SDimitry Andric void FPPassManager::dumpPassStructure(unsigned Offset) {
13870b57cec5SDimitry Andric   dbgs().indent(Offset*2) << "FunctionPass Manager\n";
13880b57cec5SDimitry Andric   for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
13890b57cec5SDimitry Andric     FunctionPass *FP = getContainedPass(Index);
13900b57cec5SDimitry Andric     FP->dumpPassStructure(Offset + 1);
13910b57cec5SDimitry Andric     dumpLastUses(FP, Offset+1);
13920b57cec5SDimitry Andric   }
13930b57cec5SDimitry Andric }
13940b57cec5SDimitry Andric 
13950b57cec5SDimitry Andric /// Execute all of the passes scheduled for execution by invoking
13960b57cec5SDimitry Andric /// runOnFunction method.  Keep track of whether any of the passes modifies
13970b57cec5SDimitry Andric /// the function, and if so, return true.
13980b57cec5SDimitry Andric bool FPPassManager::runOnFunction(Function &F) {
13990b57cec5SDimitry Andric   if (F.isDeclaration())
14000b57cec5SDimitry Andric     return false;
14010b57cec5SDimitry Andric 
14020b57cec5SDimitry Andric   bool Changed = false;
14030b57cec5SDimitry Andric   Module &M = *F.getParent();
14040b57cec5SDimitry Andric   // Collect inherited analysis from Module level pass manager.
14050b57cec5SDimitry Andric   populateInheritedAnalysis(TPM->activeStack);
14060b57cec5SDimitry Andric 
14070b57cec5SDimitry Andric   unsigned InstrCount, FunctionSize = 0;
14080b57cec5SDimitry Andric   StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
14090b57cec5SDimitry Andric   bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
14100b57cec5SDimitry Andric   // Collect the initial size of the module.
14110b57cec5SDimitry Andric   if (EmitICRemark) {
14120b57cec5SDimitry Andric     InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
14130b57cec5SDimitry Andric     FunctionSize = F.getInstructionCount();
14140b57cec5SDimitry Andric   }
14150b57cec5SDimitry Andric 
141606c3fb27SDimitry Andric   // Store name outside of loop to avoid redundant calls.
141706c3fb27SDimitry Andric   const StringRef Name = F.getName();
1418*62987288SDimitry Andric   llvm::TimeTraceScope FunctionScope("OptFunction", Name);
14190b57cec5SDimitry Andric 
14200b57cec5SDimitry Andric   for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
14210b57cec5SDimitry Andric     FunctionPass *FP = getContainedPass(Index);
14220b57cec5SDimitry Andric     bool LocalChanged = false;
14230b57cec5SDimitry Andric 
142406c3fb27SDimitry Andric     // Call getPassName only when required. The call itself is fairly cheap, but
142506c3fb27SDimitry Andric     // still virtual and repeated calling adds unnecessary overhead.
142606c3fb27SDimitry Andric     llvm::TimeTraceScope PassScope(
142706c3fb27SDimitry Andric         "RunPass", [FP]() { return std::string(FP->getPassName()); });
14280b57cec5SDimitry Andric 
142906c3fb27SDimitry Andric     dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, Name);
14300b57cec5SDimitry Andric     dumpRequiredSet(FP);
14310b57cec5SDimitry Andric 
14320b57cec5SDimitry Andric     initializeAnalysisImpl(FP);
14330b57cec5SDimitry Andric 
14340b57cec5SDimitry Andric     {
14350b57cec5SDimitry Andric       PassManagerPrettyStackEntry X(FP, F);
14360b57cec5SDimitry Andric       TimeRegion PassTimer(getPassTimer(FP));
1437e8d8bef9SDimitry Andric #ifdef EXPENSIVE_CHECKS
143881ad6265SDimitry Andric       uint64_t RefHash = FP->structuralHash(F);
1439e8d8bef9SDimitry Andric #endif
14400b57cec5SDimitry Andric       LocalChanged |= FP->runOnFunction(F);
1441e8d8bef9SDimitry Andric 
1442e8d8bef9SDimitry Andric #if defined(EXPENSIVE_CHECKS) && !defined(NDEBUG)
144381ad6265SDimitry Andric       if (!LocalChanged && (RefHash != FP->structuralHash(F))) {
1444e8d8bef9SDimitry Andric         llvm::errs() << "Pass modifies its input and doesn't report it: "
1445e8d8bef9SDimitry Andric                      << FP->getPassName() << "\n";
1446e8d8bef9SDimitry Andric         llvm_unreachable("Pass modifies its input and doesn't report it");
1447e8d8bef9SDimitry Andric       }
1448e8d8bef9SDimitry Andric #endif
1449e8d8bef9SDimitry Andric 
14500b57cec5SDimitry Andric       if (EmitICRemark) {
14510b57cec5SDimitry Andric         unsigned NewSize = F.getInstructionCount();
14520b57cec5SDimitry Andric 
14530b57cec5SDimitry Andric         // Update the size of the function, emit a remark, and update the size
14540b57cec5SDimitry Andric         // of the module.
14550b57cec5SDimitry Andric         if (NewSize != FunctionSize) {
14560b57cec5SDimitry Andric           int64_t Delta = static_cast<int64_t>(NewSize) -
14570b57cec5SDimitry Andric                           static_cast<int64_t>(FunctionSize);
14580b57cec5SDimitry Andric           emitInstrCountChangedRemark(FP, M, Delta, InstrCount,
14590b57cec5SDimitry Andric                                       FunctionToInstrCount, &F);
14600b57cec5SDimitry Andric           InstrCount = static_cast<int64_t>(InstrCount) + Delta;
14610b57cec5SDimitry Andric           FunctionSize = NewSize;
14620b57cec5SDimitry Andric         }
14630b57cec5SDimitry Andric       }
14640b57cec5SDimitry Andric     }
14650b57cec5SDimitry Andric 
14660b57cec5SDimitry Andric     Changed |= LocalChanged;
14670b57cec5SDimitry Andric     if (LocalChanged)
146806c3fb27SDimitry Andric       dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, Name);
14690b57cec5SDimitry Andric     dumpPreservedSet(FP);
14700b57cec5SDimitry Andric     dumpUsedSet(FP);
14710b57cec5SDimitry Andric 
14720b57cec5SDimitry Andric     verifyPreservedAnalysis(FP);
1473e8d8bef9SDimitry Andric     if (LocalChanged)
14740b57cec5SDimitry Andric       removeNotPreservedAnalysis(FP);
14750b57cec5SDimitry Andric     recordAvailableAnalysis(FP);
147606c3fb27SDimitry Andric     removeDeadPasses(FP, Name, ON_FUNCTION_MSG);
14770b57cec5SDimitry Andric   }
14780b57cec5SDimitry Andric 
14790b57cec5SDimitry Andric   return Changed;
14800b57cec5SDimitry Andric }
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric bool FPPassManager::runOnModule(Module &M) {
14830b57cec5SDimitry Andric   bool Changed = false;
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric   for (Function &F : M)
14860b57cec5SDimitry Andric     Changed |= runOnFunction(F);
14870b57cec5SDimitry Andric 
14880b57cec5SDimitry Andric   return Changed;
14890b57cec5SDimitry Andric }
14900b57cec5SDimitry Andric 
14910b57cec5SDimitry Andric bool FPPassManager::doInitialization(Module &M) {
14920b57cec5SDimitry Andric   bool Changed = false;
14930b57cec5SDimitry Andric 
14940b57cec5SDimitry Andric   for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
14950b57cec5SDimitry Andric     Changed |= getContainedPass(Index)->doInitialization(M);
14960b57cec5SDimitry Andric 
14970b57cec5SDimitry Andric   return Changed;
14980b57cec5SDimitry Andric }
14990b57cec5SDimitry Andric 
15000b57cec5SDimitry Andric bool FPPassManager::doFinalization(Module &M) {
15010b57cec5SDimitry Andric   bool Changed = false;
15020b57cec5SDimitry Andric 
15030b57cec5SDimitry Andric   for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
15040b57cec5SDimitry Andric     Changed |= getContainedPass(Index)->doFinalization(M);
15050b57cec5SDimitry Andric 
15060b57cec5SDimitry Andric   return Changed;
15070b57cec5SDimitry Andric }
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15100b57cec5SDimitry Andric // MPPassManager implementation
15110b57cec5SDimitry Andric 
15120b57cec5SDimitry Andric /// Execute all of the passes scheduled for execution by invoking
15130b57cec5SDimitry Andric /// runOnModule method.  Keep track of whether any of the passes modifies
15140b57cec5SDimitry Andric /// the module, and if so, return true.
15150b57cec5SDimitry Andric bool
15160b57cec5SDimitry Andric MPPassManager::runOnModule(Module &M) {
15170b57cec5SDimitry Andric   llvm::TimeTraceScope TimeScope("OptModule", M.getName());
15180b57cec5SDimitry Andric 
15190b57cec5SDimitry Andric   bool Changed = false;
15200b57cec5SDimitry Andric 
15210b57cec5SDimitry Andric   // Initialize on-the-fly passes
15220b57cec5SDimitry Andric   for (auto &OnTheFlyManager : OnTheFlyManagers) {
15235ffd83dbSDimitry Andric     legacy::FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
15240b57cec5SDimitry Andric     Changed |= FPP->doInitialization(M);
15250b57cec5SDimitry Andric   }
15260b57cec5SDimitry Andric 
15270b57cec5SDimitry Andric   // Initialize module passes
15280b57cec5SDimitry Andric   for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
15290b57cec5SDimitry Andric     Changed |= getContainedPass(Index)->doInitialization(M);
15300b57cec5SDimitry Andric 
15310b57cec5SDimitry Andric   unsigned InstrCount;
15320b57cec5SDimitry Andric   StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
15330b57cec5SDimitry Andric   bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
15340b57cec5SDimitry Andric   // Collect the initial size of the module.
15350b57cec5SDimitry Andric   if (EmitICRemark)
15360b57cec5SDimitry Andric     InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
15370b57cec5SDimitry Andric 
15380b57cec5SDimitry Andric   for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
15390b57cec5SDimitry Andric     ModulePass *MP = getContainedPass(Index);
15400b57cec5SDimitry Andric     bool LocalChanged = false;
15410b57cec5SDimitry Andric 
15420b57cec5SDimitry Andric     dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier());
15430b57cec5SDimitry Andric     dumpRequiredSet(MP);
15440b57cec5SDimitry Andric 
15450b57cec5SDimitry Andric     initializeAnalysisImpl(MP);
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric     {
15480b57cec5SDimitry Andric       PassManagerPrettyStackEntry X(MP, M);
15490b57cec5SDimitry Andric       TimeRegion PassTimer(getPassTimer(MP));
15500b57cec5SDimitry Andric 
1551e8d8bef9SDimitry Andric #ifdef EXPENSIVE_CHECKS
155281ad6265SDimitry Andric       uint64_t RefHash = MP->structuralHash(M);
1553e8d8bef9SDimitry Andric #endif
1554e8d8bef9SDimitry Andric 
15550b57cec5SDimitry Andric       LocalChanged |= MP->runOnModule(M);
1556e8d8bef9SDimitry Andric 
1557e8d8bef9SDimitry Andric #ifdef EXPENSIVE_CHECKS
155881ad6265SDimitry Andric       assert((LocalChanged || (RefHash == MP->structuralHash(M))) &&
1559e8d8bef9SDimitry Andric              "Pass modifies its input and doesn't report it.");
1560e8d8bef9SDimitry Andric #endif
1561e8d8bef9SDimitry Andric 
15620b57cec5SDimitry Andric       if (EmitICRemark) {
15630b57cec5SDimitry Andric         // Update the size of the module.
15640b57cec5SDimitry Andric         unsigned ModuleCount = M.getInstructionCount();
15650b57cec5SDimitry Andric         if (ModuleCount != InstrCount) {
15660b57cec5SDimitry Andric           int64_t Delta = static_cast<int64_t>(ModuleCount) -
15670b57cec5SDimitry Andric                           static_cast<int64_t>(InstrCount);
15680b57cec5SDimitry Andric           emitInstrCountChangedRemark(MP, M, Delta, InstrCount,
15690b57cec5SDimitry Andric                                       FunctionToInstrCount);
15700b57cec5SDimitry Andric           InstrCount = ModuleCount;
15710b57cec5SDimitry Andric         }
15720b57cec5SDimitry Andric       }
15730b57cec5SDimitry Andric     }
15740b57cec5SDimitry Andric 
15750b57cec5SDimitry Andric     Changed |= LocalChanged;
15760b57cec5SDimitry Andric     if (LocalChanged)
15770b57cec5SDimitry Andric       dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
15780b57cec5SDimitry Andric                    M.getModuleIdentifier());
15790b57cec5SDimitry Andric     dumpPreservedSet(MP);
15800b57cec5SDimitry Andric     dumpUsedSet(MP);
15810b57cec5SDimitry Andric 
15820b57cec5SDimitry Andric     verifyPreservedAnalysis(MP);
1583e8d8bef9SDimitry Andric     if (LocalChanged)
15840b57cec5SDimitry Andric       removeNotPreservedAnalysis(MP);
15850b57cec5SDimitry Andric     recordAvailableAnalysis(MP);
15860b57cec5SDimitry Andric     removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG);
15870b57cec5SDimitry Andric   }
15880b57cec5SDimitry Andric 
15890b57cec5SDimitry Andric   // Finalize module passes
15900b57cec5SDimitry Andric   for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
15910b57cec5SDimitry Andric     Changed |= getContainedPass(Index)->doFinalization(M);
15920b57cec5SDimitry Andric 
15930b57cec5SDimitry Andric   // Finalize on-the-fly passes
15940b57cec5SDimitry Andric   for (auto &OnTheFlyManager : OnTheFlyManagers) {
15955ffd83dbSDimitry Andric     legacy::FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
15960b57cec5SDimitry Andric     // We don't know when is the last time an on-the-fly pass is run,
15970b57cec5SDimitry Andric     // so we need to releaseMemory / finalize here
15980b57cec5SDimitry Andric     FPP->releaseMemoryOnTheFly();
15990b57cec5SDimitry Andric     Changed |= FPP->doFinalization(M);
16000b57cec5SDimitry Andric   }
16010b57cec5SDimitry Andric 
16020b57cec5SDimitry Andric   return Changed;
16030b57cec5SDimitry Andric }
16040b57cec5SDimitry Andric 
16050b57cec5SDimitry Andric /// Add RequiredPass into list of lower level passes required by pass P.
16060b57cec5SDimitry Andric /// RequiredPass is run on the fly by Pass Manager when P requests it
16070b57cec5SDimitry Andric /// through getAnalysis interface.
16080b57cec5SDimitry Andric void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
1609480093f4SDimitry Andric   assert(RequiredPass && "No required pass?");
16100b57cec5SDimitry Andric   assert(P->getPotentialPassManagerType() == PMT_ModulePassManager &&
16110b57cec5SDimitry Andric          "Unable to handle Pass that requires lower level Analysis pass");
16120b57cec5SDimitry Andric   assert((P->getPotentialPassManagerType() <
16130b57cec5SDimitry Andric           RequiredPass->getPotentialPassManagerType()) &&
16140b57cec5SDimitry Andric          "Unable to handle Pass that requires lower level Analysis pass");
16150b57cec5SDimitry Andric 
16165ffd83dbSDimitry Andric   legacy::FunctionPassManagerImpl *FPP = OnTheFlyManagers[P];
16170b57cec5SDimitry Andric   if (!FPP) {
16185ffd83dbSDimitry Andric     FPP = new legacy::FunctionPassManagerImpl();
16190b57cec5SDimitry Andric     // FPP is the top level manager.
16200b57cec5SDimitry Andric     FPP->setTopLevelManager(FPP);
16210b57cec5SDimitry Andric 
16220b57cec5SDimitry Andric     OnTheFlyManagers[P] = FPP;
16230b57cec5SDimitry Andric   }
16240b57cec5SDimitry Andric   const PassInfo *RequiredPassPI =
16250b57cec5SDimitry Andric       TPM->findAnalysisPassInfo(RequiredPass->getPassID());
16260b57cec5SDimitry Andric 
16270b57cec5SDimitry Andric   Pass *FoundPass = nullptr;
16280b57cec5SDimitry Andric   if (RequiredPassPI && RequiredPassPI->isAnalysis()) {
16290b57cec5SDimitry Andric     FoundPass =
16300b57cec5SDimitry Andric       ((PMTopLevelManager*)FPP)->findAnalysisPass(RequiredPass->getPassID());
16310b57cec5SDimitry Andric   }
16320b57cec5SDimitry Andric   if (!FoundPass) {
16330b57cec5SDimitry Andric     FoundPass = RequiredPass;
16340b57cec5SDimitry Andric     // This should be guaranteed to add RequiredPass to the passmanager given
16350b57cec5SDimitry Andric     // that we checked for an available analysis above.
16360b57cec5SDimitry Andric     FPP->add(RequiredPass);
16370b57cec5SDimitry Andric   }
16380b57cec5SDimitry Andric   // Register P as the last user of FoundPass or RequiredPass.
16390b57cec5SDimitry Andric   SmallVector<Pass *, 1> LU;
16400b57cec5SDimitry Andric   LU.push_back(FoundPass);
16410b57cec5SDimitry Andric   FPP->setLastUser(LU,  P);
16420b57cec5SDimitry Andric }
16430b57cec5SDimitry Andric 
16440b57cec5SDimitry Andric /// Return function pass corresponding to PassInfo PI, that is
16450b57cec5SDimitry Andric /// required by module pass MP. Instantiate analysis pass, by using
16460b57cec5SDimitry Andric /// its runOnFunction() for function F.
16475ffd83dbSDimitry Andric std::tuple<Pass *, bool> MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI,
16485ffd83dbSDimitry Andric                                                         Function &F) {
16495ffd83dbSDimitry Andric   legacy::FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP];
16500b57cec5SDimitry Andric   assert(FPP && "Unable to find on the fly pass");
16510b57cec5SDimitry Andric 
16520b57cec5SDimitry Andric   FPP->releaseMemoryOnTheFly();
16535ffd83dbSDimitry Andric   bool Changed = FPP->run(F);
16545ffd83dbSDimitry Andric   return std::make_tuple(((PMTopLevelManager *)FPP)->findAnalysisPass(PI),
16555ffd83dbSDimitry Andric                          Changed);
16560b57cec5SDimitry Andric }
16570b57cec5SDimitry Andric 
16585ffd83dbSDimitry Andric namespace llvm {
16595ffd83dbSDimitry Andric namespace legacy {
16600b57cec5SDimitry Andric 
16610b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16620b57cec5SDimitry Andric // PassManager implementation
16630b57cec5SDimitry Andric 
16640b57cec5SDimitry Andric /// Create new pass manager
16650b57cec5SDimitry Andric PassManager::PassManager() {
16660b57cec5SDimitry Andric   PM = new PassManagerImpl();
16670b57cec5SDimitry Andric   // PM is the top level manager
16680b57cec5SDimitry Andric   PM->setTopLevelManager(PM);
16690b57cec5SDimitry Andric }
16700b57cec5SDimitry Andric 
16710b57cec5SDimitry Andric PassManager::~PassManager() {
16720b57cec5SDimitry Andric   delete PM;
16730b57cec5SDimitry Andric }
16740b57cec5SDimitry Andric 
16750b57cec5SDimitry Andric void PassManager::add(Pass *P) {
16760b57cec5SDimitry Andric   PM->add(P);
16770b57cec5SDimitry Andric }
16780b57cec5SDimitry Andric 
16790b57cec5SDimitry Andric /// run - Execute all of the passes scheduled for execution.  Keep track of
16800b57cec5SDimitry Andric /// whether any of the passes modifies the module, and if so, return true.
16810b57cec5SDimitry Andric bool PassManager::run(Module &M) {
16820b57cec5SDimitry Andric   return PM->run(M);
16830b57cec5SDimitry Andric }
16845ffd83dbSDimitry Andric } // namespace legacy
16855ffd83dbSDimitry Andric } // namespace llvm
16860b57cec5SDimitry Andric 
16870b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16880b57cec5SDimitry Andric // PMStack implementation
16890b57cec5SDimitry Andric //
16900b57cec5SDimitry Andric 
16910b57cec5SDimitry Andric // Pop Pass Manager from the stack and clear its analysis info.
16920b57cec5SDimitry Andric void PMStack::pop() {
16930b57cec5SDimitry Andric 
16940b57cec5SDimitry Andric   PMDataManager *Top = this->top();
16950b57cec5SDimitry Andric   Top->initializeAnalysisInfo();
16960b57cec5SDimitry Andric 
16970b57cec5SDimitry Andric   S.pop_back();
16980b57cec5SDimitry Andric }
16990b57cec5SDimitry Andric 
17000b57cec5SDimitry Andric // Push PM on the stack and set its top level manager.
17010b57cec5SDimitry Andric void PMStack::push(PMDataManager *PM) {
17020b57cec5SDimitry Andric   assert(PM && "Unable to push. Pass Manager expected");
17030b57cec5SDimitry Andric   assert(PM->getDepth()==0 && "Pass Manager depth set too early");
17040b57cec5SDimitry Andric 
17050b57cec5SDimitry Andric   if (!this->empty()) {
17060b57cec5SDimitry Andric     assert(PM->getPassManagerType() > this->top()->getPassManagerType()
17070b57cec5SDimitry Andric            && "pushing bad pass manager to PMStack");
17080b57cec5SDimitry Andric     PMTopLevelManager *TPM = this->top()->getTopLevelManager();
17090b57cec5SDimitry Andric 
17100b57cec5SDimitry Andric     assert(TPM && "Unable to find top level manager");
17110b57cec5SDimitry Andric     TPM->addIndirectPassManager(PM);
17120b57cec5SDimitry Andric     PM->setTopLevelManager(TPM);
17130b57cec5SDimitry Andric     PM->setDepth(this->top()->getDepth()+1);
17140b57cec5SDimitry Andric   } else {
17150b57cec5SDimitry Andric     assert((PM->getPassManagerType() == PMT_ModulePassManager
17160b57cec5SDimitry Andric            || PM->getPassManagerType() == PMT_FunctionPassManager)
17170b57cec5SDimitry Andric            && "pushing bad pass manager to PMStack");
17180b57cec5SDimitry Andric     PM->setDepth(1);
17190b57cec5SDimitry Andric   }
17200b57cec5SDimitry Andric 
17210b57cec5SDimitry Andric   S.push_back(PM);
17220b57cec5SDimitry Andric }
17230b57cec5SDimitry Andric 
17240b57cec5SDimitry Andric // Dump content of the pass manager stack.
17250b57cec5SDimitry Andric LLVM_DUMP_METHOD void PMStack::dump() const {
17260b57cec5SDimitry Andric   for (PMDataManager *Manager : S)
17270b57cec5SDimitry Andric     dbgs() << Manager->getAsPass()->getPassName() << ' ';
17280b57cec5SDimitry Andric 
17290b57cec5SDimitry Andric   if (!S.empty())
17300b57cec5SDimitry Andric     dbgs() << '\n';
17310b57cec5SDimitry Andric }
17320b57cec5SDimitry Andric 
17330b57cec5SDimitry Andric /// Find appropriate Module Pass Manager in the PM Stack and
17340b57cec5SDimitry Andric /// add self into that manager.
17350b57cec5SDimitry Andric void ModulePass::assignPassManager(PMStack &PMS,
17360b57cec5SDimitry Andric                                    PassManagerType PreferredType) {
17370b57cec5SDimitry Andric   // Find Module Pass Manager
1738480093f4SDimitry Andric   PassManagerType T;
1739480093f4SDimitry Andric   while ((T = PMS.top()->getPassManagerType()) > PMT_ModulePassManager &&
1740480093f4SDimitry Andric          T != PreferredType)
1741480093f4SDimitry Andric     PMS.pop();
17420b57cec5SDimitry Andric   PMS.top()->add(this);
17430b57cec5SDimitry Andric }
17440b57cec5SDimitry Andric 
17450b57cec5SDimitry Andric /// Find appropriate Function Pass Manager or Call Graph Pass Manager
17460b57cec5SDimitry Andric /// in the PM Stack and add self into that manager.
17470b57cec5SDimitry Andric void FunctionPass::assignPassManager(PMStack &PMS,
1748480093f4SDimitry Andric                                      PassManagerType /*PreferredType*/) {
17490b57cec5SDimitry Andric   // Find Function Pass Manager
1750480093f4SDimitry Andric   PMDataManager *PM;
1751480093f4SDimitry Andric   while (PM = PMS.top(), PM->getPassManagerType() > PMT_FunctionPassManager)
17520b57cec5SDimitry Andric     PMS.pop();
17530b57cec5SDimitry Andric 
17540b57cec5SDimitry Andric   // Create new Function Pass Manager if needed.
1755480093f4SDimitry Andric   if (PM->getPassManagerType() != PMT_FunctionPassManager) {
17560b57cec5SDimitry Andric     // [1] Create new Function Pass Manager
1757480093f4SDimitry Andric     auto *FPP = new FPPassManager;
17580b57cec5SDimitry Andric     FPP->populateInheritedAnalysis(PMS);
17590b57cec5SDimitry Andric 
17600b57cec5SDimitry Andric     // [2] Set up new manager's top level manager
1761480093f4SDimitry Andric     PM->getTopLevelManager()->addIndirectPassManager(FPP);
17620b57cec5SDimitry Andric 
17630b57cec5SDimitry Andric     // [3] Assign manager to manage this new manager. This may create
17640b57cec5SDimitry Andric     // and push new managers into PMS
1765480093f4SDimitry Andric     FPP->assignPassManager(PMS, PM->getPassManagerType());
17660b57cec5SDimitry Andric 
17670b57cec5SDimitry Andric     // [4] Push new manager into PMS
17680b57cec5SDimitry Andric     PMS.push(FPP);
1769480093f4SDimitry Andric     PM = FPP;
17700b57cec5SDimitry Andric   }
17710b57cec5SDimitry Andric 
17720b57cec5SDimitry Andric   // Assign FPP as the manager of this pass.
1773480093f4SDimitry Andric   PM->add(this);
17740b57cec5SDimitry Andric }
17750b57cec5SDimitry Andric 
177681ad6265SDimitry Andric legacy::PassManagerBase::~PassManagerBase() = default;
1777