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