17330f729Sjoerg //===- LegacyPassManager.cpp - LLVM Pass Infrastructure Implementation ----===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements the legacy LLVM Pass Manager infrastructure.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg
137330f729Sjoerg #include "llvm/IR/LegacyPassManager.h"
147330f729Sjoerg #include "llvm/ADT/MapVector.h"
157330f729Sjoerg #include "llvm/ADT/Statistic.h"
167330f729Sjoerg #include "llvm/IR/DiagnosticInfo.h"
177330f729Sjoerg #include "llvm/IR/IRPrintingPasses.h"
187330f729Sjoerg #include "llvm/IR/LLVMContext.h"
197330f729Sjoerg #include "llvm/IR/LegacyPassManagers.h"
207330f729Sjoerg #include "llvm/IR/LegacyPassNameParser.h"
217330f729Sjoerg #include "llvm/IR/Module.h"
227330f729Sjoerg #include "llvm/IR/PassTimingInfo.h"
23*82d56013Sjoerg #include "llvm/IR/PrintPasses.h"
24*82d56013Sjoerg #include "llvm/IR/StructuralHash.h"
257330f729Sjoerg #include "llvm/Support/Chrono.h"
267330f729Sjoerg #include "llvm/Support/CommandLine.h"
277330f729Sjoerg #include "llvm/Support/Debug.h"
287330f729Sjoerg #include "llvm/Support/Error.h"
297330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
307330f729Sjoerg #include "llvm/Support/ManagedStatic.h"
317330f729Sjoerg #include "llvm/Support/Mutex.h"
327330f729Sjoerg #include "llvm/Support/TimeProfiler.h"
337330f729Sjoerg #include "llvm/Support/Timer.h"
347330f729Sjoerg #include "llvm/Support/raw_ostream.h"
357330f729Sjoerg #include <algorithm>
367330f729Sjoerg #include <unordered_set>
377330f729Sjoerg using namespace llvm;
387330f729Sjoerg
397330f729Sjoerg // See PassManagers.h for Pass Manager infrastructure overview.
407330f729Sjoerg
417330f729Sjoerg //===----------------------------------------------------------------------===//
427330f729Sjoerg // Pass debugging information. Often it is useful to find out what pass is
437330f729Sjoerg // running when a crash occurs in a utility. When this library is compiled with
447330f729Sjoerg // debugging on, a command line option (--debug-pass) is enabled that causes the
457330f729Sjoerg // pass name to be printed before it executes.
467330f729Sjoerg //
477330f729Sjoerg
487330f729Sjoerg namespace {
497330f729Sjoerg // Different debug levels that can be enabled...
507330f729Sjoerg enum PassDebugLevel {
517330f729Sjoerg Disabled, Arguments, Structure, Executions, Details
527330f729Sjoerg };
53*82d56013Sjoerg } // namespace
547330f729Sjoerg
55*82d56013Sjoerg static cl::opt<enum PassDebugLevel> PassDebugging(
56*82d56013Sjoerg "debug-pass", cl::Hidden,
57*82d56013Sjoerg cl::desc("Print legacy PassManager debugging information"),
58*82d56013Sjoerg cl::values(clEnumVal(Disabled, "disable debug output"),
597330f729Sjoerg clEnumVal(Arguments, "print pass arguments to pass to 'opt'"),
607330f729Sjoerg clEnumVal(Structure, "print pass structure before run()"),
617330f729Sjoerg clEnumVal(Executions, "print pass name before it is executed"),
627330f729Sjoerg clEnumVal(Details, "print pass details when it is executed")));
637330f729Sjoerg
647330f729Sjoerg /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
657330f729Sjoerg /// or higher is specified.
isPassDebuggingExecutionsOrMore() const667330f729Sjoerg bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
677330f729Sjoerg return PassDebugging >= Executions;
687330f729Sjoerg }
697330f729Sjoerg
initSizeRemarkInfo(Module & M,StringMap<std::pair<unsigned,unsigned>> & FunctionToInstrCount)707330f729Sjoerg unsigned PMDataManager::initSizeRemarkInfo(
717330f729Sjoerg Module &M, StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount) {
727330f729Sjoerg // Only calculate getInstructionCount if the size-info remark is requested.
737330f729Sjoerg unsigned InstrCount = 0;
747330f729Sjoerg
757330f729Sjoerg // Collect instruction counts for every function. We'll use this to emit
767330f729Sjoerg // per-function size remarks later.
777330f729Sjoerg for (Function &F : M) {
787330f729Sjoerg unsigned FCount = F.getInstructionCount();
797330f729Sjoerg
807330f729Sjoerg // Insert a record into FunctionToInstrCount keeping track of the current
817330f729Sjoerg // size of the function as the first member of a pair. Set the second
827330f729Sjoerg // member to 0; if the function is deleted by the pass, then when we get
837330f729Sjoerg // here, we'll be able to let the user know that F no longer contributes to
847330f729Sjoerg // the module.
857330f729Sjoerg FunctionToInstrCount[F.getName().str()] =
867330f729Sjoerg std::pair<unsigned, unsigned>(FCount, 0);
877330f729Sjoerg InstrCount += FCount;
887330f729Sjoerg }
897330f729Sjoerg return InstrCount;
907330f729Sjoerg }
917330f729Sjoerg
emitInstrCountChangedRemark(Pass * P,Module & M,int64_t Delta,unsigned CountBefore,StringMap<std::pair<unsigned,unsigned>> & FunctionToInstrCount,Function * F)927330f729Sjoerg void PMDataManager::emitInstrCountChangedRemark(
937330f729Sjoerg Pass *P, Module &M, int64_t Delta, unsigned CountBefore,
947330f729Sjoerg StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount,
957330f729Sjoerg Function *F) {
967330f729Sjoerg // If it's a pass manager, don't emit a remark. (This hinges on the assumption
977330f729Sjoerg // that the only passes that return non-null with getAsPMDataManager are pass
987330f729Sjoerg // managers.) The reason we have to do this is to avoid emitting remarks for
997330f729Sjoerg // CGSCC passes.
1007330f729Sjoerg if (P->getAsPMDataManager())
1017330f729Sjoerg return;
1027330f729Sjoerg
1037330f729Sjoerg // Set to true if this isn't a module pass or CGSCC pass.
1047330f729Sjoerg bool CouldOnlyImpactOneFunction = (F != nullptr);
1057330f729Sjoerg
1067330f729Sjoerg // Helper lambda that updates the changes to the size of some function.
1077330f729Sjoerg auto UpdateFunctionChanges =
1087330f729Sjoerg [&FunctionToInstrCount](Function &MaybeChangedFn) {
1097330f729Sjoerg // Update the total module count.
1107330f729Sjoerg unsigned FnSize = MaybeChangedFn.getInstructionCount();
1117330f729Sjoerg auto It = FunctionToInstrCount.find(MaybeChangedFn.getName());
1127330f729Sjoerg
1137330f729Sjoerg // If we created a new function, then we need to add it to the map and
1147330f729Sjoerg // say that it changed from 0 instructions to FnSize.
1157330f729Sjoerg if (It == FunctionToInstrCount.end()) {
1167330f729Sjoerg FunctionToInstrCount[MaybeChangedFn.getName()] =
1177330f729Sjoerg std::pair<unsigned, unsigned>(0, FnSize);
1187330f729Sjoerg return;
1197330f729Sjoerg }
1207330f729Sjoerg // Insert the new function size into the second member of the pair. This
1217330f729Sjoerg // tells us whether or not this function changed in size.
1227330f729Sjoerg It->second.second = FnSize;
1237330f729Sjoerg };
1247330f729Sjoerg
1257330f729Sjoerg // We need to initially update all of the function sizes.
1267330f729Sjoerg // If no function was passed in, then we're either a module pass or an
1277330f729Sjoerg // CGSCC pass.
1287330f729Sjoerg if (!CouldOnlyImpactOneFunction)
1297330f729Sjoerg std::for_each(M.begin(), M.end(), UpdateFunctionChanges);
1307330f729Sjoerg else
1317330f729Sjoerg UpdateFunctionChanges(*F);
1327330f729Sjoerg
1337330f729Sjoerg // Do we have a function we can use to emit a remark?
1347330f729Sjoerg if (!CouldOnlyImpactOneFunction) {
1357330f729Sjoerg // We need a function containing at least one basic block in order to output
1367330f729Sjoerg // remarks. Since it's possible that the first function in the module
1377330f729Sjoerg // doesn't actually contain a basic block, we have to go and find one that's
1387330f729Sjoerg // suitable for emitting remarks.
139*82d56013Sjoerg auto It = llvm::find_if(M, [](const Function &Fn) { return !Fn.empty(); });
1407330f729Sjoerg
1417330f729Sjoerg // Didn't find a function. Quit.
1427330f729Sjoerg if (It == M.end())
1437330f729Sjoerg return;
1447330f729Sjoerg
1457330f729Sjoerg // We found a function containing at least one basic block.
1467330f729Sjoerg F = &*It;
1477330f729Sjoerg }
1487330f729Sjoerg int64_t CountAfter = static_cast<int64_t>(CountBefore) + Delta;
1497330f729Sjoerg BasicBlock &BB = *F->begin();
1507330f729Sjoerg OptimizationRemarkAnalysis R("size-info", "IRSizeChange",
1517330f729Sjoerg DiagnosticLocation(), &BB);
1527330f729Sjoerg // FIXME: Move ore namespace to DiagnosticInfo so that we can use it. This
1537330f729Sjoerg // would let us use NV instead of DiagnosticInfoOptimizationBase::Argument.
1547330f729Sjoerg R << DiagnosticInfoOptimizationBase::Argument("Pass", P->getPassName())
1557330f729Sjoerg << ": IR instruction count changed from "
1567330f729Sjoerg << DiagnosticInfoOptimizationBase::Argument("IRInstrsBefore", CountBefore)
1577330f729Sjoerg << " to "
1587330f729Sjoerg << DiagnosticInfoOptimizationBase::Argument("IRInstrsAfter", CountAfter)
1597330f729Sjoerg << "; Delta: "
1607330f729Sjoerg << DiagnosticInfoOptimizationBase::Argument("DeltaInstrCount", Delta);
1617330f729Sjoerg F->getContext().diagnose(R); // Not using ORE for layering reasons.
1627330f729Sjoerg
1637330f729Sjoerg // Emit per-function size change remarks separately.
1647330f729Sjoerg std::string PassName = P->getPassName().str();
1657330f729Sjoerg
1667330f729Sjoerg // Helper lambda that emits a remark when the size of a function has changed.
1677330f729Sjoerg auto EmitFunctionSizeChangedRemark = [&FunctionToInstrCount, &F, &BB,
168*82d56013Sjoerg &PassName](StringRef Fname) {
1697330f729Sjoerg unsigned FnCountBefore, FnCountAfter;
1707330f729Sjoerg std::pair<unsigned, unsigned> &Change = FunctionToInstrCount[Fname];
1717330f729Sjoerg std::tie(FnCountBefore, FnCountAfter) = Change;
1727330f729Sjoerg int64_t FnDelta = static_cast<int64_t>(FnCountAfter) -
1737330f729Sjoerg static_cast<int64_t>(FnCountBefore);
1747330f729Sjoerg
1757330f729Sjoerg if (FnDelta == 0)
1767330f729Sjoerg return;
1777330f729Sjoerg
1787330f729Sjoerg // FIXME: We shouldn't use BB for the location here. Unfortunately, because
1797330f729Sjoerg // the function that we're looking at could have been deleted, we can't use
1807330f729Sjoerg // it for the source location. We *want* remarks when a function is deleted
1817330f729Sjoerg // though, so we're kind of stuck here as is. (This remark, along with the
1827330f729Sjoerg // whole-module size change remarks really ought not to have source
1837330f729Sjoerg // locations at all.)
1847330f729Sjoerg OptimizationRemarkAnalysis FR("size-info", "FunctionIRSizeChange",
1857330f729Sjoerg DiagnosticLocation(), &BB);
1867330f729Sjoerg FR << DiagnosticInfoOptimizationBase::Argument("Pass", PassName)
1877330f729Sjoerg << ": Function: "
1887330f729Sjoerg << DiagnosticInfoOptimizationBase::Argument("Function", Fname)
1897330f729Sjoerg << ": IR instruction count changed from "
1907330f729Sjoerg << DiagnosticInfoOptimizationBase::Argument("IRInstrsBefore",
1917330f729Sjoerg FnCountBefore)
1927330f729Sjoerg << " to "
1937330f729Sjoerg << DiagnosticInfoOptimizationBase::Argument("IRInstrsAfter",
1947330f729Sjoerg FnCountAfter)
1957330f729Sjoerg << "; Delta: "
1967330f729Sjoerg << DiagnosticInfoOptimizationBase::Argument("DeltaInstrCount", FnDelta);
1977330f729Sjoerg F->getContext().diagnose(FR);
1987330f729Sjoerg
1997330f729Sjoerg // Update the function size.
2007330f729Sjoerg Change.first = FnCountAfter;
2017330f729Sjoerg };
2027330f729Sjoerg
2037330f729Sjoerg // Are we looking at more than one function? If so, emit remarks for all of
2047330f729Sjoerg // the functions in the module. Otherwise, only emit one remark.
2057330f729Sjoerg if (!CouldOnlyImpactOneFunction)
2067330f729Sjoerg std::for_each(FunctionToInstrCount.keys().begin(),
2077330f729Sjoerg FunctionToInstrCount.keys().end(),
2087330f729Sjoerg EmitFunctionSizeChangedRemark);
2097330f729Sjoerg else
2107330f729Sjoerg EmitFunctionSizeChangedRemark(F->getName().str());
2117330f729Sjoerg }
2127330f729Sjoerg
print(raw_ostream & OS) const2137330f729Sjoerg void PassManagerPrettyStackEntry::print(raw_ostream &OS) const {
2147330f729Sjoerg if (!V && !M)
2157330f729Sjoerg OS << "Releasing pass '";
2167330f729Sjoerg else
2177330f729Sjoerg OS << "Running pass '";
2187330f729Sjoerg
2197330f729Sjoerg OS << P->getPassName() << "'";
2207330f729Sjoerg
2217330f729Sjoerg if (M) {
2227330f729Sjoerg OS << " on module '" << M->getModuleIdentifier() << "'.\n";
2237330f729Sjoerg return;
2247330f729Sjoerg }
2257330f729Sjoerg if (!V) {
2267330f729Sjoerg OS << '\n';
2277330f729Sjoerg return;
2287330f729Sjoerg }
2297330f729Sjoerg
2307330f729Sjoerg OS << " on ";
2317330f729Sjoerg if (isa<Function>(V))
2327330f729Sjoerg OS << "function";
2337330f729Sjoerg else if (isa<BasicBlock>(V))
2347330f729Sjoerg OS << "basic block";
2357330f729Sjoerg else
2367330f729Sjoerg OS << "value";
2377330f729Sjoerg
2387330f729Sjoerg OS << " '";
2397330f729Sjoerg V->printAsOperand(OS, /*PrintType=*/false, M);
2407330f729Sjoerg OS << "'\n";
2417330f729Sjoerg }
2427330f729Sjoerg
2437330f729Sjoerg namespace llvm {
2447330f729Sjoerg namespace legacy {
debugPassSpecified()245*82d56013Sjoerg bool debugPassSpecified() { return PassDebugging != Disabled; }
246*82d56013Sjoerg
2477330f729Sjoerg //===----------------------------------------------------------------------===//
2487330f729Sjoerg // FunctionPassManagerImpl
2497330f729Sjoerg //
2507330f729Sjoerg /// FunctionPassManagerImpl manages FPPassManagers
2517330f729Sjoerg class FunctionPassManagerImpl : public Pass,
2527330f729Sjoerg public PMDataManager,
2537330f729Sjoerg public PMTopLevelManager {
2547330f729Sjoerg virtual void anchor();
2557330f729Sjoerg private:
2567330f729Sjoerg bool wasRun;
2577330f729Sjoerg public:
2587330f729Sjoerg static char ID;
FunctionPassManagerImpl()2597330f729Sjoerg explicit FunctionPassManagerImpl() :
2607330f729Sjoerg Pass(PT_PassManager, ID), PMDataManager(),
2617330f729Sjoerg PMTopLevelManager(new FPPassManager()), wasRun(false) {}
2627330f729Sjoerg
2637330f729Sjoerg /// \copydoc FunctionPassManager::add()
add(Pass * P)2647330f729Sjoerg void add(Pass *P) {
2657330f729Sjoerg schedulePass(P);
2667330f729Sjoerg }
2677330f729Sjoerg
2687330f729Sjoerg /// createPrinterPass - Get a function printer pass.
createPrinterPass(raw_ostream & O,const std::string & Banner) const2697330f729Sjoerg Pass *createPrinterPass(raw_ostream &O,
2707330f729Sjoerg const std::string &Banner) const override {
2717330f729Sjoerg return createPrintFunctionPass(O, Banner);
2727330f729Sjoerg }
2737330f729Sjoerg
2747330f729Sjoerg // Prepare for running an on the fly pass, freeing memory if needed
2757330f729Sjoerg // from a previous run.
2767330f729Sjoerg void releaseMemoryOnTheFly();
2777330f729Sjoerg
2787330f729Sjoerg /// run - Execute all of the passes scheduled for execution. Keep track of
2797330f729Sjoerg /// whether any of the passes modifies the module, and if so, return true.
2807330f729Sjoerg bool run(Function &F);
2817330f729Sjoerg
2827330f729Sjoerg /// doInitialization - Run all of the initializers for the function passes.
2837330f729Sjoerg ///
2847330f729Sjoerg bool doInitialization(Module &M) override;
2857330f729Sjoerg
2867330f729Sjoerg /// doFinalization - Run all of the finalizers for the function passes.
2877330f729Sjoerg ///
2887330f729Sjoerg bool doFinalization(Module &M) override;
2897330f729Sjoerg
2907330f729Sjoerg
getAsPMDataManager()2917330f729Sjoerg PMDataManager *getAsPMDataManager() override { return this; }
getAsPass()2927330f729Sjoerg Pass *getAsPass() override { return this; }
getTopLevelPassManagerType()2937330f729Sjoerg PassManagerType getTopLevelPassManagerType() override {
2947330f729Sjoerg return PMT_FunctionPassManager;
2957330f729Sjoerg }
2967330f729Sjoerg
2977330f729Sjoerg /// Pass Manager itself does not invalidate any analysis info.
getAnalysisUsage(AnalysisUsage & Info) const2987330f729Sjoerg void getAnalysisUsage(AnalysisUsage &Info) const override {
2997330f729Sjoerg Info.setPreservesAll();
3007330f729Sjoerg }
3017330f729Sjoerg
getContainedManager(unsigned N)3027330f729Sjoerg FPPassManager *getContainedManager(unsigned N) {
3037330f729Sjoerg assert(N < PassManagers.size() && "Pass number out of range!");
3047330f729Sjoerg FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]);
3057330f729Sjoerg return FP;
3067330f729Sjoerg }
307*82d56013Sjoerg
dumpPassStructure(unsigned Offset)308*82d56013Sjoerg void dumpPassStructure(unsigned Offset) override {
309*82d56013Sjoerg for (unsigned I = 0; I < getNumContainedManagers(); ++I)
310*82d56013Sjoerg getContainedManager(I)->dumpPassStructure(Offset);
311*82d56013Sjoerg }
3127330f729Sjoerg };
3137330f729Sjoerg
anchor()3147330f729Sjoerg void FunctionPassManagerImpl::anchor() {}
3157330f729Sjoerg
3167330f729Sjoerg char FunctionPassManagerImpl::ID = 0;
317*82d56013Sjoerg
318*82d56013Sjoerg //===----------------------------------------------------------------------===//
319*82d56013Sjoerg // FunctionPassManagerImpl implementation
320*82d56013Sjoerg //
doInitialization(Module & M)321*82d56013Sjoerg bool FunctionPassManagerImpl::doInitialization(Module &M) {
322*82d56013Sjoerg bool Changed = false;
323*82d56013Sjoerg
324*82d56013Sjoerg dumpArguments();
325*82d56013Sjoerg dumpPasses();
326*82d56013Sjoerg
327*82d56013Sjoerg for (ImmutablePass *ImPass : getImmutablePasses())
328*82d56013Sjoerg Changed |= ImPass->doInitialization(M);
329*82d56013Sjoerg
330*82d56013Sjoerg for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
331*82d56013Sjoerg Changed |= getContainedManager(Index)->doInitialization(M);
332*82d56013Sjoerg
333*82d56013Sjoerg return Changed;
334*82d56013Sjoerg }
335*82d56013Sjoerg
doFinalization(Module & M)336*82d56013Sjoerg bool FunctionPassManagerImpl::doFinalization(Module &M) {
337*82d56013Sjoerg bool Changed = false;
338*82d56013Sjoerg
339*82d56013Sjoerg for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index)
340*82d56013Sjoerg Changed |= getContainedManager(Index)->doFinalization(M);
341*82d56013Sjoerg
342*82d56013Sjoerg for (ImmutablePass *ImPass : getImmutablePasses())
343*82d56013Sjoerg Changed |= ImPass->doFinalization(M);
344*82d56013Sjoerg
345*82d56013Sjoerg return Changed;
346*82d56013Sjoerg }
347*82d56013Sjoerg
releaseMemoryOnTheFly()348*82d56013Sjoerg void FunctionPassManagerImpl::releaseMemoryOnTheFly() {
349*82d56013Sjoerg if (!wasRun)
350*82d56013Sjoerg return;
351*82d56013Sjoerg for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
352*82d56013Sjoerg FPPassManager *FPPM = getContainedManager(Index);
353*82d56013Sjoerg for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) {
354*82d56013Sjoerg FPPM->getContainedPass(Index)->releaseMemory();
355*82d56013Sjoerg }
356*82d56013Sjoerg }
357*82d56013Sjoerg wasRun = false;
358*82d56013Sjoerg }
359*82d56013Sjoerg
360*82d56013Sjoerg // Execute all the passes managed by this top level manager.
361*82d56013Sjoerg // Return true if any function is modified by a pass.
run(Function & F)362*82d56013Sjoerg bool FunctionPassManagerImpl::run(Function &F) {
363*82d56013Sjoerg bool Changed = false;
364*82d56013Sjoerg
365*82d56013Sjoerg initializeAllAnalysisInfo();
366*82d56013Sjoerg for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
367*82d56013Sjoerg Changed |= getContainedManager(Index)->runOnFunction(F);
368*82d56013Sjoerg F.getContext().yield();
369*82d56013Sjoerg }
370*82d56013Sjoerg
371*82d56013Sjoerg for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
372*82d56013Sjoerg getContainedManager(Index)->cleanup();
373*82d56013Sjoerg
374*82d56013Sjoerg wasRun = true;
375*82d56013Sjoerg return Changed;
376*82d56013Sjoerg }
377*82d56013Sjoerg } // namespace legacy
378*82d56013Sjoerg } // namespace llvm
3797330f729Sjoerg
3807330f729Sjoerg namespace {
3817330f729Sjoerg //===----------------------------------------------------------------------===//
3827330f729Sjoerg // MPPassManager
3837330f729Sjoerg //
3847330f729Sjoerg /// MPPassManager manages ModulePasses and function pass managers.
3857330f729Sjoerg /// It batches all Module passes and function pass managers together and
3867330f729Sjoerg /// sequences them to process one module.
3877330f729Sjoerg class MPPassManager : public Pass, public PMDataManager {
3887330f729Sjoerg public:
3897330f729Sjoerg static char ID;
MPPassManager()3907330f729Sjoerg explicit MPPassManager() :
3917330f729Sjoerg Pass(PT_PassManager, ID), PMDataManager() { }
3927330f729Sjoerg
3937330f729Sjoerg // Delete on the fly managers.
~MPPassManager()3947330f729Sjoerg ~MPPassManager() override {
3957330f729Sjoerg for (auto &OnTheFlyManager : OnTheFlyManagers) {
396*82d56013Sjoerg legacy::FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
3977330f729Sjoerg delete FPP;
3987330f729Sjoerg }
3997330f729Sjoerg }
4007330f729Sjoerg
4017330f729Sjoerg /// createPrinterPass - Get a module printer pass.
createPrinterPass(raw_ostream & O,const std::string & Banner) const4027330f729Sjoerg Pass *createPrinterPass(raw_ostream &O,
4037330f729Sjoerg const std::string &Banner) const override {
4047330f729Sjoerg return createPrintModulePass(O, Banner);
4057330f729Sjoerg }
4067330f729Sjoerg
4077330f729Sjoerg /// run - Execute all of the passes scheduled for execution. Keep track of
4087330f729Sjoerg /// whether any of the passes modifies the module, and if so, return true.
4097330f729Sjoerg bool runOnModule(Module &M);
4107330f729Sjoerg
4117330f729Sjoerg using llvm::Pass::doInitialization;
4127330f729Sjoerg using llvm::Pass::doFinalization;
4137330f729Sjoerg
4147330f729Sjoerg /// Pass Manager itself does not invalidate any analysis info.
getAnalysisUsage(AnalysisUsage & Info) const4157330f729Sjoerg void getAnalysisUsage(AnalysisUsage &Info) const override {
4167330f729Sjoerg Info.setPreservesAll();
4177330f729Sjoerg }
4187330f729Sjoerg
4197330f729Sjoerg /// Add RequiredPass into list of lower level passes required by pass P.
4207330f729Sjoerg /// RequiredPass is run on the fly by Pass Manager when P requests it
4217330f729Sjoerg /// through getAnalysis interface.
4227330f729Sjoerg void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) override;
4237330f729Sjoerg
4247330f729Sjoerg /// Return function pass corresponding to PassInfo PI, that is
4257330f729Sjoerg /// required by module pass MP. Instantiate analysis pass, by using
4267330f729Sjoerg /// its runOnFunction() for function F.
427*82d56013Sjoerg std::tuple<Pass *, bool> getOnTheFlyPass(Pass *MP, AnalysisID PI,
428*82d56013Sjoerg Function &F) override;
4297330f729Sjoerg
getPassName() const4307330f729Sjoerg StringRef getPassName() const override { return "Module Pass Manager"; }
4317330f729Sjoerg
getAsPMDataManager()4327330f729Sjoerg PMDataManager *getAsPMDataManager() override { return this; }
getAsPass()4337330f729Sjoerg Pass *getAsPass() override { return this; }
4347330f729Sjoerg
4357330f729Sjoerg // Print passes managed by this manager
dumpPassStructure(unsigned Offset)4367330f729Sjoerg void dumpPassStructure(unsigned Offset) override {
4377330f729Sjoerg dbgs().indent(Offset*2) << "ModulePass Manager\n";
4387330f729Sjoerg for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
4397330f729Sjoerg ModulePass *MP = getContainedPass(Index);
4407330f729Sjoerg MP->dumpPassStructure(Offset + 1);
441*82d56013Sjoerg MapVector<Pass *, legacy::FunctionPassManagerImpl *>::const_iterator I =
4427330f729Sjoerg OnTheFlyManagers.find(MP);
4437330f729Sjoerg if (I != OnTheFlyManagers.end())
4447330f729Sjoerg I->second->dumpPassStructure(Offset + 2);
4457330f729Sjoerg dumpLastUses(MP, Offset+1);
4467330f729Sjoerg }
4477330f729Sjoerg }
4487330f729Sjoerg
getContainedPass(unsigned N)4497330f729Sjoerg ModulePass *getContainedPass(unsigned N) {
4507330f729Sjoerg assert(N < PassVector.size() && "Pass number out of range!");
4517330f729Sjoerg return static_cast<ModulePass *>(PassVector[N]);
4527330f729Sjoerg }
4537330f729Sjoerg
getPassManagerType() const4547330f729Sjoerg PassManagerType getPassManagerType() const override {
4557330f729Sjoerg return PMT_ModulePassManager;
4567330f729Sjoerg }
4577330f729Sjoerg
4587330f729Sjoerg private:
4597330f729Sjoerg /// Collection of on the fly FPPassManagers. These managers manage
4607330f729Sjoerg /// function passes that are required by module passes.
461*82d56013Sjoerg MapVector<Pass *, legacy::FunctionPassManagerImpl *> OnTheFlyManagers;
4627330f729Sjoerg };
4637330f729Sjoerg
4647330f729Sjoerg char MPPassManager::ID = 0;
4657330f729Sjoerg } // End anonymous namespace
4667330f729Sjoerg
4677330f729Sjoerg namespace llvm {
4687330f729Sjoerg namespace legacy {
4697330f729Sjoerg //===----------------------------------------------------------------------===//
4707330f729Sjoerg // PassManagerImpl
4717330f729Sjoerg //
4727330f729Sjoerg
4737330f729Sjoerg /// PassManagerImpl manages MPPassManagers
4747330f729Sjoerg class PassManagerImpl : public Pass,
4757330f729Sjoerg public PMDataManager,
4767330f729Sjoerg public PMTopLevelManager {
4777330f729Sjoerg virtual void anchor();
4787330f729Sjoerg
4797330f729Sjoerg public:
4807330f729Sjoerg static char ID;
PassManagerImpl()4817330f729Sjoerg explicit PassManagerImpl() :
4827330f729Sjoerg Pass(PT_PassManager, ID), PMDataManager(),
4837330f729Sjoerg PMTopLevelManager(new MPPassManager()) {}
4847330f729Sjoerg
4857330f729Sjoerg /// \copydoc PassManager::add()
add(Pass * P)4867330f729Sjoerg void add(Pass *P) {
4877330f729Sjoerg schedulePass(P);
4887330f729Sjoerg }
4897330f729Sjoerg
4907330f729Sjoerg /// createPrinterPass - Get a module printer pass.
createPrinterPass(raw_ostream & O,const std::string & Banner) const4917330f729Sjoerg Pass *createPrinterPass(raw_ostream &O,
4927330f729Sjoerg const std::string &Banner) const override {
4937330f729Sjoerg return createPrintModulePass(O, Banner);
4947330f729Sjoerg }
4957330f729Sjoerg
4967330f729Sjoerg /// run - Execute all of the passes scheduled for execution. Keep track of
4977330f729Sjoerg /// whether any of the passes modifies the module, and if so, return true.
4987330f729Sjoerg bool run(Module &M);
4997330f729Sjoerg
5007330f729Sjoerg using llvm::Pass::doInitialization;
5017330f729Sjoerg using llvm::Pass::doFinalization;
5027330f729Sjoerg
5037330f729Sjoerg /// Pass Manager itself does not invalidate any analysis info.
getAnalysisUsage(AnalysisUsage & Info) const5047330f729Sjoerg void getAnalysisUsage(AnalysisUsage &Info) const override {
5057330f729Sjoerg Info.setPreservesAll();
5067330f729Sjoerg }
5077330f729Sjoerg
getAsPMDataManager()5087330f729Sjoerg PMDataManager *getAsPMDataManager() override { return this; }
getAsPass()5097330f729Sjoerg Pass *getAsPass() override { return this; }
getTopLevelPassManagerType()5107330f729Sjoerg PassManagerType getTopLevelPassManagerType() override {
5117330f729Sjoerg return PMT_ModulePassManager;
5127330f729Sjoerg }
5137330f729Sjoerg
getContainedManager(unsigned N)5147330f729Sjoerg MPPassManager *getContainedManager(unsigned N) {
5157330f729Sjoerg assert(N < PassManagers.size() && "Pass number out of range!");
5167330f729Sjoerg MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]);
5177330f729Sjoerg return MP;
5187330f729Sjoerg }
5197330f729Sjoerg };
5207330f729Sjoerg
anchor()5217330f729Sjoerg void PassManagerImpl::anchor() {}
5227330f729Sjoerg
5237330f729Sjoerg char PassManagerImpl::ID = 0;
524*82d56013Sjoerg
525*82d56013Sjoerg //===----------------------------------------------------------------------===//
526*82d56013Sjoerg // PassManagerImpl implementation
527*82d56013Sjoerg
528*82d56013Sjoerg //
529*82d56013Sjoerg /// run - Execute all of the passes scheduled for execution. Keep track of
530*82d56013Sjoerg /// whether any of the passes modifies the module, and if so, return true.
run(Module & M)531*82d56013Sjoerg bool PassManagerImpl::run(Module &M) {
532*82d56013Sjoerg bool Changed = false;
533*82d56013Sjoerg
534*82d56013Sjoerg dumpArguments();
535*82d56013Sjoerg dumpPasses();
536*82d56013Sjoerg
537*82d56013Sjoerg for (ImmutablePass *ImPass : getImmutablePasses())
538*82d56013Sjoerg Changed |= ImPass->doInitialization(M);
539*82d56013Sjoerg
540*82d56013Sjoerg initializeAllAnalysisInfo();
541*82d56013Sjoerg for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
542*82d56013Sjoerg Changed |= getContainedManager(Index)->runOnModule(M);
543*82d56013Sjoerg M.getContext().yield();
544*82d56013Sjoerg }
545*82d56013Sjoerg
546*82d56013Sjoerg for (ImmutablePass *ImPass : getImmutablePasses())
547*82d56013Sjoerg Changed |= ImPass->doFinalization(M);
548*82d56013Sjoerg
549*82d56013Sjoerg return Changed;
550*82d56013Sjoerg }
551*82d56013Sjoerg } // namespace legacy
552*82d56013Sjoerg } // namespace llvm
5537330f729Sjoerg
5547330f729Sjoerg //===----------------------------------------------------------------------===//
5557330f729Sjoerg // PMTopLevelManager implementation
5567330f729Sjoerg
5577330f729Sjoerg /// Initialize top level manager. Create first pass manager.
PMTopLevelManager(PMDataManager * PMDM)5587330f729Sjoerg PMTopLevelManager::PMTopLevelManager(PMDataManager *PMDM) {
5597330f729Sjoerg PMDM->setTopLevelManager(this);
5607330f729Sjoerg addPassManager(PMDM);
5617330f729Sjoerg activeStack.push(PMDM);
5627330f729Sjoerg }
5637330f729Sjoerg
5647330f729Sjoerg /// Set pass P as the last user of the given analysis passes.
5657330f729Sjoerg void
setLastUser(ArrayRef<Pass * > AnalysisPasses,Pass * P)5667330f729Sjoerg PMTopLevelManager::setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P) {
5677330f729Sjoerg unsigned PDepth = 0;
5687330f729Sjoerg if (P->getResolver())
5697330f729Sjoerg PDepth = P->getResolver()->getPMDataManager().getDepth();
5707330f729Sjoerg
5717330f729Sjoerg for (Pass *AP : AnalysisPasses) {
572*82d56013Sjoerg // Record P as the new last user of AP.
573*82d56013Sjoerg auto &LastUserOfAP = LastUser[AP];
574*82d56013Sjoerg if (LastUserOfAP)
575*82d56013Sjoerg InversedLastUser[LastUserOfAP].erase(AP);
576*82d56013Sjoerg LastUserOfAP = P;
577*82d56013Sjoerg InversedLastUser[P].insert(AP);
5787330f729Sjoerg
5797330f729Sjoerg if (P == AP)
5807330f729Sjoerg continue;
5817330f729Sjoerg
5827330f729Sjoerg // Update the last users of passes that are required transitive by AP.
5837330f729Sjoerg AnalysisUsage *AnUsage = findAnalysisUsage(AP);
5847330f729Sjoerg const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet();
5857330f729Sjoerg SmallVector<Pass *, 12> LastUses;
5867330f729Sjoerg SmallVector<Pass *, 12> LastPMUses;
5877330f729Sjoerg for (AnalysisID ID : IDs) {
5887330f729Sjoerg Pass *AnalysisPass = findAnalysisPass(ID);
5897330f729Sjoerg assert(AnalysisPass && "Expected analysis pass to exist.");
5907330f729Sjoerg AnalysisResolver *AR = AnalysisPass->getResolver();
5917330f729Sjoerg assert(AR && "Expected analysis resolver to exist.");
5927330f729Sjoerg unsigned APDepth = AR->getPMDataManager().getDepth();
5937330f729Sjoerg
5947330f729Sjoerg if (PDepth == APDepth)
5957330f729Sjoerg LastUses.push_back(AnalysisPass);
5967330f729Sjoerg else if (PDepth > APDepth)
5977330f729Sjoerg LastPMUses.push_back(AnalysisPass);
5987330f729Sjoerg }
5997330f729Sjoerg
6007330f729Sjoerg setLastUser(LastUses, P);
6017330f729Sjoerg
6027330f729Sjoerg // If this pass has a corresponding pass manager, push higher level
6037330f729Sjoerg // analysis to this pass manager.
6047330f729Sjoerg if (P->getResolver())
6057330f729Sjoerg setLastUser(LastPMUses, P->getResolver()->getPMDataManager().getAsPass());
6067330f729Sjoerg
6077330f729Sjoerg // If AP is the last user of other passes then make P last user of
6087330f729Sjoerg // such passes.
609*82d56013Sjoerg auto &LastUsedByAP = InversedLastUser[AP];
610*82d56013Sjoerg for (Pass *L : LastUsedByAP)
611*82d56013Sjoerg LastUser[L] = P;
612*82d56013Sjoerg InversedLastUser[P].insert(LastUsedByAP.begin(), LastUsedByAP.end());
613*82d56013Sjoerg LastUsedByAP.clear();
6147330f729Sjoerg }
6157330f729Sjoerg }
6167330f729Sjoerg
6177330f729Sjoerg /// Collect passes whose last user is P
collectLastUses(SmallVectorImpl<Pass * > & LastUses,Pass * P)6187330f729Sjoerg void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses,
6197330f729Sjoerg Pass *P) {
620*82d56013Sjoerg auto DMI = InversedLastUser.find(P);
6217330f729Sjoerg if (DMI == InversedLastUser.end())
6227330f729Sjoerg return;
6237330f729Sjoerg
624*82d56013Sjoerg auto &LU = DMI->second;
625*82d56013Sjoerg LastUses.append(LU.begin(), LU.end());
6267330f729Sjoerg }
6277330f729Sjoerg
findAnalysisUsage(Pass * P)6287330f729Sjoerg AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) {
6297330f729Sjoerg AnalysisUsage *AnUsage = nullptr;
6307330f729Sjoerg auto DMI = AnUsageMap.find(P);
6317330f729Sjoerg if (DMI != AnUsageMap.end())
6327330f729Sjoerg AnUsage = DMI->second;
6337330f729Sjoerg else {
6347330f729Sjoerg // Look up the analysis usage from the pass instance (different instances
6357330f729Sjoerg // of the same pass can produce different results), but unique the
6367330f729Sjoerg // resulting object to reduce memory usage. This helps to greatly reduce
6377330f729Sjoerg // memory usage when we have many instances of only a few pass types
6387330f729Sjoerg // (e.g. instcombine, simplifycfg, etc...) which tend to share a fixed set
6397330f729Sjoerg // of dependencies.
6407330f729Sjoerg AnalysisUsage AU;
6417330f729Sjoerg P->getAnalysisUsage(AU);
6427330f729Sjoerg
6437330f729Sjoerg AUFoldingSetNode* Node = nullptr;
6447330f729Sjoerg FoldingSetNodeID ID;
6457330f729Sjoerg AUFoldingSetNode::Profile(ID, AU);
6467330f729Sjoerg void *IP = nullptr;
6477330f729Sjoerg if (auto *N = UniqueAnalysisUsages.FindNodeOrInsertPos(ID, IP))
6487330f729Sjoerg Node = N;
6497330f729Sjoerg else {
6507330f729Sjoerg Node = new (AUFoldingSetNodeAllocator.Allocate()) AUFoldingSetNode(AU);
6517330f729Sjoerg UniqueAnalysisUsages.InsertNode(Node, IP);
6527330f729Sjoerg }
6537330f729Sjoerg assert(Node && "cached analysis usage must be non null");
6547330f729Sjoerg
6557330f729Sjoerg AnUsageMap[P] = &Node->AU;
6567330f729Sjoerg AnUsage = &Node->AU;
6577330f729Sjoerg }
6587330f729Sjoerg return AnUsage;
6597330f729Sjoerg }
6607330f729Sjoerg
6617330f729Sjoerg /// Schedule pass P for execution. Make sure that passes required by
6627330f729Sjoerg /// P are run before P is run. Update analysis info maintained by
6637330f729Sjoerg /// the manager. Remove dead passes. This is a recursive function.
schedulePass(Pass * P)6647330f729Sjoerg void PMTopLevelManager::schedulePass(Pass *P) {
6657330f729Sjoerg
6667330f729Sjoerg // TODO : Allocate function manager for this pass, other wise required set
6677330f729Sjoerg // may be inserted into previous function manager
6687330f729Sjoerg
6697330f729Sjoerg // Give pass a chance to prepare the stage.
6707330f729Sjoerg P->preparePassManager(activeStack);
6717330f729Sjoerg
6727330f729Sjoerg // If P is an analysis pass and it is available then do not
6737330f729Sjoerg // generate the analysis again. Stale analysis info should not be
6747330f729Sjoerg // available at this point.
6757330f729Sjoerg const PassInfo *PI = findAnalysisPassInfo(P->getPassID());
6767330f729Sjoerg if (PI && PI->isAnalysis() && findAnalysisPass(P->getPassID())) {
6777330f729Sjoerg // Remove any cached AnalysisUsage information.
6787330f729Sjoerg AnUsageMap.erase(P);
6797330f729Sjoerg delete P;
6807330f729Sjoerg return;
6817330f729Sjoerg }
6827330f729Sjoerg
6837330f729Sjoerg AnalysisUsage *AnUsage = findAnalysisUsage(P);
6847330f729Sjoerg
6857330f729Sjoerg bool checkAnalysis = true;
6867330f729Sjoerg while (checkAnalysis) {
6877330f729Sjoerg checkAnalysis = false;
6887330f729Sjoerg
6897330f729Sjoerg const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet();
6907330f729Sjoerg for (const AnalysisID ID : RequiredSet) {
6917330f729Sjoerg
6927330f729Sjoerg Pass *AnalysisPass = findAnalysisPass(ID);
6937330f729Sjoerg if (!AnalysisPass) {
6947330f729Sjoerg const PassInfo *PI = findAnalysisPassInfo(ID);
6957330f729Sjoerg
6967330f729Sjoerg if (!PI) {
6977330f729Sjoerg // Pass P is not in the global PassRegistry
6987330f729Sjoerg dbgs() << "Pass '" << P->getPassName() << "' is not initialized." << "\n";
6997330f729Sjoerg dbgs() << "Verify if there is a pass dependency cycle." << "\n";
7007330f729Sjoerg dbgs() << "Required Passes:" << "\n";
7017330f729Sjoerg for (const AnalysisID ID2 : RequiredSet) {
7027330f729Sjoerg if (ID == ID2)
7037330f729Sjoerg break;
7047330f729Sjoerg Pass *AnalysisPass2 = findAnalysisPass(ID2);
7057330f729Sjoerg if (AnalysisPass2) {
7067330f729Sjoerg dbgs() << "\t" << AnalysisPass2->getPassName() << "\n";
7077330f729Sjoerg } else {
7087330f729Sjoerg dbgs() << "\t" << "Error: Required pass not found! Possible causes:" << "\n";
7097330f729Sjoerg dbgs() << "\t\t" << "- Pass misconfiguration (e.g.: missing macros)" << "\n";
7107330f729Sjoerg dbgs() << "\t\t" << "- Corruption of the global PassRegistry" << "\n";
7117330f729Sjoerg }
7127330f729Sjoerg }
7137330f729Sjoerg }
7147330f729Sjoerg
7157330f729Sjoerg assert(PI && "Expected required passes to be initialized");
7167330f729Sjoerg AnalysisPass = PI->createPass();
7177330f729Sjoerg if (P->getPotentialPassManagerType () ==
7187330f729Sjoerg AnalysisPass->getPotentialPassManagerType())
7197330f729Sjoerg // Schedule analysis pass that is managed by the same pass manager.
7207330f729Sjoerg schedulePass(AnalysisPass);
7217330f729Sjoerg else if (P->getPotentialPassManagerType () >
7227330f729Sjoerg AnalysisPass->getPotentialPassManagerType()) {
7237330f729Sjoerg // Schedule analysis pass that is managed by a new manager.
7247330f729Sjoerg schedulePass(AnalysisPass);
7257330f729Sjoerg // Recheck analysis passes to ensure that required analyses that
7267330f729Sjoerg // are already checked are still available.
7277330f729Sjoerg checkAnalysis = true;
7287330f729Sjoerg } else
7297330f729Sjoerg // Do not schedule this analysis. Lower level analysis
7307330f729Sjoerg // passes are run on the fly.
7317330f729Sjoerg delete AnalysisPass;
7327330f729Sjoerg }
7337330f729Sjoerg }
7347330f729Sjoerg }
7357330f729Sjoerg
7367330f729Sjoerg // Now all required passes are available.
7377330f729Sjoerg if (ImmutablePass *IP = P->getAsImmutablePass()) {
7387330f729Sjoerg // P is a immutable pass and it will be managed by this
7397330f729Sjoerg // top level manager. Set up analysis resolver to connect them.
7407330f729Sjoerg PMDataManager *DM = getAsPMDataManager();
7417330f729Sjoerg AnalysisResolver *AR = new AnalysisResolver(*DM);
7427330f729Sjoerg P->setResolver(AR);
7437330f729Sjoerg DM->initializeAnalysisImpl(P);
7447330f729Sjoerg addImmutablePass(IP);
7457330f729Sjoerg DM->recordAvailableAnalysis(IP);
7467330f729Sjoerg return;
7477330f729Sjoerg }
7487330f729Sjoerg
7497330f729Sjoerg if (PI && !PI->isAnalysis() && shouldPrintBeforePass(PI->getPassArgument())) {
750*82d56013Sjoerg Pass *PP =
751*82d56013Sjoerg P->createPrinterPass(dbgs(), ("*** IR Dump Before " + P->getPassName() +
752*82d56013Sjoerg " (" + PI->getPassArgument() + ") ***")
753*82d56013Sjoerg .str());
7547330f729Sjoerg PP->assignPassManager(activeStack, getTopLevelPassManagerType());
7557330f729Sjoerg }
7567330f729Sjoerg
7577330f729Sjoerg // Add the requested pass to the best available pass manager.
7587330f729Sjoerg P->assignPassManager(activeStack, getTopLevelPassManagerType());
7597330f729Sjoerg
7607330f729Sjoerg if (PI && !PI->isAnalysis() && shouldPrintAfterPass(PI->getPassArgument())) {
761*82d56013Sjoerg Pass *PP =
762*82d56013Sjoerg P->createPrinterPass(dbgs(), ("*** IR Dump After " + P->getPassName() +
763*82d56013Sjoerg " (" + PI->getPassArgument() + ") ***")
764*82d56013Sjoerg .str());
7657330f729Sjoerg PP->assignPassManager(activeStack, getTopLevelPassManagerType());
7667330f729Sjoerg }
7677330f729Sjoerg }
7687330f729Sjoerg
7697330f729Sjoerg /// Find the pass that implements Analysis AID. Search immutable
7707330f729Sjoerg /// passes and all pass managers. If desired pass is not found
7717330f729Sjoerg /// then return NULL.
findAnalysisPass(AnalysisID AID)7727330f729Sjoerg Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
7737330f729Sjoerg // For immutable passes we have a direct mapping from ID to pass, so check
7747330f729Sjoerg // that first.
7757330f729Sjoerg if (Pass *P = ImmutablePassMap.lookup(AID))
7767330f729Sjoerg return P;
7777330f729Sjoerg
7787330f729Sjoerg // Check pass managers
7797330f729Sjoerg for (PMDataManager *PassManager : PassManagers)
7807330f729Sjoerg if (Pass *P = PassManager->findAnalysisPass(AID, false))
7817330f729Sjoerg return P;
7827330f729Sjoerg
7837330f729Sjoerg // Check other pass managers
7847330f729Sjoerg for (PMDataManager *IndirectPassManager : IndirectPassManagers)
7857330f729Sjoerg if (Pass *P = IndirectPassManager->findAnalysisPass(AID, false))
7867330f729Sjoerg return P;
7877330f729Sjoerg
7887330f729Sjoerg return nullptr;
7897330f729Sjoerg }
7907330f729Sjoerg
findAnalysisPassInfo(AnalysisID AID) const7917330f729Sjoerg const PassInfo *PMTopLevelManager::findAnalysisPassInfo(AnalysisID AID) const {
7927330f729Sjoerg const PassInfo *&PI = AnalysisPassInfos[AID];
7937330f729Sjoerg if (!PI)
7947330f729Sjoerg PI = PassRegistry::getPassRegistry()->getPassInfo(AID);
7957330f729Sjoerg else
7967330f729Sjoerg assert(PI == PassRegistry::getPassRegistry()->getPassInfo(AID) &&
7977330f729Sjoerg "The pass info pointer changed for an analysis ID!");
7987330f729Sjoerg
7997330f729Sjoerg return PI;
8007330f729Sjoerg }
8017330f729Sjoerg
addImmutablePass(ImmutablePass * P)8027330f729Sjoerg void PMTopLevelManager::addImmutablePass(ImmutablePass *P) {
8037330f729Sjoerg P->initializePass();
8047330f729Sjoerg ImmutablePasses.push_back(P);
8057330f729Sjoerg
8067330f729Sjoerg // Add this pass to the map from its analysis ID. We clobber any prior runs
8077330f729Sjoerg // of the pass in the map so that the last one added is the one found when
8087330f729Sjoerg // doing lookups.
8097330f729Sjoerg AnalysisID AID = P->getPassID();
8107330f729Sjoerg ImmutablePassMap[AID] = P;
8117330f729Sjoerg
8127330f729Sjoerg // Also add any interfaces implemented by the immutable pass to the map for
8137330f729Sjoerg // fast lookup.
8147330f729Sjoerg const PassInfo *PassInf = findAnalysisPassInfo(AID);
8157330f729Sjoerg assert(PassInf && "Expected all immutable passes to be initialized");
8167330f729Sjoerg for (const PassInfo *ImmPI : PassInf->getInterfacesImplemented())
8177330f729Sjoerg ImmutablePassMap[ImmPI->getTypeInfo()] = P;
8187330f729Sjoerg }
8197330f729Sjoerg
8207330f729Sjoerg // Print passes managed by this top level manager.
dumpPasses() const8217330f729Sjoerg void PMTopLevelManager::dumpPasses() const {
8227330f729Sjoerg
8237330f729Sjoerg if (PassDebugging < Structure)
8247330f729Sjoerg return;
8257330f729Sjoerg
8267330f729Sjoerg // Print out the immutable passes
8277330f729Sjoerg for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) {
8287330f729Sjoerg ImmutablePasses[i]->dumpPassStructure(0);
8297330f729Sjoerg }
8307330f729Sjoerg
8317330f729Sjoerg // Every class that derives from PMDataManager also derives from Pass
8327330f729Sjoerg // (sometimes indirectly), but there's no inheritance relationship
8337330f729Sjoerg // between PMDataManager and Pass, so we have to getAsPass to get
8347330f729Sjoerg // from a PMDataManager* to a Pass*.
8357330f729Sjoerg for (PMDataManager *Manager : PassManagers)
8367330f729Sjoerg Manager->getAsPass()->dumpPassStructure(1);
8377330f729Sjoerg }
8387330f729Sjoerg
dumpArguments() const8397330f729Sjoerg void PMTopLevelManager::dumpArguments() const {
8407330f729Sjoerg
8417330f729Sjoerg if (PassDebugging < Arguments)
8427330f729Sjoerg return;
8437330f729Sjoerg
8447330f729Sjoerg dbgs() << "Pass Arguments: ";
8457330f729Sjoerg for (ImmutablePass *P : ImmutablePasses)
8467330f729Sjoerg if (const PassInfo *PI = findAnalysisPassInfo(P->getPassID())) {
8477330f729Sjoerg assert(PI && "Expected all immutable passes to be initialized");
8487330f729Sjoerg if (!PI->isAnalysisGroup())
8497330f729Sjoerg dbgs() << " -" << PI->getPassArgument();
8507330f729Sjoerg }
8517330f729Sjoerg for (PMDataManager *PM : PassManagers)
8527330f729Sjoerg PM->dumpPassArguments();
8537330f729Sjoerg dbgs() << "\n";
8547330f729Sjoerg }
8557330f729Sjoerg
initializeAllAnalysisInfo()8567330f729Sjoerg void PMTopLevelManager::initializeAllAnalysisInfo() {
8577330f729Sjoerg for (PMDataManager *PM : PassManagers)
8587330f729Sjoerg PM->initializeAnalysisInfo();
8597330f729Sjoerg
8607330f729Sjoerg // Initailize other pass managers
8617330f729Sjoerg for (PMDataManager *IPM : IndirectPassManagers)
8627330f729Sjoerg IPM->initializeAnalysisInfo();
8637330f729Sjoerg }
8647330f729Sjoerg
8657330f729Sjoerg /// Destructor
~PMTopLevelManager()8667330f729Sjoerg PMTopLevelManager::~PMTopLevelManager() {
8677330f729Sjoerg for (PMDataManager *PM : PassManagers)
8687330f729Sjoerg delete PM;
8697330f729Sjoerg
8707330f729Sjoerg for (ImmutablePass *P : ImmutablePasses)
8717330f729Sjoerg delete P;
8727330f729Sjoerg }
8737330f729Sjoerg
8747330f729Sjoerg //===----------------------------------------------------------------------===//
8757330f729Sjoerg // PMDataManager implementation
8767330f729Sjoerg
8777330f729Sjoerg /// Augement AvailableAnalysis by adding analysis made available by pass P.
recordAvailableAnalysis(Pass * P)8787330f729Sjoerg void PMDataManager::recordAvailableAnalysis(Pass *P) {
8797330f729Sjoerg AnalysisID PI = P->getPassID();
8807330f729Sjoerg
8817330f729Sjoerg AvailableAnalysis[PI] = P;
8827330f729Sjoerg
8837330f729Sjoerg assert(!AvailableAnalysis.empty());
8847330f729Sjoerg
8857330f729Sjoerg // This pass is the current implementation of all of the interfaces it
8867330f729Sjoerg // implements as well.
8877330f729Sjoerg const PassInfo *PInf = TPM->findAnalysisPassInfo(PI);
8887330f729Sjoerg if (!PInf) return;
8897330f729Sjoerg const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented();
8907330f729Sjoerg for (unsigned i = 0, e = II.size(); i != e; ++i)
8917330f729Sjoerg AvailableAnalysis[II[i]->getTypeInfo()] = P;
8927330f729Sjoerg }
8937330f729Sjoerg
8947330f729Sjoerg // Return true if P preserves high level analysis used by other
8957330f729Sjoerg // passes managed by this manager
preserveHigherLevelAnalysis(Pass * P)8967330f729Sjoerg bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) {
8977330f729Sjoerg AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
8987330f729Sjoerg if (AnUsage->getPreservesAll())
8997330f729Sjoerg return true;
9007330f729Sjoerg
9017330f729Sjoerg const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
9027330f729Sjoerg for (Pass *P1 : HigherLevelAnalysis) {
9037330f729Sjoerg if (P1->getAsImmutablePass() == nullptr &&
9047330f729Sjoerg !is_contained(PreservedSet, P1->getPassID()))
9057330f729Sjoerg return false;
9067330f729Sjoerg }
9077330f729Sjoerg
9087330f729Sjoerg return true;
9097330f729Sjoerg }
9107330f729Sjoerg
9117330f729Sjoerg /// verifyPreservedAnalysis -- Verify analysis preserved by pass P.
verifyPreservedAnalysis(Pass * P)9127330f729Sjoerg void PMDataManager::verifyPreservedAnalysis(Pass *P) {
9137330f729Sjoerg // Don't do this unless assertions are enabled.
9147330f729Sjoerg #ifdef NDEBUG
9157330f729Sjoerg return;
9167330f729Sjoerg #endif
9177330f729Sjoerg AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
9187330f729Sjoerg const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
9197330f729Sjoerg
9207330f729Sjoerg // Verify preserved analysis
9217330f729Sjoerg for (AnalysisID AID : PreservedSet) {
9227330f729Sjoerg if (Pass *AP = findAnalysisPass(AID, true)) {
9237330f729Sjoerg TimeRegion PassTimer(getPassTimer(AP));
9247330f729Sjoerg AP->verifyAnalysis();
9257330f729Sjoerg }
9267330f729Sjoerg }
9277330f729Sjoerg }
9287330f729Sjoerg
9297330f729Sjoerg /// Remove Analysis not preserved by Pass P
removeNotPreservedAnalysis(Pass * P)9307330f729Sjoerg void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
9317330f729Sjoerg AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
9327330f729Sjoerg if (AnUsage->getPreservesAll())
9337330f729Sjoerg return;
9347330f729Sjoerg
9357330f729Sjoerg const AnalysisUsage::VectorType &PreservedSet = AnUsage->getPreservedSet();
9367330f729Sjoerg for (DenseMap<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(),
9377330f729Sjoerg E = AvailableAnalysis.end(); I != E; ) {
9387330f729Sjoerg DenseMap<AnalysisID, Pass*>::iterator Info = I++;
9397330f729Sjoerg if (Info->second->getAsImmutablePass() == nullptr &&
9407330f729Sjoerg !is_contained(PreservedSet, Info->first)) {
9417330f729Sjoerg // Remove this analysis
9427330f729Sjoerg if (PassDebugging >= Details) {
9437330f729Sjoerg Pass *S = Info->second;
9447330f729Sjoerg dbgs() << " -- '" << P->getPassName() << "' is not preserving '";
9457330f729Sjoerg dbgs() << S->getPassName() << "'\n";
9467330f729Sjoerg }
9477330f729Sjoerg AvailableAnalysis.erase(Info);
9487330f729Sjoerg }
9497330f729Sjoerg }
9507330f729Sjoerg
9517330f729Sjoerg // Check inherited analysis also. If P is not preserving analysis
9527330f729Sjoerg // provided by parent manager then remove it here.
953*82d56013Sjoerg for (DenseMap<AnalysisID, Pass *> *IA : InheritedAnalysis) {
954*82d56013Sjoerg if (!IA)
9557330f729Sjoerg continue;
9567330f729Sjoerg
957*82d56013Sjoerg for (DenseMap<AnalysisID, Pass *>::iterator I = IA->begin(),
958*82d56013Sjoerg E = IA->end();
959*82d56013Sjoerg I != E;) {
9607330f729Sjoerg DenseMap<AnalysisID, Pass *>::iterator Info = I++;
9617330f729Sjoerg if (Info->second->getAsImmutablePass() == nullptr &&
9627330f729Sjoerg !is_contained(PreservedSet, Info->first)) {
9637330f729Sjoerg // Remove this analysis
9647330f729Sjoerg if (PassDebugging >= Details) {
9657330f729Sjoerg Pass *S = Info->second;
9667330f729Sjoerg dbgs() << " -- '" << P->getPassName() << "' is not preserving '";
9677330f729Sjoerg dbgs() << S->getPassName() << "'\n";
9687330f729Sjoerg }
969*82d56013Sjoerg IA->erase(Info);
9707330f729Sjoerg }
9717330f729Sjoerg }
9727330f729Sjoerg }
9737330f729Sjoerg }
9747330f729Sjoerg
9757330f729Sjoerg /// Remove analysis passes that are not used any longer
removeDeadPasses(Pass * P,StringRef Msg,enum PassDebuggingString DBG_STR)9767330f729Sjoerg void PMDataManager::removeDeadPasses(Pass *P, StringRef Msg,
9777330f729Sjoerg enum PassDebuggingString DBG_STR) {
9787330f729Sjoerg
9797330f729Sjoerg SmallVector<Pass *, 12> DeadPasses;
9807330f729Sjoerg
9817330f729Sjoerg // If this is a on the fly manager then it does not have TPM.
9827330f729Sjoerg if (!TPM)
9837330f729Sjoerg return;
9847330f729Sjoerg
9857330f729Sjoerg TPM->collectLastUses(DeadPasses, P);
9867330f729Sjoerg
9877330f729Sjoerg if (PassDebugging >= Details && !DeadPasses.empty()) {
9887330f729Sjoerg dbgs() << " -*- '" << P->getPassName();
9897330f729Sjoerg dbgs() << "' is the last user of following pass instances.";
9907330f729Sjoerg dbgs() << " Free these instances\n";
9917330f729Sjoerg }
9927330f729Sjoerg
9937330f729Sjoerg for (Pass *P : DeadPasses)
9947330f729Sjoerg freePass(P, Msg, DBG_STR);
9957330f729Sjoerg }
9967330f729Sjoerg
freePass(Pass * P,StringRef Msg,enum PassDebuggingString DBG_STR)9977330f729Sjoerg void PMDataManager::freePass(Pass *P, StringRef Msg,
9987330f729Sjoerg enum PassDebuggingString DBG_STR) {
9997330f729Sjoerg dumpPassInfo(P, FREEING_MSG, DBG_STR, Msg);
10007330f729Sjoerg
10017330f729Sjoerg {
10027330f729Sjoerg // If the pass crashes releasing memory, remember this.
10037330f729Sjoerg PassManagerPrettyStackEntry X(P);
10047330f729Sjoerg TimeRegion PassTimer(getPassTimer(P));
10057330f729Sjoerg
10067330f729Sjoerg P->releaseMemory();
10077330f729Sjoerg }
10087330f729Sjoerg
10097330f729Sjoerg AnalysisID PI = P->getPassID();
10107330f729Sjoerg if (const PassInfo *PInf = TPM->findAnalysisPassInfo(PI)) {
10117330f729Sjoerg // Remove the pass itself (if it is not already removed).
10127330f729Sjoerg AvailableAnalysis.erase(PI);
10137330f729Sjoerg
10147330f729Sjoerg // Remove all interfaces this pass implements, for which it is also
10157330f729Sjoerg // listed as the available implementation.
10167330f729Sjoerg const std::vector<const PassInfo*> &II = PInf->getInterfacesImplemented();
10177330f729Sjoerg for (unsigned i = 0, e = II.size(); i != e; ++i) {
10187330f729Sjoerg DenseMap<AnalysisID, Pass*>::iterator Pos =
10197330f729Sjoerg AvailableAnalysis.find(II[i]->getTypeInfo());
10207330f729Sjoerg if (Pos != AvailableAnalysis.end() && Pos->second == P)
10217330f729Sjoerg AvailableAnalysis.erase(Pos);
10227330f729Sjoerg }
10237330f729Sjoerg }
10247330f729Sjoerg }
10257330f729Sjoerg
10267330f729Sjoerg /// Add pass P into the PassVector. Update
10277330f729Sjoerg /// AvailableAnalysis appropriately if ProcessAnalysis is true.
add(Pass * P,bool ProcessAnalysis)10287330f729Sjoerg void PMDataManager::add(Pass *P, bool ProcessAnalysis) {
10297330f729Sjoerg // This manager is going to manage pass P. Set up analysis resolver
10307330f729Sjoerg // to connect them.
10317330f729Sjoerg AnalysisResolver *AR = new AnalysisResolver(*this);
10327330f729Sjoerg P->setResolver(AR);
10337330f729Sjoerg
10347330f729Sjoerg // If a FunctionPass F is the last user of ModulePass info M
10357330f729Sjoerg // then the F's manager, not F, records itself as a last user of M.
10367330f729Sjoerg SmallVector<Pass *, 12> TransferLastUses;
10377330f729Sjoerg
10387330f729Sjoerg if (!ProcessAnalysis) {
10397330f729Sjoerg // Add pass
10407330f729Sjoerg PassVector.push_back(P);
10417330f729Sjoerg return;
10427330f729Sjoerg }
10437330f729Sjoerg
10447330f729Sjoerg // At the moment, this pass is the last user of all required passes.
10457330f729Sjoerg SmallVector<Pass *, 12> LastUses;
10467330f729Sjoerg SmallVector<Pass *, 8> UsedPasses;
10477330f729Sjoerg SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable;
10487330f729Sjoerg
10497330f729Sjoerg unsigned PDepth = this->getDepth();
10507330f729Sjoerg
10517330f729Sjoerg collectRequiredAndUsedAnalyses(UsedPasses, ReqAnalysisNotAvailable, P);
10527330f729Sjoerg for (Pass *PUsed : UsedPasses) {
10537330f729Sjoerg unsigned RDepth = 0;
10547330f729Sjoerg
10557330f729Sjoerg assert(PUsed->getResolver() && "Analysis Resolver is not set");
10567330f729Sjoerg PMDataManager &DM = PUsed->getResolver()->getPMDataManager();
10577330f729Sjoerg RDepth = DM.getDepth();
10587330f729Sjoerg
10597330f729Sjoerg if (PDepth == RDepth)
10607330f729Sjoerg LastUses.push_back(PUsed);
10617330f729Sjoerg else if (PDepth > RDepth) {
10627330f729Sjoerg // Let the parent claim responsibility of last use
10637330f729Sjoerg TransferLastUses.push_back(PUsed);
10647330f729Sjoerg // Keep track of higher level analysis used by this manager.
10657330f729Sjoerg HigherLevelAnalysis.push_back(PUsed);
10667330f729Sjoerg } else
10677330f729Sjoerg llvm_unreachable("Unable to accommodate Used Pass");
10687330f729Sjoerg }
10697330f729Sjoerg
10707330f729Sjoerg // Set P as P's last user until someone starts using P.
10717330f729Sjoerg // However, if P is a Pass Manager then it does not need
10727330f729Sjoerg // to record its last user.
10737330f729Sjoerg if (!P->getAsPMDataManager())
10747330f729Sjoerg LastUses.push_back(P);
10757330f729Sjoerg TPM->setLastUser(LastUses, P);
10767330f729Sjoerg
10777330f729Sjoerg if (!TransferLastUses.empty()) {
10787330f729Sjoerg Pass *My_PM = getAsPass();
10797330f729Sjoerg TPM->setLastUser(TransferLastUses, My_PM);
10807330f729Sjoerg TransferLastUses.clear();
10817330f729Sjoerg }
10827330f729Sjoerg
10837330f729Sjoerg // Now, take care of required analyses that are not available.
10847330f729Sjoerg for (AnalysisID ID : ReqAnalysisNotAvailable) {
10857330f729Sjoerg const PassInfo *PI = TPM->findAnalysisPassInfo(ID);
10867330f729Sjoerg Pass *AnalysisPass = PI->createPass();
10877330f729Sjoerg this->addLowerLevelRequiredPass(P, AnalysisPass);
10887330f729Sjoerg }
10897330f729Sjoerg
10907330f729Sjoerg // Take a note of analysis required and made available by this pass.
10917330f729Sjoerg // Remove the analysis not preserved by this pass
10927330f729Sjoerg removeNotPreservedAnalysis(P);
10937330f729Sjoerg recordAvailableAnalysis(P);
10947330f729Sjoerg
10957330f729Sjoerg // Add pass
10967330f729Sjoerg PassVector.push_back(P);
10977330f729Sjoerg }
10987330f729Sjoerg
10997330f729Sjoerg
11007330f729Sjoerg /// Populate UP with analysis pass that are used or required by
11017330f729Sjoerg /// pass P and are available. Populate RP_NotAvail with analysis
11027330f729Sjoerg /// pass that are required by pass P but are not available.
collectRequiredAndUsedAnalyses(SmallVectorImpl<Pass * > & UP,SmallVectorImpl<AnalysisID> & RP_NotAvail,Pass * P)11037330f729Sjoerg void PMDataManager::collectRequiredAndUsedAnalyses(
11047330f729Sjoerg SmallVectorImpl<Pass *> &UP, SmallVectorImpl<AnalysisID> &RP_NotAvail,
11057330f729Sjoerg Pass *P) {
11067330f729Sjoerg AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
11077330f729Sjoerg
11087330f729Sjoerg for (const auto &UsedID : AnUsage->getUsedSet())
11097330f729Sjoerg if (Pass *AnalysisPass = findAnalysisPass(UsedID, true))
11107330f729Sjoerg UP.push_back(AnalysisPass);
11117330f729Sjoerg
11127330f729Sjoerg for (const auto &RequiredID : AnUsage->getRequiredSet())
11137330f729Sjoerg if (Pass *AnalysisPass = findAnalysisPass(RequiredID, true))
11147330f729Sjoerg UP.push_back(AnalysisPass);
11157330f729Sjoerg else
11167330f729Sjoerg RP_NotAvail.push_back(RequiredID);
11177330f729Sjoerg }
11187330f729Sjoerg
11197330f729Sjoerg // All Required analyses should be available to the pass as it runs! Here
11207330f729Sjoerg // we fill in the AnalysisImpls member of the pass so that it can
11217330f729Sjoerg // successfully use the getAnalysis() method to retrieve the
11227330f729Sjoerg // implementations it needs.
11237330f729Sjoerg //
initializeAnalysisImpl(Pass * P)11247330f729Sjoerg void PMDataManager::initializeAnalysisImpl(Pass *P) {
11257330f729Sjoerg AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
11267330f729Sjoerg
11277330f729Sjoerg for (const AnalysisID ID : AnUsage->getRequiredSet()) {
11287330f729Sjoerg Pass *Impl = findAnalysisPass(ID, true);
11297330f729Sjoerg if (!Impl)
11307330f729Sjoerg // This may be analysis pass that is initialized on the fly.
11317330f729Sjoerg // If that is not the case then it will raise an assert when it is used.
11327330f729Sjoerg continue;
11337330f729Sjoerg AnalysisResolver *AR = P->getResolver();
11347330f729Sjoerg assert(AR && "Analysis Resolver is not set");
11357330f729Sjoerg AR->addAnalysisImplsPair(ID, Impl);
11367330f729Sjoerg }
11377330f729Sjoerg }
11387330f729Sjoerg
11397330f729Sjoerg /// Find the pass that implements Analysis AID. If desired pass is not found
11407330f729Sjoerg /// then return NULL.
findAnalysisPass(AnalysisID AID,bool SearchParent)11417330f729Sjoerg Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) {
11427330f729Sjoerg
11437330f729Sjoerg // Check if AvailableAnalysis map has one entry.
11447330f729Sjoerg DenseMap<AnalysisID, Pass*>::const_iterator I = AvailableAnalysis.find(AID);
11457330f729Sjoerg
11467330f729Sjoerg if (I != AvailableAnalysis.end())
11477330f729Sjoerg return I->second;
11487330f729Sjoerg
11497330f729Sjoerg // Search Parents through TopLevelManager
11507330f729Sjoerg if (SearchParent)
11517330f729Sjoerg return TPM->findAnalysisPass(AID);
11527330f729Sjoerg
11537330f729Sjoerg return nullptr;
11547330f729Sjoerg }
11557330f729Sjoerg
11567330f729Sjoerg // Print list of passes that are last used by P.
dumpLastUses(Pass * P,unsigned Offset) const11577330f729Sjoerg void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{
1158*82d56013Sjoerg if (PassDebugging < Details)
1159*82d56013Sjoerg return;
11607330f729Sjoerg
11617330f729Sjoerg SmallVector<Pass *, 12> LUses;
11627330f729Sjoerg
11637330f729Sjoerg // If this is a on the fly manager then it does not have TPM.
11647330f729Sjoerg if (!TPM)
11657330f729Sjoerg return;
11667330f729Sjoerg
11677330f729Sjoerg TPM->collectLastUses(LUses, P);
11687330f729Sjoerg
11697330f729Sjoerg for (Pass *P : LUses) {
11707330f729Sjoerg dbgs() << "--" << std::string(Offset*2, ' ');
11717330f729Sjoerg P->dumpPassStructure(0);
11727330f729Sjoerg }
11737330f729Sjoerg }
11747330f729Sjoerg
dumpPassArguments() const11757330f729Sjoerg void PMDataManager::dumpPassArguments() const {
11767330f729Sjoerg for (Pass *P : PassVector) {
11777330f729Sjoerg if (PMDataManager *PMD = P->getAsPMDataManager())
11787330f729Sjoerg PMD->dumpPassArguments();
11797330f729Sjoerg else
11807330f729Sjoerg if (const PassInfo *PI =
11817330f729Sjoerg TPM->findAnalysisPassInfo(P->getPassID()))
11827330f729Sjoerg if (!PI->isAnalysisGroup())
11837330f729Sjoerg dbgs() << " -" << PI->getPassArgument();
11847330f729Sjoerg }
11857330f729Sjoerg }
11867330f729Sjoerg
dumpPassInfo(Pass * P,enum PassDebuggingString S1,enum PassDebuggingString S2,StringRef Msg)11877330f729Sjoerg void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1,
11887330f729Sjoerg enum PassDebuggingString S2,
11897330f729Sjoerg StringRef Msg) {
11907330f729Sjoerg if (PassDebugging < Executions)
11917330f729Sjoerg return;
11927330f729Sjoerg dbgs() << "[" << std::chrono::system_clock::now() << "] " << (void *)this
11937330f729Sjoerg << std::string(getDepth() * 2 + 1, ' ');
11947330f729Sjoerg switch (S1) {
11957330f729Sjoerg case EXECUTION_MSG:
11967330f729Sjoerg dbgs() << "Executing Pass '" << P->getPassName();
11977330f729Sjoerg break;
11987330f729Sjoerg case MODIFICATION_MSG:
11997330f729Sjoerg dbgs() << "Made Modification '" << P->getPassName();
12007330f729Sjoerg break;
12017330f729Sjoerg case FREEING_MSG:
12027330f729Sjoerg dbgs() << " Freeing Pass '" << P->getPassName();
12037330f729Sjoerg break;
12047330f729Sjoerg default:
12057330f729Sjoerg break;
12067330f729Sjoerg }
12077330f729Sjoerg switch (S2) {
12087330f729Sjoerg case ON_FUNCTION_MSG:
12097330f729Sjoerg dbgs() << "' on Function '" << Msg << "'...\n";
12107330f729Sjoerg break;
12117330f729Sjoerg case ON_MODULE_MSG:
12127330f729Sjoerg dbgs() << "' on Module '" << Msg << "'...\n";
12137330f729Sjoerg break;
12147330f729Sjoerg case ON_REGION_MSG:
12157330f729Sjoerg dbgs() << "' on Region '" << Msg << "'...\n";
12167330f729Sjoerg break;
12177330f729Sjoerg case ON_LOOP_MSG:
12187330f729Sjoerg dbgs() << "' on Loop '" << Msg << "'...\n";
12197330f729Sjoerg break;
12207330f729Sjoerg case ON_CG_MSG:
12217330f729Sjoerg dbgs() << "' on Call Graph Nodes '" << Msg << "'...\n";
12227330f729Sjoerg break;
12237330f729Sjoerg default:
12247330f729Sjoerg break;
12257330f729Sjoerg }
12267330f729Sjoerg }
12277330f729Sjoerg
dumpRequiredSet(const Pass * P) const12287330f729Sjoerg void PMDataManager::dumpRequiredSet(const Pass *P) const {
12297330f729Sjoerg if (PassDebugging < Details)
12307330f729Sjoerg return;
12317330f729Sjoerg
12327330f729Sjoerg AnalysisUsage analysisUsage;
12337330f729Sjoerg P->getAnalysisUsage(analysisUsage);
12347330f729Sjoerg dumpAnalysisUsage("Required", P, analysisUsage.getRequiredSet());
12357330f729Sjoerg }
12367330f729Sjoerg
dumpPreservedSet(const Pass * P) const12377330f729Sjoerg void PMDataManager::dumpPreservedSet(const Pass *P) const {
12387330f729Sjoerg if (PassDebugging < Details)
12397330f729Sjoerg return;
12407330f729Sjoerg
12417330f729Sjoerg AnalysisUsage analysisUsage;
12427330f729Sjoerg P->getAnalysisUsage(analysisUsage);
12437330f729Sjoerg dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet());
12447330f729Sjoerg }
12457330f729Sjoerg
dumpUsedSet(const Pass * P) const12467330f729Sjoerg void PMDataManager::dumpUsedSet(const Pass *P) const {
12477330f729Sjoerg if (PassDebugging < Details)
12487330f729Sjoerg return;
12497330f729Sjoerg
12507330f729Sjoerg AnalysisUsage analysisUsage;
12517330f729Sjoerg P->getAnalysisUsage(analysisUsage);
12527330f729Sjoerg dumpAnalysisUsage("Used", P, analysisUsage.getUsedSet());
12537330f729Sjoerg }
12547330f729Sjoerg
dumpAnalysisUsage(StringRef Msg,const Pass * P,const AnalysisUsage::VectorType & Set) const12557330f729Sjoerg void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
12567330f729Sjoerg const AnalysisUsage::VectorType &Set) const {
12577330f729Sjoerg assert(PassDebugging >= Details);
12587330f729Sjoerg if (Set.empty())
12597330f729Sjoerg return;
12607330f729Sjoerg dbgs() << (const void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:";
12617330f729Sjoerg for (unsigned i = 0; i != Set.size(); ++i) {
12627330f729Sjoerg if (i) dbgs() << ',';
12637330f729Sjoerg const PassInfo *PInf = TPM->findAnalysisPassInfo(Set[i]);
12647330f729Sjoerg if (!PInf) {
12657330f729Sjoerg // Some preserved passes, such as AliasAnalysis, may not be initialized by
12667330f729Sjoerg // all drivers.
12677330f729Sjoerg dbgs() << " Uninitialized Pass";
12687330f729Sjoerg continue;
12697330f729Sjoerg }
12707330f729Sjoerg dbgs() << ' ' << PInf->getPassName();
12717330f729Sjoerg }
12727330f729Sjoerg dbgs() << '\n';
12737330f729Sjoerg }
12747330f729Sjoerg
12757330f729Sjoerg /// Add RequiredPass into list of lower level passes required by pass P.
12767330f729Sjoerg /// RequiredPass is run on the fly by Pass Manager when P requests it
12777330f729Sjoerg /// through getAnalysis interface.
12787330f729Sjoerg /// This should be handled by specific pass manager.
addLowerLevelRequiredPass(Pass * P,Pass * RequiredPass)12797330f729Sjoerg void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
12807330f729Sjoerg if (TPM) {
12817330f729Sjoerg TPM->dumpArguments();
12827330f729Sjoerg TPM->dumpPasses();
12837330f729Sjoerg }
12847330f729Sjoerg
12857330f729Sjoerg // Module Level pass may required Function Level analysis info
12867330f729Sjoerg // (e.g. dominator info). Pass manager uses on the fly function pass manager
12877330f729Sjoerg // to provide this on demand. In that case, in Pass manager terminology,
12887330f729Sjoerg // module level pass is requiring lower level analysis info managed by
12897330f729Sjoerg // lower level pass manager.
12907330f729Sjoerg
12917330f729Sjoerg // When Pass manager is not able to order required analysis info, Pass manager
12927330f729Sjoerg // checks whether any lower level manager will be able to provide this
12937330f729Sjoerg // analysis info on demand or not.
12947330f729Sjoerg #ifndef NDEBUG
12957330f729Sjoerg dbgs() << "Unable to schedule '" << RequiredPass->getPassName();
12967330f729Sjoerg dbgs() << "' required by '" << P->getPassName() << "'\n";
12977330f729Sjoerg #endif
12987330f729Sjoerg llvm_unreachable("Unable to schedule pass");
12997330f729Sjoerg }
13007330f729Sjoerg
getOnTheFlyPass(Pass * P,AnalysisID PI,Function & F)1301*82d56013Sjoerg std::tuple<Pass *, bool> PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI,
1302*82d56013Sjoerg Function &F) {
13037330f729Sjoerg llvm_unreachable("Unable to find on the fly pass");
13047330f729Sjoerg }
13057330f729Sjoerg
13067330f729Sjoerg // Destructor
~PMDataManager()13077330f729Sjoerg PMDataManager::~PMDataManager() {
13087330f729Sjoerg for (Pass *P : PassVector)
13097330f729Sjoerg delete P;
13107330f729Sjoerg }
13117330f729Sjoerg
13127330f729Sjoerg //===----------------------------------------------------------------------===//
13137330f729Sjoerg // NOTE: Is this the right place to define this method ?
13147330f729Sjoerg // getAnalysisIfAvailable - Return analysis result or null if it doesn't exist.
getAnalysisIfAvailable(AnalysisID ID) const1315*82d56013Sjoerg Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID) const {
1316*82d56013Sjoerg return PM.findAnalysisPass(ID, true);
13177330f729Sjoerg }
13187330f729Sjoerg
1319*82d56013Sjoerg std::tuple<Pass *, bool>
findImplPass(Pass * P,AnalysisID AnalysisPI,Function & F)1320*82d56013Sjoerg AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, Function &F) {
13217330f729Sjoerg return PM.getOnTheFlyPass(P, AnalysisPI, F);
13227330f729Sjoerg }
13237330f729Sjoerg
1324*82d56013Sjoerg namespace llvm {
1325*82d56013Sjoerg namespace legacy {
13267330f729Sjoerg
13277330f729Sjoerg //===----------------------------------------------------------------------===//
13287330f729Sjoerg // FunctionPassManager implementation
13297330f729Sjoerg
13307330f729Sjoerg /// Create new Function pass manager
FunctionPassManager(Module * m)13317330f729Sjoerg FunctionPassManager::FunctionPassManager(Module *m) : M(m) {
1332*82d56013Sjoerg FPM = new legacy::FunctionPassManagerImpl();
13337330f729Sjoerg // FPM is the top level manager.
13347330f729Sjoerg FPM->setTopLevelManager(FPM);
13357330f729Sjoerg
13367330f729Sjoerg AnalysisResolver *AR = new AnalysisResolver(*FPM);
13377330f729Sjoerg FPM->setResolver(AR);
13387330f729Sjoerg }
13397330f729Sjoerg
~FunctionPassManager()13407330f729Sjoerg FunctionPassManager::~FunctionPassManager() {
13417330f729Sjoerg delete FPM;
13427330f729Sjoerg }
13437330f729Sjoerg
add(Pass * P)13447330f729Sjoerg void FunctionPassManager::add(Pass *P) {
13457330f729Sjoerg FPM->add(P);
13467330f729Sjoerg }
13477330f729Sjoerg
13487330f729Sjoerg /// run - Execute all of the passes scheduled for execution. Keep
13497330f729Sjoerg /// track of whether any of the passes modifies the function, and if
13507330f729Sjoerg /// so, return true.
13517330f729Sjoerg ///
run(Function & F)13527330f729Sjoerg bool FunctionPassManager::run(Function &F) {
13537330f729Sjoerg handleAllErrors(F.materialize(), [&](ErrorInfoBase &EIB) {
13547330f729Sjoerg report_fatal_error("Error reading bitcode file: " + EIB.message());
13557330f729Sjoerg });
13567330f729Sjoerg return FPM->run(F);
13577330f729Sjoerg }
13587330f729Sjoerg
13597330f729Sjoerg
13607330f729Sjoerg /// doInitialization - Run all of the initializers for the function passes.
13617330f729Sjoerg ///
doInitialization()13627330f729Sjoerg bool FunctionPassManager::doInitialization() {
13637330f729Sjoerg return FPM->doInitialization(*M);
13647330f729Sjoerg }
13657330f729Sjoerg
13667330f729Sjoerg /// doFinalization - Run all of the finalizers for the function passes.
13677330f729Sjoerg ///
doFinalization()13687330f729Sjoerg bool FunctionPassManager::doFinalization() {
13697330f729Sjoerg return FPM->doFinalization(*M);
13707330f729Sjoerg }
1371*82d56013Sjoerg } // namespace legacy
1372*82d56013Sjoerg } // namespace llvm
13737330f729Sjoerg
13747330f729Sjoerg /// cleanup - After running all passes, clean up pass manager cache.
cleanup()13757330f729Sjoerg void FPPassManager::cleanup() {
13767330f729Sjoerg for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
13777330f729Sjoerg FunctionPass *FP = getContainedPass(Index);
13787330f729Sjoerg AnalysisResolver *AR = FP->getResolver();
13797330f729Sjoerg assert(AR && "Analysis Resolver is not set");
13807330f729Sjoerg AR->clearAnalysisImpls();
13817330f729Sjoerg }
13827330f729Sjoerg }
13837330f729Sjoerg
13847330f729Sjoerg
13857330f729Sjoerg //===----------------------------------------------------------------------===//
13867330f729Sjoerg // FPPassManager implementation
13877330f729Sjoerg
13887330f729Sjoerg char FPPassManager::ID = 0;
13897330f729Sjoerg /// Print passes managed by this manager
dumpPassStructure(unsigned Offset)13907330f729Sjoerg void FPPassManager::dumpPassStructure(unsigned Offset) {
13917330f729Sjoerg dbgs().indent(Offset*2) << "FunctionPass Manager\n";
13927330f729Sjoerg for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
13937330f729Sjoerg FunctionPass *FP = getContainedPass(Index);
13947330f729Sjoerg FP->dumpPassStructure(Offset + 1);
13957330f729Sjoerg dumpLastUses(FP, Offset+1);
13967330f729Sjoerg }
13977330f729Sjoerg }
13987330f729Sjoerg
13997330f729Sjoerg /// Execute all of the passes scheduled for execution by invoking
14007330f729Sjoerg /// runOnFunction method. Keep track of whether any of the passes modifies
14017330f729Sjoerg /// the function, and if so, return true.
runOnFunction(Function & F)14027330f729Sjoerg bool FPPassManager::runOnFunction(Function &F) {
14037330f729Sjoerg if (F.isDeclaration())
14047330f729Sjoerg return false;
14057330f729Sjoerg
14067330f729Sjoerg bool Changed = false;
14077330f729Sjoerg Module &M = *F.getParent();
14087330f729Sjoerg // Collect inherited analysis from Module level pass manager.
14097330f729Sjoerg populateInheritedAnalysis(TPM->activeStack);
14107330f729Sjoerg
14117330f729Sjoerg unsigned InstrCount, FunctionSize = 0;
14127330f729Sjoerg StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
14137330f729Sjoerg bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
14147330f729Sjoerg // Collect the initial size of the module.
14157330f729Sjoerg if (EmitICRemark) {
14167330f729Sjoerg InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
14177330f729Sjoerg FunctionSize = F.getInstructionCount();
14187330f729Sjoerg }
14197330f729Sjoerg
14207330f729Sjoerg llvm::TimeTraceScope FunctionScope("OptFunction", F.getName());
14217330f729Sjoerg
14227330f729Sjoerg for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
14237330f729Sjoerg FunctionPass *FP = getContainedPass(Index);
14247330f729Sjoerg bool LocalChanged = false;
14257330f729Sjoerg
14267330f729Sjoerg llvm::TimeTraceScope PassScope("RunPass", FP->getPassName());
14277330f729Sjoerg
14287330f729Sjoerg dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName());
14297330f729Sjoerg dumpRequiredSet(FP);
14307330f729Sjoerg
14317330f729Sjoerg initializeAnalysisImpl(FP);
14327330f729Sjoerg
14337330f729Sjoerg {
14347330f729Sjoerg PassManagerPrettyStackEntry X(FP, F);
14357330f729Sjoerg TimeRegion PassTimer(getPassTimer(FP));
1436*82d56013Sjoerg #ifdef EXPENSIVE_CHECKS
1437*82d56013Sjoerg uint64_t RefHash = StructuralHash(F);
1438*82d56013Sjoerg #endif
14397330f729Sjoerg LocalChanged |= FP->runOnFunction(F);
1440*82d56013Sjoerg
1441*82d56013Sjoerg #if defined(EXPENSIVE_CHECKS) && !defined(NDEBUG)
1442*82d56013Sjoerg if (!LocalChanged && (RefHash != StructuralHash(F))) {
1443*82d56013Sjoerg llvm::errs() << "Pass modifies its input and doesn't report it: "
1444*82d56013Sjoerg << FP->getPassName() << "\n";
1445*82d56013Sjoerg llvm_unreachable("Pass modifies its input and doesn't report it");
1446*82d56013Sjoerg }
1447*82d56013Sjoerg #endif
1448*82d56013Sjoerg
14497330f729Sjoerg if (EmitICRemark) {
14507330f729Sjoerg unsigned NewSize = F.getInstructionCount();
14517330f729Sjoerg
14527330f729Sjoerg // Update the size of the function, emit a remark, and update the size
14537330f729Sjoerg // of the module.
14547330f729Sjoerg if (NewSize != FunctionSize) {
14557330f729Sjoerg int64_t Delta = static_cast<int64_t>(NewSize) -
14567330f729Sjoerg static_cast<int64_t>(FunctionSize);
14577330f729Sjoerg emitInstrCountChangedRemark(FP, M, Delta, InstrCount,
14587330f729Sjoerg FunctionToInstrCount, &F);
14597330f729Sjoerg InstrCount = static_cast<int64_t>(InstrCount) + Delta;
14607330f729Sjoerg FunctionSize = NewSize;
14617330f729Sjoerg }
14627330f729Sjoerg }
14637330f729Sjoerg }
14647330f729Sjoerg
14657330f729Sjoerg Changed |= LocalChanged;
14667330f729Sjoerg if (LocalChanged)
14677330f729Sjoerg dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName());
14687330f729Sjoerg dumpPreservedSet(FP);
14697330f729Sjoerg dumpUsedSet(FP);
14707330f729Sjoerg
14717330f729Sjoerg verifyPreservedAnalysis(FP);
1472*82d56013Sjoerg if (LocalChanged)
14737330f729Sjoerg removeNotPreservedAnalysis(FP);
14747330f729Sjoerg recordAvailableAnalysis(FP);
14757330f729Sjoerg removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG);
14767330f729Sjoerg }
14777330f729Sjoerg
14787330f729Sjoerg return Changed;
14797330f729Sjoerg }
14807330f729Sjoerg
runOnModule(Module & M)14817330f729Sjoerg bool FPPassManager::runOnModule(Module &M) {
14827330f729Sjoerg bool Changed = false;
14837330f729Sjoerg
14847330f729Sjoerg for (Function &F : M)
14857330f729Sjoerg Changed |= runOnFunction(F);
14867330f729Sjoerg
14877330f729Sjoerg return Changed;
14887330f729Sjoerg }
14897330f729Sjoerg
doInitialization(Module & M)14907330f729Sjoerg bool FPPassManager::doInitialization(Module &M) {
14917330f729Sjoerg bool Changed = false;
14927330f729Sjoerg
14937330f729Sjoerg for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
14947330f729Sjoerg Changed |= getContainedPass(Index)->doInitialization(M);
14957330f729Sjoerg
14967330f729Sjoerg return Changed;
14977330f729Sjoerg }
14987330f729Sjoerg
doFinalization(Module & M)14997330f729Sjoerg bool FPPassManager::doFinalization(Module &M) {
15007330f729Sjoerg bool Changed = false;
15017330f729Sjoerg
15027330f729Sjoerg for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
15037330f729Sjoerg Changed |= getContainedPass(Index)->doFinalization(M);
15047330f729Sjoerg
15057330f729Sjoerg return Changed;
15067330f729Sjoerg }
15077330f729Sjoerg
15087330f729Sjoerg //===----------------------------------------------------------------------===//
15097330f729Sjoerg // MPPassManager implementation
15107330f729Sjoerg
15117330f729Sjoerg /// Execute all of the passes scheduled for execution by invoking
15127330f729Sjoerg /// runOnModule method. Keep track of whether any of the passes modifies
15137330f729Sjoerg /// the module, and if so, return true.
15147330f729Sjoerg bool
runOnModule(Module & M)15157330f729Sjoerg MPPassManager::runOnModule(Module &M) {
15167330f729Sjoerg llvm::TimeTraceScope TimeScope("OptModule", M.getName());
15177330f729Sjoerg
15187330f729Sjoerg bool Changed = false;
15197330f729Sjoerg
15207330f729Sjoerg // Initialize on-the-fly passes
15217330f729Sjoerg for (auto &OnTheFlyManager : OnTheFlyManagers) {
1522*82d56013Sjoerg legacy::FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
15237330f729Sjoerg Changed |= FPP->doInitialization(M);
15247330f729Sjoerg }
15257330f729Sjoerg
15267330f729Sjoerg // Initialize module passes
15277330f729Sjoerg for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index)
15287330f729Sjoerg Changed |= getContainedPass(Index)->doInitialization(M);
15297330f729Sjoerg
15307330f729Sjoerg unsigned InstrCount;
15317330f729Sjoerg StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
15327330f729Sjoerg bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
15337330f729Sjoerg // Collect the initial size of the module.
15347330f729Sjoerg if (EmitICRemark)
15357330f729Sjoerg InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
15367330f729Sjoerg
15377330f729Sjoerg for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
15387330f729Sjoerg ModulePass *MP = getContainedPass(Index);
15397330f729Sjoerg bool LocalChanged = false;
15407330f729Sjoerg
15417330f729Sjoerg dumpPassInfo(MP, EXECUTION_MSG, ON_MODULE_MSG, M.getModuleIdentifier());
15427330f729Sjoerg dumpRequiredSet(MP);
15437330f729Sjoerg
15447330f729Sjoerg initializeAnalysisImpl(MP);
15457330f729Sjoerg
15467330f729Sjoerg {
15477330f729Sjoerg PassManagerPrettyStackEntry X(MP, M);
15487330f729Sjoerg TimeRegion PassTimer(getPassTimer(MP));
15497330f729Sjoerg
1550*82d56013Sjoerg #ifdef EXPENSIVE_CHECKS
1551*82d56013Sjoerg uint64_t RefHash = StructuralHash(M);
1552*82d56013Sjoerg #endif
1553*82d56013Sjoerg
15547330f729Sjoerg LocalChanged |= MP->runOnModule(M);
1555*82d56013Sjoerg
1556*82d56013Sjoerg #ifdef EXPENSIVE_CHECKS
1557*82d56013Sjoerg assert((LocalChanged || (RefHash == StructuralHash(M))) &&
1558*82d56013Sjoerg "Pass modifies its input and doesn't report it.");
1559*82d56013Sjoerg #endif
1560*82d56013Sjoerg
15617330f729Sjoerg if (EmitICRemark) {
15627330f729Sjoerg // Update the size of the module.
15637330f729Sjoerg unsigned ModuleCount = M.getInstructionCount();
15647330f729Sjoerg if (ModuleCount != InstrCount) {
15657330f729Sjoerg int64_t Delta = static_cast<int64_t>(ModuleCount) -
15667330f729Sjoerg static_cast<int64_t>(InstrCount);
15677330f729Sjoerg emitInstrCountChangedRemark(MP, M, Delta, InstrCount,
15687330f729Sjoerg FunctionToInstrCount);
15697330f729Sjoerg InstrCount = ModuleCount;
15707330f729Sjoerg }
15717330f729Sjoerg }
15727330f729Sjoerg }
15737330f729Sjoerg
15747330f729Sjoerg Changed |= LocalChanged;
15757330f729Sjoerg if (LocalChanged)
15767330f729Sjoerg dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
15777330f729Sjoerg M.getModuleIdentifier());
15787330f729Sjoerg dumpPreservedSet(MP);
15797330f729Sjoerg dumpUsedSet(MP);
15807330f729Sjoerg
15817330f729Sjoerg verifyPreservedAnalysis(MP);
1582*82d56013Sjoerg if (LocalChanged)
15837330f729Sjoerg removeNotPreservedAnalysis(MP);
15847330f729Sjoerg recordAvailableAnalysis(MP);
15857330f729Sjoerg removeDeadPasses(MP, M.getModuleIdentifier(), ON_MODULE_MSG);
15867330f729Sjoerg }
15877330f729Sjoerg
15887330f729Sjoerg // Finalize module passes
15897330f729Sjoerg for (int Index = getNumContainedPasses() - 1; Index >= 0; --Index)
15907330f729Sjoerg Changed |= getContainedPass(Index)->doFinalization(M);
15917330f729Sjoerg
15927330f729Sjoerg // Finalize on-the-fly passes
15937330f729Sjoerg for (auto &OnTheFlyManager : OnTheFlyManagers) {
1594*82d56013Sjoerg legacy::FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
15957330f729Sjoerg // We don't know when is the last time an on-the-fly pass is run,
15967330f729Sjoerg // so we need to releaseMemory / finalize here
15977330f729Sjoerg FPP->releaseMemoryOnTheFly();
15987330f729Sjoerg Changed |= FPP->doFinalization(M);
15997330f729Sjoerg }
16007330f729Sjoerg
16017330f729Sjoerg return Changed;
16027330f729Sjoerg }
16037330f729Sjoerg
16047330f729Sjoerg /// Add RequiredPass into list of lower level passes required by pass P.
16057330f729Sjoerg /// RequiredPass is run on the fly by Pass Manager when P requests it
16067330f729Sjoerg /// through getAnalysis interface.
addLowerLevelRequiredPass(Pass * P,Pass * RequiredPass)16077330f729Sjoerg void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
1608*82d56013Sjoerg assert(RequiredPass && "No required pass?");
16097330f729Sjoerg assert(P->getPotentialPassManagerType() == PMT_ModulePassManager &&
16107330f729Sjoerg "Unable to handle Pass that requires lower level Analysis pass");
16117330f729Sjoerg assert((P->getPotentialPassManagerType() <
16127330f729Sjoerg RequiredPass->getPotentialPassManagerType()) &&
16137330f729Sjoerg "Unable to handle Pass that requires lower level Analysis pass");
16147330f729Sjoerg
1615*82d56013Sjoerg legacy::FunctionPassManagerImpl *FPP = OnTheFlyManagers[P];
16167330f729Sjoerg if (!FPP) {
1617*82d56013Sjoerg FPP = new legacy::FunctionPassManagerImpl();
16187330f729Sjoerg // FPP is the top level manager.
16197330f729Sjoerg FPP->setTopLevelManager(FPP);
16207330f729Sjoerg
16217330f729Sjoerg OnTheFlyManagers[P] = FPP;
16227330f729Sjoerg }
16237330f729Sjoerg const PassInfo *RequiredPassPI =
16247330f729Sjoerg TPM->findAnalysisPassInfo(RequiredPass->getPassID());
16257330f729Sjoerg
16267330f729Sjoerg Pass *FoundPass = nullptr;
16277330f729Sjoerg if (RequiredPassPI && RequiredPassPI->isAnalysis()) {
16287330f729Sjoerg FoundPass =
16297330f729Sjoerg ((PMTopLevelManager*)FPP)->findAnalysisPass(RequiredPass->getPassID());
16307330f729Sjoerg }
16317330f729Sjoerg if (!FoundPass) {
16327330f729Sjoerg FoundPass = RequiredPass;
16337330f729Sjoerg // This should be guaranteed to add RequiredPass to the passmanager given
16347330f729Sjoerg // that we checked for an available analysis above.
16357330f729Sjoerg FPP->add(RequiredPass);
16367330f729Sjoerg }
16377330f729Sjoerg // Register P as the last user of FoundPass or RequiredPass.
16387330f729Sjoerg SmallVector<Pass *, 1> LU;
16397330f729Sjoerg LU.push_back(FoundPass);
16407330f729Sjoerg FPP->setLastUser(LU, P);
16417330f729Sjoerg }
16427330f729Sjoerg
16437330f729Sjoerg /// Return function pass corresponding to PassInfo PI, that is
16447330f729Sjoerg /// required by module pass MP. Instantiate analysis pass, by using
16457330f729Sjoerg /// its runOnFunction() for function F.
getOnTheFlyPass(Pass * MP,AnalysisID PI,Function & F)1646*82d56013Sjoerg std::tuple<Pass *, bool> MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI,
1647*82d56013Sjoerg Function &F) {
1648*82d56013Sjoerg legacy::FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP];
16497330f729Sjoerg assert(FPP && "Unable to find on the fly pass");
16507330f729Sjoerg
16517330f729Sjoerg FPP->releaseMemoryOnTheFly();
1652*82d56013Sjoerg bool Changed = FPP->run(F);
1653*82d56013Sjoerg return std::make_tuple(((PMTopLevelManager *)FPP)->findAnalysisPass(PI),
1654*82d56013Sjoerg Changed);
16557330f729Sjoerg }
16567330f729Sjoerg
1657*82d56013Sjoerg namespace llvm {
1658*82d56013Sjoerg namespace legacy {
16597330f729Sjoerg
16607330f729Sjoerg //===----------------------------------------------------------------------===//
16617330f729Sjoerg // PassManager implementation
16627330f729Sjoerg
16637330f729Sjoerg /// Create new pass manager
PassManager()16647330f729Sjoerg PassManager::PassManager() {
16657330f729Sjoerg PM = new PassManagerImpl();
16667330f729Sjoerg // PM is the top level manager
16677330f729Sjoerg PM->setTopLevelManager(PM);
16687330f729Sjoerg }
16697330f729Sjoerg
~PassManager()16707330f729Sjoerg PassManager::~PassManager() {
16717330f729Sjoerg delete PM;
16727330f729Sjoerg }
16737330f729Sjoerg
add(Pass * P)16747330f729Sjoerg void PassManager::add(Pass *P) {
16757330f729Sjoerg PM->add(P);
16767330f729Sjoerg }
16777330f729Sjoerg
16787330f729Sjoerg /// run - Execute all of the passes scheduled for execution. Keep track of
16797330f729Sjoerg /// whether any of the passes modifies the module, and if so, return true.
run(Module & M)16807330f729Sjoerg bool PassManager::run(Module &M) {
16817330f729Sjoerg return PM->run(M);
16827330f729Sjoerg }
1683*82d56013Sjoerg } // namespace legacy
1684*82d56013Sjoerg } // namespace llvm
16857330f729Sjoerg
16867330f729Sjoerg //===----------------------------------------------------------------------===//
16877330f729Sjoerg // PMStack implementation
16887330f729Sjoerg //
16897330f729Sjoerg
16907330f729Sjoerg // Pop Pass Manager from the stack and clear its analysis info.
pop()16917330f729Sjoerg void PMStack::pop() {
16927330f729Sjoerg
16937330f729Sjoerg PMDataManager *Top = this->top();
16947330f729Sjoerg Top->initializeAnalysisInfo();
16957330f729Sjoerg
16967330f729Sjoerg S.pop_back();
16977330f729Sjoerg }
16987330f729Sjoerg
16997330f729Sjoerg // Push PM on the stack and set its top level manager.
push(PMDataManager * PM)17007330f729Sjoerg void PMStack::push(PMDataManager *PM) {
17017330f729Sjoerg assert(PM && "Unable to push. Pass Manager expected");
17027330f729Sjoerg assert(PM->getDepth()==0 && "Pass Manager depth set too early");
17037330f729Sjoerg
17047330f729Sjoerg if (!this->empty()) {
17057330f729Sjoerg assert(PM->getPassManagerType() > this->top()->getPassManagerType()
17067330f729Sjoerg && "pushing bad pass manager to PMStack");
17077330f729Sjoerg PMTopLevelManager *TPM = this->top()->getTopLevelManager();
17087330f729Sjoerg
17097330f729Sjoerg assert(TPM && "Unable to find top level manager");
17107330f729Sjoerg TPM->addIndirectPassManager(PM);
17117330f729Sjoerg PM->setTopLevelManager(TPM);
17127330f729Sjoerg PM->setDepth(this->top()->getDepth()+1);
17137330f729Sjoerg } else {
17147330f729Sjoerg assert((PM->getPassManagerType() == PMT_ModulePassManager
17157330f729Sjoerg || PM->getPassManagerType() == PMT_FunctionPassManager)
17167330f729Sjoerg && "pushing bad pass manager to PMStack");
17177330f729Sjoerg PM->setDepth(1);
17187330f729Sjoerg }
17197330f729Sjoerg
17207330f729Sjoerg S.push_back(PM);
17217330f729Sjoerg }
17227330f729Sjoerg
17237330f729Sjoerg // Dump content of the pass manager stack.
dump() const17247330f729Sjoerg LLVM_DUMP_METHOD void PMStack::dump() const {
17257330f729Sjoerg for (PMDataManager *Manager : S)
17267330f729Sjoerg dbgs() << Manager->getAsPass()->getPassName() << ' ';
17277330f729Sjoerg
17287330f729Sjoerg if (!S.empty())
17297330f729Sjoerg dbgs() << '\n';
17307330f729Sjoerg }
17317330f729Sjoerg
17327330f729Sjoerg /// Find appropriate Module Pass Manager in the PM Stack and
17337330f729Sjoerg /// add self into that manager.
assignPassManager(PMStack & PMS,PassManagerType PreferredType)17347330f729Sjoerg void ModulePass::assignPassManager(PMStack &PMS,
17357330f729Sjoerg PassManagerType PreferredType) {
17367330f729Sjoerg // Find Module Pass Manager
1737*82d56013Sjoerg PassManagerType T;
1738*82d56013Sjoerg while ((T = PMS.top()->getPassManagerType()) > PMT_ModulePassManager &&
1739*82d56013Sjoerg T != PreferredType)
1740*82d56013Sjoerg PMS.pop();
17417330f729Sjoerg PMS.top()->add(this);
17427330f729Sjoerg }
17437330f729Sjoerg
17447330f729Sjoerg /// Find appropriate Function Pass Manager or Call Graph Pass Manager
17457330f729Sjoerg /// in the PM Stack and add self into that manager.
assignPassManager(PMStack & PMS,PassManagerType)17467330f729Sjoerg void FunctionPass::assignPassManager(PMStack &PMS,
1747*82d56013Sjoerg PassManagerType /*PreferredType*/) {
17487330f729Sjoerg // Find Function Pass Manager
1749*82d56013Sjoerg PMDataManager *PM;
1750*82d56013Sjoerg while (PM = PMS.top(), PM->getPassManagerType() > PMT_FunctionPassManager)
17517330f729Sjoerg PMS.pop();
17527330f729Sjoerg
17537330f729Sjoerg // Create new Function Pass Manager if needed.
1754*82d56013Sjoerg if (PM->getPassManagerType() != PMT_FunctionPassManager) {
17557330f729Sjoerg // [1] Create new Function Pass Manager
1756*82d56013Sjoerg auto *FPP = new FPPassManager;
17577330f729Sjoerg FPP->populateInheritedAnalysis(PMS);
17587330f729Sjoerg
17597330f729Sjoerg // [2] Set up new manager's top level manager
1760*82d56013Sjoerg PM->getTopLevelManager()->addIndirectPassManager(FPP);
17617330f729Sjoerg
17627330f729Sjoerg // [3] Assign manager to manage this new manager. This may create
17637330f729Sjoerg // and push new managers into PMS
1764*82d56013Sjoerg FPP->assignPassManager(PMS, PM->getPassManagerType());
17657330f729Sjoerg
17667330f729Sjoerg // [4] Push new manager into PMS
17677330f729Sjoerg PMS.push(FPP);
1768*82d56013Sjoerg PM = FPP;
17697330f729Sjoerg }
17707330f729Sjoerg
17717330f729Sjoerg // Assign FPP as the manager of this pass.
1772*82d56013Sjoerg PM->add(this);
17737330f729Sjoerg }
17747330f729Sjoerg
~PassManagerBase()1775*82d56013Sjoerg legacy::PassManagerBase::~PassManagerBase() {}
1776