1311116Sdim//===- LoopUnrollPass.h -----------------------------------------*- C++ -*-===// 2311116Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6311116Sdim// 7311116Sdim//===----------------------------------------------------------------------===// 8311116Sdim 9311116Sdim#ifndef LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H 10311116Sdim#define LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H 11311116Sdim 12344779Sdim#include "llvm/ADT/Optional.h" 13327952Sdim#include "llvm/Analysis/LoopAnalysisManager.h" 14311116Sdim#include "llvm/IR/PassManager.h" 15360784Sdim#include "llvm/Support/CommandLine.h" 16311116Sdim 17311116Sdimnamespace llvm { 18311116Sdim 19353358Sdimextern cl::opt<bool> ForgetSCEVInLoopUnroll; 20353358Sdim 21327952Sdimclass Function; 22327952Sdimclass Loop; 23327952Sdimclass LPMUpdater; 24327952Sdim 25327952Sdim/// Loop unroll pass that only does full loop unrolling. 26327952Sdimclass LoopFullUnrollPass : public PassInfoMixin<LoopFullUnrollPass> { 27327952Sdim const int OptLevel; 28327952Sdim 29344779Sdim /// If false, use a cost model to determine whether unrolling of a loop is 30344779Sdim /// profitable. If true, only loops that explicitly request unrolling via 31344779Sdim /// metadata are considered. All other loops are skipped. 32344779Sdim const bool OnlyWhenForced; 33344779Sdim 34353358Sdim /// If true, forget all loops when unrolling. If false, forget top-most loop 35353358Sdim /// of the currently processed loops, which removes one entry at a time from 36353358Sdim /// the internal SCEV records. For large loops, the former is faster. 37353358Sdim const bool ForgetSCEV; 38353358Sdim 39327952Sdimpublic: 40353358Sdim explicit LoopFullUnrollPass(int OptLevel = 2, bool OnlyWhenForced = false, 41353358Sdim bool ForgetSCEV = false) 42353358Sdim : OptLevel(OptLevel), OnlyWhenForced(OnlyWhenForced), 43353358Sdim ForgetSCEV(ForgetSCEV) {} 44327952Sdim 45327952Sdim PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, 46327952Sdim LoopStandardAnalysisResults &AR, LPMUpdater &U); 47327952Sdim}; 48327952Sdim 49344779Sdim/// A set of parameters used to control various transforms performed by the 50344779Sdim/// LoopUnroll pass. Each of the boolean parameters can be set to: 51344779Sdim/// true - enabling the transformation. 52344779Sdim/// false - disabling the transformation. 53344779Sdim/// None - relying on a global default. 54344779Sdim/// 55344779Sdim/// There is also OptLevel parameter, which is used for additional loop unroll 56344779Sdim/// tuning. 57344779Sdim/// 58344779Sdim/// Intended use is to create a default object, modify parameters with 59344779Sdim/// additional setters and then pass it to LoopUnrollPass. 60344779Sdim/// 61344779Sdimstruct LoopUnrollOptions { 62344779Sdim Optional<bool> AllowPartial; 63344779Sdim Optional<bool> AllowPeeling; 64344779Sdim Optional<bool> AllowRuntime; 65344779Sdim Optional<bool> AllowUpperBound; 66360784Sdim Optional<bool> AllowProfileBasedPeeling; 67360784Sdim Optional<unsigned> FullUnrollMaxCount; 68344779Sdim int OptLevel; 69344779Sdim 70344779Sdim /// If false, use a cost model to determine whether unrolling of a loop is 71344779Sdim /// profitable. If true, only loops that explicitly request unrolling via 72344779Sdim /// metadata are considered. All other loops are skipped. 73344779Sdim bool OnlyWhenForced; 74344779Sdim 75353358Sdim /// If true, forget all loops when unrolling. If false, forget top-most loop 76353358Sdim /// of the currently processed loops, which removes one entry at a time from 77353358Sdim /// the internal SCEV records. For large loops, the former is faster. 78353358Sdim const bool ForgetSCEV; 79344779Sdim 80353358Sdim LoopUnrollOptions(int OptLevel = 2, bool OnlyWhenForced = false, 81353358Sdim bool ForgetSCEV = false) 82353358Sdim : OptLevel(OptLevel), OnlyWhenForced(OnlyWhenForced), 83353358Sdim ForgetSCEV(ForgetSCEV) {} 84353358Sdim 85344779Sdim /// Enables or disables partial unrolling. When disabled only full unrolling 86344779Sdim /// is allowed. 87344779Sdim LoopUnrollOptions &setPartial(bool Partial) { 88344779Sdim AllowPartial = Partial; 89344779Sdim return *this; 90344779Sdim } 91344779Sdim 92344779Sdim /// Enables or disables unrolling of loops with runtime trip count. 93344779Sdim LoopUnrollOptions &setRuntime(bool Runtime) { 94344779Sdim AllowRuntime = Runtime; 95344779Sdim return *this; 96344779Sdim } 97344779Sdim 98344779Sdim /// Enables or disables loop peeling. 99344779Sdim LoopUnrollOptions &setPeeling(bool Peeling) { 100344779Sdim AllowPeeling = Peeling; 101344779Sdim return *this; 102344779Sdim } 103344779Sdim 104344779Sdim /// Enables or disables the use of trip count upper bound 105344779Sdim /// in loop unrolling. 106344779Sdim LoopUnrollOptions &setUpperBound(bool UpperBound) { 107344779Sdim AllowUpperBound = UpperBound; 108344779Sdim return *this; 109344779Sdim } 110344779Sdim 111344779Sdim // Sets "optimization level" tuning parameter for loop unrolling. 112344779Sdim LoopUnrollOptions &setOptLevel(int O) { 113344779Sdim OptLevel = O; 114344779Sdim return *this; 115344779Sdim } 116360784Sdim 117360784Sdim // Enables or disables loop peeling basing on profile. 118360784Sdim LoopUnrollOptions &setProfileBasedPeeling(int O) { 119360784Sdim AllowProfileBasedPeeling = O; 120360784Sdim return *this; 121360784Sdim } 122360784Sdim 123360784Sdim // Sets the max full unroll count. 124360784Sdim LoopUnrollOptions &setFullUnrollMaxCount(unsigned O) { 125360784Sdim FullUnrollMaxCount = O; 126360784Sdim return *this; 127360784Sdim } 128344779Sdim}; 129344779Sdim 130327952Sdim/// Loop unroll pass that will support both full and partial unrolling. 131327952Sdim/// It is a function pass to have access to function and module analyses. 132327952Sdim/// It will also put loops into canonical form (simplified and LCSSA). 133321369Sdimclass LoopUnrollPass : public PassInfoMixin<LoopUnrollPass> { 134344779Sdim LoopUnrollOptions UnrollOpts; 135311116Sdim 136321369Sdimpublic: 137321369Sdim /// This uses the target information (or flags) to control the thresholds for 138321369Sdim /// different unrolling stategies but supports all of them. 139344779Sdim explicit LoopUnrollPass(LoopUnrollOptions UnrollOpts = {}) 140344779Sdim : UnrollOpts(UnrollOpts) {} 141321369Sdim 142327952Sdim PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 143327952Sdim}; 144321369Sdim 145311116Sdim} // end namespace llvm 146311116Sdim 147311116Sdim#endif // LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H 148