Home | History | Annotate | Download | only in Analysis
      1 //===- LoopPassManager.h - Loop pass management -----------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 /// \file
     10 ///
     11 /// This header provides classes for managing passes over loops in LLVM IR.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_ANALYSIS_LOOPPASSMANAGER_H
     16 #define LLVM_ANALYSIS_LOOPPASSMANAGER_H
     17 
     18 #include "llvm/ADT/STLExtras.h"
     19 #include "llvm/Analysis/LoopInfo.h"
     20 #include "llvm/IR/PassManager.h"
     21 
     22 namespace llvm {
     23 
     24 extern template class PassManager<Loop>;
     25 /// \brief The loop pass manager.
     26 ///
     27 /// See the documentation for the PassManager template for details. It runs a
     28 /// sequency of loop passes over each loop that the manager is run over. This
     29 /// typedef serves as a convenient way to refer to this construct.
     30 typedef PassManager<Loop> LoopPassManager;
     31 
     32 extern template class AnalysisManager<Loop>;
     33 /// \brief The loop analysis manager.
     34 ///
     35 /// See the documentation for the AnalysisManager template for detail
     36 /// documentation. This typedef serves as a convenient way to refer to this
     37 /// construct in the adaptors and proxies used to integrate this into the larger
     38 /// pass manager infrastructure.
     39 typedef AnalysisManager<Loop> LoopAnalysisManager;
     40 
     41 extern template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
     42 /// A proxy from a \c LoopAnalysisManager to a \c Function.
     43 typedef InnerAnalysisManagerProxy<LoopAnalysisManager, Function>
     44     LoopAnalysisManagerFunctionProxy;
     45 
     46 extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>;
     47 /// A proxy from a \c FunctionAnalysisManager to a \c Loop.
     48 typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>
     49     FunctionAnalysisManagerLoopProxy;
     50 
     51 /// Returns the minimum set of Analyses that all loop passes must preserve.
     52 PreservedAnalyses getLoopPassPreservedAnalyses();
     53 
     54 /// \brief Adaptor that maps from a function to its loops.
     55 ///
     56 /// Designed to allow composition of a LoopPass(Manager) and a
     57 /// FunctionPassManager. Note that if this pass is constructed with a \c
     58 /// FunctionAnalysisManager it will run the \c LoopAnalysisManagerFunctionProxy
     59 /// analysis prior to running the loop passes over the function to enable a \c
     60 /// LoopAnalysisManager to be used within this run safely.
     61 template <typename LoopPassT>
     62 class FunctionToLoopPassAdaptor
     63     : public PassInfoMixin<FunctionToLoopPassAdaptor<LoopPassT>> {
     64 public:
     65   explicit FunctionToLoopPassAdaptor(LoopPassT Pass)
     66       : Pass(std::move(Pass)) {}
     67   // We have to explicitly define all the special member functions because MSVC
     68   // refuses to generate them.
     69   FunctionToLoopPassAdaptor(const FunctionToLoopPassAdaptor &Arg)
     70       : Pass(Arg.Pass) {}
     71   FunctionToLoopPassAdaptor(FunctionToLoopPassAdaptor &&Arg)
     72       : Pass(std::move(Arg.Pass)) {}
     73   friend void swap(FunctionToLoopPassAdaptor &LHS,
     74                    FunctionToLoopPassAdaptor &RHS) {
     75     using std::swap;
     76     swap(LHS.Pass, RHS.Pass);
     77   }
     78   FunctionToLoopPassAdaptor &operator=(FunctionToLoopPassAdaptor RHS) {
     79     swap(*this, RHS);
     80     return *this;
     81   }
     82 
     83   /// \brief Runs the loop passes across every loop in the function.
     84   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
     85     // Setup the loop analysis manager from its proxy.
     86     LoopAnalysisManager &LAM =
     87         AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
     88     // Get the loop structure for this function
     89     LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
     90 
     91     PreservedAnalyses PA = PreservedAnalyses::all();
     92 
     93     // We want to visit the loops in reverse post-order. We'll build the stack
     94     // of loops to visit in Loops by first walking the loops in pre-order.
     95     SmallVector<Loop *, 2> Loops;
     96     SmallVector<Loop *, 2> WorkList(LI.begin(), LI.end());
     97     while (!WorkList.empty()) {
     98       Loop *L = WorkList.pop_back_val();
     99       WorkList.insert(WorkList.end(), L->begin(), L->end());
    100       Loops.push_back(L);
    101     }
    102 
    103     // Now pop each element off of the stack to visit the loops in reverse
    104     // post-order.
    105     for (auto *L : reverse(Loops)) {
    106       PreservedAnalyses PassPA = Pass.run(*L, LAM);
    107       assert(PassPA.preserved(getLoopPassPreservedAnalyses()) &&
    108              "Loop passes must preserve all relevant analyses");
    109 
    110       // We know that the loop pass couldn't have invalidated any other loop's
    111       // analyses (that's the contract of a loop pass), so directly handle the
    112       // loop analysis manager's invalidation here.  Also, update the
    113       // preserved analyses to reflect that once invalidated these can again
    114       // be preserved.
    115       PassPA = LAM.invalidate(*L, std::move(PassPA));
    116 
    117       // Then intersect the preserved set so that invalidation of module
    118       // analyses will eventually occur when the module pass completes.
    119       PA.intersect(std::move(PassPA));
    120     }
    121 
    122     // By definition we preserve the proxy. This precludes *any* invalidation of
    123     // loop analyses by the proxy, but that's OK because we've taken care to
    124     // invalidate analyses in the loop analysis manager incrementally above.
    125     PA.preserve<LoopAnalysisManagerFunctionProxy>();
    126     return PA;
    127   }
    128 
    129 private:
    130   LoopPassT Pass;
    131 };
    132 
    133 /// \brief A function to deduce a loop pass type and wrap it in the templated
    134 /// adaptor.
    135 template <typename LoopPassT>
    136 FunctionToLoopPassAdaptor<LoopPassT>
    137 createFunctionToLoopPassAdaptor(LoopPassT Pass) {
    138   return FunctionToLoopPassAdaptor<LoopPassT>(std::move(Pass));
    139 }
    140 }
    141 
    142 #endif // LLVM_ANALYSIS_LOOPPASSMANAGER_H
    143