llvm/lib/Transforms/Scalar/LoopPassManager.cpp
Chandler Carruth f541c74552 [PM] Teach LoopUnroll to update the LPM infrastructure as it unrolls
loops.

We do this by reconstructing the newly added loops after the unroll
completes to avoid threading pass manager details through all the mess
of the unrolling infrastructure.

I've enabled some extra assertions in the LPM to try and catch issues
here and enabled a bunch of unroller tests to try and make sure this is
sane.

Currently, I'm manually running loop-simplify when needed. That should
go away once it is folded into the LPM infrastructure.

Differential Revision: https://reviews.llvm.org/D28848

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293011 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-25 02:49:01 +00:00

93 lines
3.3 KiB
C++

//===- LoopPassManager.cpp - Loop pass management -------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#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";
for (auto &Pass : Passes) {
if (DebugLogging)
dbgs() << "Running pass: " << Pass->name() << " on " << L;
PreservedAnalyses PassPA = Pass->run(L, AM, AR, U);
// 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();
}