forked from OSchip/llvm-project
106 lines
3.9 KiB
C++
106 lines
3.9 KiB
C++
//===- LoopPassManager.cpp - Loop pass management -------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Transforms/Scalar/LoopPassManager.h"
|
|
#include "llvm/Analysis/LoopInfo.h"
|
|
|
|
using namespace llvm;
|
|
|
|
// Explicit template instantiations and specialization defininitions for core
|
|
// template typedefs.
|
|
namespace llvm {
|
|
template class PassManager<Loop, LoopAnalysisManager,
|
|
LoopStandardAnalysisResults &, LPMUpdater &>;
|
|
|
|
/// Explicitly specialize the pass manager's run method to handle loop nest
|
|
/// structure updates.
|
|
template <>
|
|
PreservedAnalyses
|
|
PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
|
|
LPMUpdater &>::run(Loop &L, LoopAnalysisManager &AM,
|
|
LoopStandardAnalysisResults &AR, LPMUpdater &U) {
|
|
PreservedAnalyses PA = PreservedAnalyses::all();
|
|
|
|
if (DebugLogging)
|
|
dbgs() << "Starting Loop pass manager run.\n";
|
|
|
|
// Request PassInstrumentation from analysis manager, will use it to run
|
|
// instrumenting callbacks for the passes later.
|
|
PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
|
|
for (auto &Pass : Passes) {
|
|
if (DebugLogging)
|
|
dbgs() << "Running pass: " << Pass->name() << " on " << L;
|
|
|
|
// Check the PassInstrumentation's BeforePass callbacks before running the
|
|
// pass, skip its execution completely if asked to (callback returns false).
|
|
if (!PI.runBeforePass<Loop>(*Pass, L))
|
|
continue;
|
|
|
|
PreservedAnalyses PassPA = Pass->run(L, AM, AR, U);
|
|
|
|
// do not pass deleted Loop into the instrumentation
|
|
if (U.skipCurrentLoop())
|
|
PI.runAfterPassInvalidated<Loop>(*Pass);
|
|
else
|
|
PI.runAfterPass<Loop>(*Pass, L);
|
|
|
|
// If the loop was deleted, abort the run and return to the outer walk.
|
|
if (U.skipCurrentLoop()) {
|
|
PA.intersect(std::move(PassPA));
|
|
break;
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
// Verify the loop structure and LCSSA form before visiting the loop.
|
|
L.verifyLoop();
|
|
assert(L.isRecursivelyLCSSAForm(AR.DT, AR.LI) &&
|
|
"Loops must remain in LCSSA form!");
|
|
#endif
|
|
|
|
// Update the analysis manager as each pass runs and potentially
|
|
// invalidates analyses.
|
|
AM.invalidate(L, PassPA);
|
|
|
|
// Finally, we intersect the final preserved analyses to compute the
|
|
// aggregate preserved set for this pass manager.
|
|
PA.intersect(std::move(PassPA));
|
|
|
|
// FIXME: Historically, the pass managers all called the LLVM context's
|
|
// yield function here. We don't have a generic way to acquire the
|
|
// context and it isn't yet clear what the right pattern is for yielding
|
|
// in the new pass manager so it is currently omitted.
|
|
// ...getContext().yield();
|
|
}
|
|
|
|
// Invalidation for the current loop should be handled above, and other loop
|
|
// analysis results shouldn't be impacted by runs over this loop. Therefore,
|
|
// the remaining analysis results in the AnalysisManager are preserved. We
|
|
// mark this with a set so that we don't need to inspect each one
|
|
// individually.
|
|
// FIXME: This isn't correct! This loop and all nested loops' analyses should
|
|
// be preserved, but unrolling should invalidate the parent loop's analyses.
|
|
PA.preserveSet<AllAnalysesOn<Loop>>();
|
|
|
|
if (DebugLogging)
|
|
dbgs() << "Finished Loop pass manager run.\n";
|
|
|
|
return PA;
|
|
}
|
|
}
|
|
|
|
PrintLoopPass::PrintLoopPass() : OS(dbgs()) {}
|
|
PrintLoopPass::PrintLoopPass(raw_ostream &OS, const std::string &Banner)
|
|
: OS(OS), Banner(Banner) {}
|
|
|
|
PreservedAnalyses PrintLoopPass::run(Loop &L, LoopAnalysisManager &,
|
|
LoopStandardAnalysisResults &,
|
|
LPMUpdater &) {
|
|
printLoop(L, OS, Banner);
|
|
return PreservedAnalyses::all();
|
|
}
|