1f1a29dd3SDimitry Andric //===- LoopPassManager.cpp - Loop pass management -------------------------===//
2f1a29dd3SDimitry Andric //
3f1a29dd3SDimitry Andric // The LLVM Compiler Infrastructure
4f1a29dd3SDimitry Andric //
5f1a29dd3SDimitry Andric // This file is distributed under the University of Illinois Open Source
6f1a29dd3SDimitry Andric // License. See LICENSE.TXT for details.
7f1a29dd3SDimitry Andric //
8f1a29dd3SDimitry Andric //===----------------------------------------------------------------------===//
9f1a29dd3SDimitry Andric
10f1a29dd3SDimitry Andric #include "llvm/Transforms/Scalar/LoopPassManager.h"
11f1a29dd3SDimitry Andric #include "llvm/Analysis/LoopInfo.h"
12f1a29dd3SDimitry Andric
13f1a29dd3SDimitry Andric using namespace llvm;
14f1a29dd3SDimitry Andric
15f1a29dd3SDimitry Andric // Explicit template instantiations and specialization defininitions for core
16f1a29dd3SDimitry Andric // template typedefs.
17f1a29dd3SDimitry Andric namespace llvm {
18f1a29dd3SDimitry Andric template class PassManager<Loop, LoopAnalysisManager,
19f1a29dd3SDimitry Andric LoopStandardAnalysisResults &, LPMUpdater &>;
20f1a29dd3SDimitry Andric
21f1a29dd3SDimitry Andric /// Explicitly specialize the pass manager's run method to handle loop nest
22f1a29dd3SDimitry Andric /// structure updates.
23f1a29dd3SDimitry Andric template <>
24f1a29dd3SDimitry Andric PreservedAnalyses
25f1a29dd3SDimitry Andric PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
run(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)26f1a29dd3SDimitry Andric LPMUpdater &>::run(Loop &L, LoopAnalysisManager &AM,
27f1a29dd3SDimitry Andric LoopStandardAnalysisResults &AR, LPMUpdater &U) {
28f1a29dd3SDimitry Andric PreservedAnalyses PA = PreservedAnalyses::all();
29f1a29dd3SDimitry Andric
30f1a29dd3SDimitry Andric if (DebugLogging)
31f1a29dd3SDimitry Andric dbgs() << "Starting Loop pass manager run.\n";
32f1a29dd3SDimitry Andric
33*b5893f02SDimitry Andric // Request PassInstrumentation from analysis manager, will use it to run
34*b5893f02SDimitry Andric // instrumenting callbacks for the passes later.
35*b5893f02SDimitry Andric PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(L, AR);
36f1a29dd3SDimitry Andric for (auto &Pass : Passes) {
37f1a29dd3SDimitry Andric if (DebugLogging)
38f1a29dd3SDimitry Andric dbgs() << "Running pass: " << Pass->name() << " on " << L;
39f1a29dd3SDimitry Andric
40*b5893f02SDimitry Andric // Check the PassInstrumentation's BeforePass callbacks before running the
41*b5893f02SDimitry Andric // pass, skip its execution completely if asked to (callback returns false).
42*b5893f02SDimitry Andric if (!PI.runBeforePass<Loop>(*Pass, L))
43*b5893f02SDimitry Andric continue;
44*b5893f02SDimitry Andric
45f1a29dd3SDimitry Andric PreservedAnalyses PassPA = Pass->run(L, AM, AR, U);
46f1a29dd3SDimitry Andric
47*b5893f02SDimitry Andric // do not pass deleted Loop into the instrumentation
48*b5893f02SDimitry Andric if (U.skipCurrentLoop())
49*b5893f02SDimitry Andric PI.runAfterPassInvalidated<Loop>(*Pass);
50*b5893f02SDimitry Andric else
51*b5893f02SDimitry Andric PI.runAfterPass<Loop>(*Pass, L);
52*b5893f02SDimitry Andric
53f1a29dd3SDimitry Andric // If the loop was deleted, abort the run and return to the outer walk.
54f1a29dd3SDimitry Andric if (U.skipCurrentLoop()) {
55f1a29dd3SDimitry Andric PA.intersect(std::move(PassPA));
56f1a29dd3SDimitry Andric break;
57f1a29dd3SDimitry Andric }
58f1a29dd3SDimitry Andric
597a7e6055SDimitry Andric #ifndef NDEBUG
607a7e6055SDimitry Andric // Verify the loop structure and LCSSA form before visiting the loop.
617a7e6055SDimitry Andric L.verifyLoop();
627a7e6055SDimitry Andric assert(L.isRecursivelyLCSSAForm(AR.DT, AR.LI) &&
637a7e6055SDimitry Andric "Loops must remain in LCSSA form!");
647a7e6055SDimitry Andric #endif
657a7e6055SDimitry Andric
66f1a29dd3SDimitry Andric // Update the analysis manager as each pass runs and potentially
67f1a29dd3SDimitry Andric // invalidates analyses.
68f1a29dd3SDimitry Andric AM.invalidate(L, PassPA);
69f1a29dd3SDimitry Andric
70f1a29dd3SDimitry Andric // Finally, we intersect the final preserved analyses to compute the
71f1a29dd3SDimitry Andric // aggregate preserved set for this pass manager.
72f1a29dd3SDimitry Andric PA.intersect(std::move(PassPA));
73f1a29dd3SDimitry Andric
74f1a29dd3SDimitry Andric // FIXME: Historically, the pass managers all called the LLVM context's
75f1a29dd3SDimitry Andric // yield function here. We don't have a generic way to acquire the
76f1a29dd3SDimitry Andric // context and it isn't yet clear what the right pattern is for yielding
77f1a29dd3SDimitry Andric // in the new pass manager so it is currently omitted.
78f1a29dd3SDimitry Andric // ...getContext().yield();
79f1a29dd3SDimitry Andric }
80f1a29dd3SDimitry Andric
81f1a29dd3SDimitry Andric // Invalidation for the current loop should be handled above, and other loop
82f1a29dd3SDimitry Andric // analysis results shouldn't be impacted by runs over this loop. Therefore,
83f1a29dd3SDimitry Andric // the remaining analysis results in the AnalysisManager are preserved. We
84f1a29dd3SDimitry Andric // mark this with a set so that we don't need to inspect each one
85f1a29dd3SDimitry Andric // individually.
86f1a29dd3SDimitry Andric // FIXME: This isn't correct! This loop and all nested loops' analyses should
87f1a29dd3SDimitry Andric // be preserved, but unrolling should invalidate the parent loop's analyses.
88f1a29dd3SDimitry Andric PA.preserveSet<AllAnalysesOn<Loop>>();
89f1a29dd3SDimitry Andric
90f1a29dd3SDimitry Andric if (DebugLogging)
91f1a29dd3SDimitry Andric dbgs() << "Finished Loop pass manager run.\n";
92f1a29dd3SDimitry Andric
93f1a29dd3SDimitry Andric return PA;
94f1a29dd3SDimitry Andric }
95f1a29dd3SDimitry Andric }
96f1a29dd3SDimitry Andric
PrintLoopPass()97f1a29dd3SDimitry Andric PrintLoopPass::PrintLoopPass() : OS(dbgs()) {}
PrintLoopPass(raw_ostream & OS,const std::string & Banner)98f1a29dd3SDimitry Andric PrintLoopPass::PrintLoopPass(raw_ostream &OS, const std::string &Banner)
99f1a29dd3SDimitry Andric : OS(OS), Banner(Banner) {}
100f1a29dd3SDimitry Andric
run(Loop & L,LoopAnalysisManager &,LoopStandardAnalysisResults &,LPMUpdater &)101f1a29dd3SDimitry Andric PreservedAnalyses PrintLoopPass::run(Loop &L, LoopAnalysisManager &,
102f1a29dd3SDimitry Andric LoopStandardAnalysisResults &,
103f1a29dd3SDimitry Andric LPMUpdater &) {
104f1a29dd3SDimitry Andric printLoop(L, OS, Banner);
105f1a29dd3SDimitry Andric return PreservedAnalyses::all();
106f1a29dd3SDimitry Andric }
107