Home | History | Annotate | Line # | Download | only in Analysis
      1 //===- LoopAnalysisManager.h - Loop analysis management ---------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 /// \file
      9 ///
     10 /// This header provides classes for managing per-loop analyses. These are
     11 /// typically used as part of a loop pass pipeline over the loop nests of
     12 /// a function.
     13 ///
     14 /// Loop analyses are allowed to make some simplifying assumptions:
     15 /// 1) Loops are, where possible, in simplified form.
     16 /// 2) Loops are *always* in LCSSA form.
     17 /// 3) A collection of analysis results are available:
     18 ///    - LoopInfo
     19 ///    - DominatorTree
     20 ///    - ScalarEvolution
     21 ///    - AAManager
     22 ///
     23 /// The primary mechanism to provide these invariants is the loop pass manager,
     24 /// but they can also be manually provided in order to reason about a loop from
     25 /// outside of a dedicated pass manager.
     26 ///
     27 //===----------------------------------------------------------------------===//
     28 
     29 #ifndef LLVM_ANALYSIS_LOOPANALYSISMANAGER_H
     30 #define LLVM_ANALYSIS_LOOPANALYSISMANAGER_H
     31 
     32 #include "llvm/ADT/PostOrderIterator.h"
     33 #include "llvm/IR/PassManager.h"
     34 
     35 namespace llvm {
     36 
     37 class AAResults;
     38 class AssumptionCache;
     39 class DominatorTree;
     40 class Function;
     41 class Loop;
     42 class LoopInfo;
     43 class MemorySSA;
     44 class ScalarEvolution;
     45 class TargetLibraryInfo;
     46 class TargetTransformInfo;
     47 
     48 /// The adaptor from a function pass to a loop pass computes these analyses and
     49 /// makes them available to the loop passes "for free". Each loop pass is
     50 /// expected to update these analyses if necessary to ensure they're
     51 /// valid after it runs.
     52 struct LoopStandardAnalysisResults {
     53   AAResults &AA;
     54   AssumptionCache ∾
     55   DominatorTree &DT;
     56   LoopInfo &LI;
     57   ScalarEvolution &SE;
     58   TargetLibraryInfo &TLI;
     59   TargetTransformInfo &TTI;
     60   BlockFrequencyInfo *BFI;
     61   MemorySSA *MSSA;
     62 };
     63 
     64 /// Extern template declaration for the analysis set for this IR unit.
     65 extern template class AllAnalysesOn<Loop>;
     66 
     67 extern template class AnalysisManager<Loop, LoopStandardAnalysisResults &>;
     68 /// The loop analysis manager.
     69 ///
     70 /// See the documentation for the AnalysisManager template for detail
     71 /// documentation. This typedef serves as a convenient way to refer to this
     72 /// construct in the adaptors and proxies used to integrate this into the larger
     73 /// pass manager infrastructure.
     74 typedef AnalysisManager<Loop, LoopStandardAnalysisResults &>
     75     LoopAnalysisManager;
     76 
     77 /// A proxy from a \c LoopAnalysisManager to a \c Function.
     78 typedef InnerAnalysisManagerProxy<LoopAnalysisManager, Function>
     79     LoopAnalysisManagerFunctionProxy;
     80 
     81 /// A specialized result for the \c LoopAnalysisManagerFunctionProxy which
     82 /// retains a \c LoopInfo reference.
     83 ///
     84 /// This allows it to collect loop objects for which analysis results may be
     85 /// cached in the \c LoopAnalysisManager.
     86 template <> class LoopAnalysisManagerFunctionProxy::Result {
     87 public:
     88   explicit Result(LoopAnalysisManager &InnerAM, LoopInfo &LI)
     89       : InnerAM(&InnerAM), LI(&LI), MSSAUsed(false) {}
     90   Result(Result &&Arg)
     91       : InnerAM(std::move(Arg.InnerAM)), LI(Arg.LI), MSSAUsed(Arg.MSSAUsed) {
     92     // We have to null out the analysis manager in the moved-from state
     93     // because we are taking ownership of the responsibilty to clear the
     94     // analysis state.
     95     Arg.InnerAM = nullptr;
     96   }
     97   Result &operator=(Result &&RHS) {
     98     InnerAM = RHS.InnerAM;
     99     LI = RHS.LI;
    100     MSSAUsed = RHS.MSSAUsed;
    101     // We have to null out the analysis manager in the moved-from state
    102     // because we are taking ownership of the responsibilty to clear the
    103     // analysis state.
    104     RHS.InnerAM = nullptr;
    105     return *this;
    106   }
    107   ~Result() {
    108     // InnerAM is cleared in a moved from state where there is nothing to do.
    109     if (!InnerAM)
    110       return;
    111 
    112     // Clear out the analysis manager if we're being destroyed -- it means we
    113     // didn't even see an invalidate call when we got invalidated.
    114     InnerAM->clear();
    115   }
    116 
    117   /// Mark MemorySSA as used so we can invalidate self if MSSA is invalidated.
    118   void markMSSAUsed() { MSSAUsed = true; }
    119 
    120   /// Accessor for the analysis manager.
    121   LoopAnalysisManager &getManager() { return *InnerAM; }
    122 
    123   /// Handler for invalidation of the proxy for a particular function.
    124   ///
    125   /// If the proxy, \c LoopInfo, and associated analyses are preserved, this
    126   /// will merely forward the invalidation event to any cached loop analysis
    127   /// results for loops within this function.
    128   ///
    129   /// If the necessary loop infrastructure is not preserved, this will forcibly
    130   /// clear all of the cached analysis results that are keyed on the \c
    131   /// LoopInfo for this function.
    132   bool invalidate(Function &F, const PreservedAnalyses &PA,
    133                   FunctionAnalysisManager::Invalidator &Inv);
    134 
    135 private:
    136   LoopAnalysisManager *InnerAM;
    137   LoopInfo *LI;
    138   bool MSSAUsed;
    139 };
    140 
    141 /// Provide a specialized run method for the \c LoopAnalysisManagerFunctionProxy
    142 /// so it can pass the \c LoopInfo to the result.
    143 template <>
    144 LoopAnalysisManagerFunctionProxy::Result
    145 LoopAnalysisManagerFunctionProxy::run(Function &F, FunctionAnalysisManager &AM);
    146 
    147 // Ensure the \c LoopAnalysisManagerFunctionProxy is provided as an extern
    148 // template.
    149 extern template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
    150 
    151 extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop,
    152                                                 LoopStandardAnalysisResults &>;
    153 /// A proxy from a \c FunctionAnalysisManager to a \c Loop.
    154 typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop,
    155                                   LoopStandardAnalysisResults &>
    156     FunctionAnalysisManagerLoopProxy;
    157 
    158 /// Returns the minimum set of Analyses that all loop passes must preserve.
    159 PreservedAnalyses getLoopPassPreservedAnalyses();
    160 }
    161 
    162 #endif // LLVM_ANALYSIS_LOOPANALYSISMANAGER_H
    163