Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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/Support/InstructionCost.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 | bool Force; |
||
71 | bool Runtime; |
||
72 | bool AllowExpensiveTripCount; |
||
73 | bool UnrollRemainder; |
||
74 | bool ForgetAllSCEV; |
||
75 | }; |
||
76 | |||
77 | LoopUnrollResult UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI, |
||
78 | ScalarEvolution *SE, DominatorTree *DT, |
||
79 | AssumptionCache *AC, |
||
80 | const llvm::TargetTransformInfo *TTI, |
||
81 | OptimizationRemarkEmitter *ORE, bool PreserveLCSSA, |
||
82 | Loop **RemainderLoop = nullptr); |
||
83 | |||
84 | bool UnrollRuntimeLoopRemainder( |
||
85 | Loop *L, unsigned Count, bool AllowExpensiveTripCount, |
||
86 | bool UseEpilogRemainder, bool UnrollRemainder, bool ForgetAllSCEV, |
||
87 | LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, |
||
88 | const TargetTransformInfo *TTI, bool PreserveLCSSA, |
||
89 | Loop **ResultLoop = nullptr); |
||
90 | |||
91 | LoopUnrollResult UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount, |
||
92 | unsigned TripMultiple, bool UnrollRemainder, |
||
93 | LoopInfo *LI, ScalarEvolution *SE, |
||
94 | DominatorTree *DT, AssumptionCache *AC, |
||
95 | const TargetTransformInfo *TTI, |
||
96 | OptimizationRemarkEmitter *ORE, |
||
97 | Loop **EpilogueLoop = nullptr); |
||
98 | |||
99 | bool isSafeToUnrollAndJam(Loop *L, ScalarEvolution &SE, DominatorTree &DT, |
||
100 | DependenceInfo &DI, LoopInfo &LI); |
||
101 | |||
102 | bool computeUnrollCount(Loop *L, const TargetTransformInfo &TTI, |
||
103 | DominatorTree &DT, LoopInfo *LI, AssumptionCache *AC, |
||
104 | ScalarEvolution &SE, |
||
105 | const SmallPtrSetImpl<const Value *> &EphValues, |
||
106 | OptimizationRemarkEmitter *ORE, unsigned TripCount, |
||
107 | unsigned MaxTripCount, bool MaxOrZero, |
||
108 | unsigned TripMultiple, unsigned LoopSize, |
||
109 | TargetTransformInfo::UnrollingPreferences &UP, |
||
110 | TargetTransformInfo::PeelingPreferences &PP, |
||
111 | bool &UseUpperBound); |
||
112 | |||
113 | void simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI, |
||
114 | ScalarEvolution *SE, DominatorTree *DT, |
||
115 | AssumptionCache *AC, |
||
116 | const TargetTransformInfo *TTI); |
||
117 | |||
118 | MDNode *GetUnrollMetadata(MDNode *LoopID, StringRef Name); |
||
119 | |||
120 | TargetTransformInfo::UnrollingPreferences gatherUnrollingPreferences( |
||
121 | Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI, |
||
122 | BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, |
||
123 | llvm::OptimizationRemarkEmitter &ORE, int OptLevel, |
||
124 | std::optional<unsigned> UserThreshold, std::optional<unsigned> UserCount, |
||
125 | std::optional<bool> UserAllowPartial, std::optional<bool> UserRuntime, |
||
126 | std::optional<bool> UserUpperBound, |
||
127 | std::optional<unsigned> UserFullUnrollMaxCount); |
||
128 | |||
129 | InstructionCost ApproximateLoopSize(const Loop *L, unsigned &NumCalls, |
||
130 | bool &NotDuplicatable, bool &Convergent, const TargetTransformInfo &TTI, |
||
131 | const SmallPtrSetImpl<const Value *> &EphValues, unsigned BEInsns); |
||
132 | |||
133 | } // end namespace llvm |
||
134 | |||
135 | #endif // LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H |