xref: /netbsd-src/external/apache2/llvm/dist/llvm/include/llvm/Transforms/Utils/UnrollLoop.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 //===- llvm/Transforms/Utils/UnrollLoop.h - Unrolling utilities -*- 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 // This file defines some loop unrolling utilities. It does not define any
10 // actual pass or policy, but provides a single function to perform loop
11 // unrolling.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
16 #define LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
17 
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/Analysis/TargetTransformInfo.h"
20 #include "llvm/Transforms/Scalar/LoopPassManager.h"
21 
22 namespace llvm {
23 
24 class AssumptionCache;
25 class BasicBlock;
26 class BlockFrequencyInfo;
27 class DependenceInfo;
28 class DominatorTree;
29 class Loop;
30 class LoopInfo;
31 class MDNode;
32 class ProfileSummaryInfo;
33 class OptimizationRemarkEmitter;
34 class ScalarEvolution;
35 class StringRef;
36 class Value;
37 
38 using NewLoopsMap = SmallDenseMap<const Loop *, Loop *, 4>;
39 
40 /// @{
41 /// Metadata attribute names
42 const char *const LLVMLoopUnrollFollowupAll = "llvm.loop.unroll.followup_all";
43 const char *const LLVMLoopUnrollFollowupUnrolled =
44     "llvm.loop.unroll.followup_unrolled";
45 const char *const LLVMLoopUnrollFollowupRemainder =
46     "llvm.loop.unroll.followup_remainder";
47 /// @}
48 
49 const Loop* addClonedBlockToLoopInfo(BasicBlock *OriginalBB,
50                                      BasicBlock *ClonedBB, LoopInfo *LI,
51                                      NewLoopsMap &NewLoops);
52 
53 /// Represents the result of a \c UnrollLoop invocation.
54 enum class LoopUnrollResult {
55   /// The loop was not modified.
56   Unmodified,
57 
58   /// The loop was partially unrolled -- we still have a loop, but with a
59   /// smaller trip count.  We may also have emitted epilogue loop if the loop
60   /// had a non-constant trip count.
61   PartiallyUnrolled,
62 
63   /// The loop was fully unrolled into straight-line code.  We no longer have
64   /// any back-edges.
65   FullyUnrolled
66 };
67 
68 struct UnrollLoopOptions {
69   unsigned Count;
70   unsigned TripCount;
71   bool Force;
72   bool AllowRuntime;
73   bool AllowExpensiveTripCount;
74   bool PreserveCondBr;
75   bool PreserveOnlyFirst;
76   unsigned TripMultiple;
77   unsigned PeelCount;
78   bool UnrollRemainder;
79   bool ForgetAllSCEV;
80 };
81 
82 LoopUnrollResult UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
83                             ScalarEvolution *SE, DominatorTree *DT,
84                             AssumptionCache *AC,
85                             const llvm::TargetTransformInfo *TTI,
86                             OptimizationRemarkEmitter *ORE, bool PreserveLCSSA,
87                             Loop **RemainderLoop = nullptr);
88 
89 bool UnrollRuntimeLoopRemainder(
90     Loop *L, unsigned Count, bool AllowExpensiveTripCount,
91     bool UseEpilogRemainder, bool UnrollRemainder, bool ForgetAllSCEV,
92     LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
93     const TargetTransformInfo *TTI, bool PreserveLCSSA,
94     Loop **ResultLoop = nullptr);
95 
96 LoopUnrollResult UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
97                                   unsigned TripMultiple, bool UnrollRemainder,
98                                   LoopInfo *LI, ScalarEvolution *SE,
99                                   DominatorTree *DT, AssumptionCache *AC,
100                                   const TargetTransformInfo *TTI,
101                                   OptimizationRemarkEmitter *ORE, LPMUpdater *U,
102                                   Loop **EpilogueLoop = nullptr);
103 
104 bool isSafeToUnrollAndJam(Loop *L, ScalarEvolution &SE, DominatorTree &DT,
105                           DependenceInfo &DI, LoopInfo &LI);
106 
107 bool computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
108                         DominatorTree &DT, LoopInfo *LI, ScalarEvolution &SE,
109                         const SmallPtrSetImpl<const Value *> &EphValues,
110                         OptimizationRemarkEmitter *ORE, unsigned &TripCount,
111                         unsigned MaxTripCount, bool MaxOrZero,
112                         unsigned &TripMultiple, unsigned LoopSize,
113                         TargetTransformInfo::UnrollingPreferences &UP,
114                         TargetTransformInfo::PeelingPreferences &PP,
115                         bool &UseUpperBound);
116 
117 void simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI,
118                              ScalarEvolution *SE, DominatorTree *DT,
119                              AssumptionCache *AC,
120                              const TargetTransformInfo *TTI);
121 
122 MDNode *GetUnrollMetadata(MDNode *LoopID, StringRef Name);
123 
124 TargetTransformInfo::UnrollingPreferences gatherUnrollingPreferences(
125     Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI,
126     BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, int OptLevel,
127     Optional<unsigned> UserThreshold, Optional<unsigned> UserCount,
128     Optional<bool> UserAllowPartial, Optional<bool> UserRuntime,
129     Optional<bool> UserUpperBound, Optional<unsigned> UserFullUnrollMaxCount);
130 
131 unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls,
132                              bool &NotDuplicatable, bool &Convergent,
133                              const TargetTransformInfo &TTI,
134                              const SmallPtrSetImpl<const Value *> &EphValues,
135                              unsigned BEInsns);
136 
137 } // end namespace llvm
138 
139 #endif // LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
140