Home | History | Annotate | Line # | Download | only in Scalar
      1 //===- LoopUnrollPass.h -----------------------------------------*- 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 
      9 #ifndef LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H
     10 #define LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H
     11 
     12 #include "llvm/ADT/Optional.h"
     13 #include "llvm/Analysis/LoopAnalysisManager.h"
     14 #include "llvm/IR/PassManager.h"
     15 #include "llvm/Support/CommandLine.h"
     16 
     17 namespace llvm {
     18 
     19 extern cl::opt<bool> ForgetSCEVInLoopUnroll;
     20 
     21 class Function;
     22 class Loop;
     23 class LPMUpdater;
     24 
     25 /// Loop unroll pass that only does full loop unrolling and peeling.
     26 class LoopFullUnrollPass : public PassInfoMixin<LoopFullUnrollPass> {
     27   const int OptLevel;
     28 
     29   /// If false, use a cost model to determine whether unrolling of a loop is
     30   /// profitable. If true, only loops that explicitly request unrolling via
     31   /// metadata are considered. All other loops are skipped.
     32   const bool OnlyWhenForced;
     33 
     34   /// If true, forget all loops when unrolling. If false, forget top-most loop
     35   /// of the currently processed loops, which removes one entry at a time from
     36   /// the internal SCEV records. For large loops, the former is faster.
     37   const bool ForgetSCEV;
     38 
     39 public:
     40   explicit LoopFullUnrollPass(int OptLevel = 2, bool OnlyWhenForced = false,
     41                               bool ForgetSCEV = false)
     42       : OptLevel(OptLevel), OnlyWhenForced(OnlyWhenForced),
     43         ForgetSCEV(ForgetSCEV) {}
     44 
     45   PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
     46                         LoopStandardAnalysisResults &AR, LPMUpdater &U);
     47 };
     48 
     49 /// A set of parameters used to control various transforms performed by the
     50 /// LoopUnroll pass. Each of the boolean parameters can be set to:
     51 ///      true - enabling the transformation.
     52 ///      false - disabling the transformation.
     53 ///      None - relying on a global default.
     54 ///
     55 /// There is also OptLevel parameter, which is used for additional loop unroll
     56 /// tuning.
     57 ///
     58 /// Intended use is to create a default object, modify parameters with
     59 /// additional setters and then pass it to LoopUnrollPass.
     60 ///
     61 struct LoopUnrollOptions {
     62   Optional<bool> AllowPartial;
     63   Optional<bool> AllowPeeling;
     64   Optional<bool> AllowRuntime;
     65   Optional<bool> AllowUpperBound;
     66   Optional<bool> AllowProfileBasedPeeling;
     67   Optional<unsigned> FullUnrollMaxCount;
     68   int OptLevel;
     69 
     70   /// If false, use a cost model to determine whether unrolling of a loop is
     71   /// profitable. If true, only loops that explicitly request unrolling via
     72   /// metadata are considered. All other loops are skipped.
     73   bool OnlyWhenForced;
     74 
     75   /// If true, forget all loops when unrolling. If false, forget top-most loop
     76   /// of the currently processed loops, which removes one entry at a time from
     77   /// the internal SCEV records. For large loops, the former is faster.
     78   const bool ForgetSCEV;
     79 
     80   LoopUnrollOptions(int OptLevel = 2, bool OnlyWhenForced = false,
     81                     bool ForgetSCEV = false)
     82       : OptLevel(OptLevel), OnlyWhenForced(OnlyWhenForced),
     83         ForgetSCEV(ForgetSCEV) {}
     84 
     85   /// Enables or disables partial unrolling. When disabled only full unrolling
     86   /// is allowed.
     87   LoopUnrollOptions &setPartial(bool Partial) {
     88     AllowPartial = Partial;
     89     return *this;
     90   }
     91 
     92   /// Enables or disables unrolling of loops with runtime trip count.
     93   LoopUnrollOptions &setRuntime(bool Runtime) {
     94     AllowRuntime = Runtime;
     95     return *this;
     96   }
     97 
     98   /// Enables or disables loop peeling.
     99   LoopUnrollOptions &setPeeling(bool Peeling) {
    100     AllowPeeling = Peeling;
    101     return *this;
    102   }
    103 
    104   /// Enables or disables the use of trip count upper bound
    105   /// in loop unrolling.
    106   LoopUnrollOptions &setUpperBound(bool UpperBound) {
    107     AllowUpperBound = UpperBound;
    108     return *this;
    109   }
    110 
    111   // Sets "optimization level" tuning parameter for loop unrolling.
    112   LoopUnrollOptions &setOptLevel(int O) {
    113     OptLevel = O;
    114     return *this;
    115   }
    116 
    117   // Enables or disables loop peeling basing on profile.
    118   LoopUnrollOptions &setProfileBasedPeeling(int O) {
    119     AllowProfileBasedPeeling = O;
    120     return *this;
    121   }
    122 
    123   // Sets the max full unroll count.
    124   LoopUnrollOptions &setFullUnrollMaxCount(unsigned O) {
    125     FullUnrollMaxCount = O;
    126     return *this;
    127   }
    128 };
    129 
    130 /// Loop unroll pass that will support both full and partial unrolling.
    131 /// It is a function pass to have access to function and module analyses.
    132 /// It will also put loops into canonical form (simplified and LCSSA).
    133 class LoopUnrollPass : public PassInfoMixin<LoopUnrollPass> {
    134   LoopUnrollOptions UnrollOpts;
    135 
    136 public:
    137   /// This uses the target information (or flags) to control the thresholds for
    138   /// different unrolling stategies but supports all of them.
    139   explicit LoopUnrollPass(LoopUnrollOptions UnrollOpts = {})
    140       : UnrollOpts(UnrollOpts) {}
    141 
    142   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
    143 };
    144 
    145 } // end namespace llvm
    146 
    147 #endif // LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H
    148