LLVM 23.0.0git
LoopUnrollAndJamPass.cpp
Go to the documentation of this file.
1//===- LoopUnrollAndJam.cpp - Loop unroll and jam pass --------------------===//
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 pass implements an unroll and jam pass. Most of the work is done by
10// Utils/UnrollLoopAndJam.cpp.
11//===----------------------------------------------------------------------===//
12
14#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/StringRef.h"
28#include "llvm/IR/BasicBlock.h"
29#include "llvm/IR/Constants.h"
30#include "llvm/IR/Dominators.h"
31#include "llvm/IR/Function.h"
33#include "llvm/IR/Metadata.h"
34#include "llvm/IR/PassManager.h"
37#include "llvm/Support/Debug.h"
43#include <cassert>
44#include <cstdint>
45
46namespace llvm {
47class Instruction;
48class Value;
49} // namespace llvm
50
51using namespace llvm;
52
53#define DEBUG_TYPE "loop-unroll-and-jam"
54
55/// @{
56/// Metadata attribute names
57static const char *const LLVMLoopUnrollAndJamFollowupAll =
58 "llvm.loop.unroll_and_jam.followup_all";
59static const char *const LLVMLoopUnrollAndJamFollowupInner =
60 "llvm.loop.unroll_and_jam.followup_inner";
61static const char *const LLVMLoopUnrollAndJamFollowupOuter =
62 "llvm.loop.unroll_and_jam.followup_outer";
64 "llvm.loop.unroll_and_jam.followup_remainder_inner";
66 "llvm.loop.unroll_and_jam.followup_remainder_outer";
67/// @}
68
69static cl::opt<bool>
70 AllowUnrollAndJam("allow-unroll-and-jam", cl::Hidden,
71 cl::desc("Allows loops to be unroll-and-jammed."));
72
74 "unroll-and-jam-count", cl::Hidden,
75 cl::desc("Use this unroll count for all loops including those with "
76 "unroll_and_jam_count pragma values, for testing purposes"));
77
79 "unroll-and-jam-threshold", cl::init(60), cl::Hidden,
80 cl::desc("Threshold to use for inner loop when doing unroll and jam."));
81
83 "pragma-unroll-and-jam-threshold", cl::init(1024), cl::Hidden,
84 cl::desc("Unrolled size limit for loops with an unroll_and_jam(full) or "
85 "unroll_count pragma."));
86
87// Returns true if the loop has any metadata starting with Prefix. For example a
88// Prefix of "llvm.loop.unroll." returns true if we have any unroll metadata.
89static bool hasAnyUnrollPragma(const Loop *L, StringRef Prefix) {
90 if (MDNode *LoopID = L->getLoopID()) {
91 // First operand should refer to the loop id itself.
92 assert(LoopID->getNumOperands() > 0 && "requires at least one operand");
93 assert(LoopID->getOperand(0) == LoopID && "invalid loop id");
94
95 for (unsigned I = 1, E = LoopID->getNumOperands(); I < E; ++I) {
96 MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(I));
97 if (!MD)
98 continue;
99
101 if (!S)
102 continue;
103
104 if (S->getString().starts_with(Prefix))
105 return true;
106 }
107 }
108 return false;
109}
110
111// Returns true if the loop has an unroll_and_jam(enable) pragma.
112static bool hasUnrollAndJamEnablePragma(const Loop *L) {
113 return getUnrollMetadataForLoop(L, "llvm.loop.unroll_and_jam.enable");
114}
115
116// If loop has an unroll_and_jam_count pragma return the (necessarily
117// positive) value from the pragma. Otherwise return 0.
118static unsigned unrollAndJamCountPragmaValue(const Loop *L) {
119 MDNode *MD = getUnrollMetadataForLoop(L, "llvm.loop.unroll_and_jam.count");
120 if (MD) {
121 assert(MD->getNumOperands() == 2 &&
122 "Unroll count hint metadata should have two operands.");
123 unsigned Count =
124 mdconst::extract<ConstantInt>(MD->getOperand(1))->getZExtValue();
125 assert(Count >= 1 && "Unroll count must be positive.");
126 return Count;
127 }
128 return 0;
129}
130
131// Returns loop size estimation for unrolled loop.
132static uint64_t
135 assert(LoopSize >= UP.BEInsns && "LoopSize should not be less than BEInsns!");
136 return static_cast<uint64_t>(LoopSize - UP.BEInsns) * UP.Count + UP.BEInsns;
137}
138
139// Calculates unroll and jam count and writes it to UP.Count. Returns true if
140// unroll count was set explicitly.
142 Loop *L, Loop *SubLoop, const TargetTransformInfo &TTI, DominatorTree &DT,
144 const SmallPtrSetImpl<const Value *> &EphValues,
145 OptimizationRemarkEmitter *ORE, unsigned OuterTripCount,
146 unsigned OuterTripMultiple, const UnrollCostEstimator &OuterUCE,
147 unsigned InnerTripCount, unsigned InnerLoopSize,
150 unsigned OuterLoopSize = OuterUCE.getRolledLoopSize();
151 // First up use computeUnrollCount from the loop unroller to get a count
152 // for unrolling the outer loop, plus any loops requiring explicit
153 // unrolling we leave to the unroller. This uses UP.Threshold /
154 // UP.PartialThreshold / UP.MaxCount to come up with sensible loop values.
155 // We have already checked that the loop has no unroll.* pragmas.
156 computeUnrollCount(L, TTI, DT, LI, AC, SE, EphValues, ORE, OuterTripCount,
157 /*MaxTripCount*/ 0, /*MaxOrZero*/ false, OuterTripMultiple,
158 OuterUCE, UP, PP);
159
160 // Override with any explicit Count from the "unroll-and-jam-count" option.
161 bool UserUnrollCount = UnrollAndJamCount.getNumOccurrences() > 0;
162 if (UserUnrollCount) {
164 UP.Force = true;
165 if (UP.AllowRemainder &&
166 getUnrollAndJammedLoopSize(OuterLoopSize, UP) < UP.Threshold &&
167 getUnrollAndJammedLoopSize(InnerLoopSize, UP) <
169 return true;
170 }
171
172 // Check for unroll_and_jam pragmas
173 unsigned PragmaCount = unrollAndJamCountPragmaValue(L);
174 if (PragmaCount > 0) {
175 UP.Count = PragmaCount;
176 UP.Runtime = true;
177 UP.Force = true;
178 if ((UP.AllowRemainder || (OuterTripMultiple % PragmaCount == 0)) &&
179 getUnrollAndJammedLoopSize(OuterLoopSize, UP) < UP.Threshold &&
180 getUnrollAndJammedLoopSize(InnerLoopSize, UP) <
182 return true;
183 }
184
185 bool PragmaEnableUnroll = hasUnrollAndJamEnablePragma(L);
186 bool ExplicitUnrollAndJamCount = PragmaCount > 0 || UserUnrollCount;
187 bool ExplicitUnrollAndJam = PragmaEnableUnroll || ExplicitUnrollAndJamCount;
188
189 // If the loop has an unrolling pragma, we want to be more aggressive with
190 // unrolling limits.
191 if (ExplicitUnrollAndJam)
193
194 if (!UP.AllowRemainder && getUnrollAndJammedLoopSize(InnerLoopSize, UP) >=
196 LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; can't create remainder and "
197 "inner loop too large\n");
198 UP.Count = 0;
199 return false;
200 }
201
202 // We have a sensible limit for the outer loop, now adjust it for the inner
203 // loop and UP.UnrollAndJamInnerLoopThreshold. If the outer limit was set
204 // explicitly, we want to stick to it.
205 if (!ExplicitUnrollAndJamCount && UP.AllowRemainder) {
206 while (UP.Count != 0 && getUnrollAndJammedLoopSize(InnerLoopSize, UP) >=
208 UP.Count--;
209 }
210
211 // If we are explicitly unroll and jamming, we are done. Otherwise there are a
212 // number of extra performance heuristics to check.
213 if (ExplicitUnrollAndJam)
214 return true;
215
216 // If the inner loop count is known and small, leave the entire loop nest to
217 // be the unroller
218 if (InnerTripCount && InnerLoopSize * InnerTripCount < UP.Threshold) {
219 LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; small inner loop count is "
220 "being left for the unroller\n");
221 UP.Count = 0;
222 return false;
223 }
224
225 // Check for situations where UnJ is likely to be unprofitable. Including
226 // subloops with more than 1 block.
227 if (SubLoop->getBlocks().size() != 1) {
229 dbgs() << "Won't unroll-and-jam; More than one inner loop block\n");
230 UP.Count = 0;
231 return false;
232 }
233
234 // Limit to loops where there is something to gain from unrolling and
235 // jamming the loop. In this case, look for loads that are invariant in the
236 // outer loop and can become shared.
237 unsigned NumInvariant = 0;
238 for (BasicBlock *BB : SubLoop->getBlocks()) {
239 for (Instruction &I : *BB) {
240 if (auto *Ld = dyn_cast<LoadInst>(&I)) {
241 Value *V = Ld->getPointerOperand();
242 const SCEV *LSCEV = SE.getSCEVAtScope(V, L);
243 if (SE.isLoopInvariant(LSCEV, L))
244 NumInvariant++;
245 }
246 }
247 }
248 if (NumInvariant == 0) {
249 LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; No loop invariant loads\n");
250 UP.Count = 0;
251 return false;
252 }
253
254 return false;
255}
256
257static LoopUnrollResult
261 OptimizationRemarkEmitter &ORE, int OptLevel) {
263 L, SE, TTI, nullptr, nullptr, ORE, OptLevel, std::nullopt, std::nullopt,
264 std::nullopt, std::nullopt, std::nullopt, std::nullopt);
266 gatherPeelingPreferences(L, SE, TTI, std::nullopt, std::nullopt);
267
269 if (EnableMode & TM_Disable)
271 if (EnableMode & TM_ForcedByUser)
272 UP.UnrollAndJam = true;
273
274 if (AllowUnrollAndJam.getNumOccurrences() > 0)
276 if (UnrollAndJamThreshold.getNumOccurrences() > 0)
278 // Exit early if unrolling is disabled.
281
282 LLVM_DEBUG(dbgs() << "Loop Unroll and Jam: F["
283 << L->getHeader()->getParent()->getName() << "] Loop %"
284 << L->getHeader()->getName() << "\n");
285
286 // A loop with any unroll pragma (enabling/disabling/count/etc) is left for
287 // the unroller, so long as it does not explicitly have unroll_and_jam
288 // metadata. This means #pragma nounroll will disable unroll and jam as well
289 // as unrolling
290 if (hasAnyUnrollPragma(L, "llvm.loop.unroll.") &&
291 !hasAnyUnrollPragma(L, "llvm.loop.unroll_and_jam.")) {
292 LLVM_DEBUG(dbgs() << " Disabled due to pragma.\n");
294 }
295
296 if (!isSafeToUnrollAndJam(L, SE, DT, DI, *LI)) {
297 LLVM_DEBUG(dbgs() << " Disabled due to not being safe.\n");
299 }
300
301 // Approximate the loop size and collect useful info
303 CodeMetrics::collectEphemeralValues(L, &AC, EphValues);
304 Loop *SubLoop = L->getSubLoops()[0];
305 UnrollCostEstimator InnerUCE(SubLoop, TTI, EphValues, UP.BEInsns);
306 UnrollCostEstimator OuterUCE(L, TTI, EphValues, UP.BEInsns);
307
308 if (!InnerUCE.canUnroll() || !OuterUCE.canUnroll()) {
309 LLVM_DEBUG(dbgs() << " Loop not considered unrollable\n");
311 }
312
313 unsigned InnerLoopSize = InnerUCE.getRolledLoopSize();
314 LLVM_DEBUG(dbgs() << " Outer Loop Size: " << OuterUCE.getRolledLoopSize()
315 << "\n");
316 LLVM_DEBUG(dbgs() << " Inner Loop Size: " << InnerLoopSize << "\n");
317
318 if (InnerUCE.NumInlineCandidates != 0 || OuterUCE.NumInlineCandidates != 0) {
319 LLVM_DEBUG(dbgs() << " Not unrolling loop with inlinable calls.\n");
321 }
322 // FIXME: The call to canUnroll() allows some controlled convergent
323 // operations, but we block them here for future changes.
324 if (InnerUCE.Convergence != ConvergenceKind::None ||
327 dbgs() << " Not unrolling loop with convergent instructions.\n");
329 }
330
331 // Save original loop IDs for after the transformation.
332 MDNode *OrigOuterLoopID = L->getLoopID();
333 MDNode *OrigSubLoopID = SubLoop->getLoopID();
334
335 // To assign the loop id of the epilogue, assign it before unrolling it so it
336 // is applied to every inner loop of the epilogue. We later apply the loop ID
337 // for the jammed inner loop.
338 std::optional<MDNode *> NewInnerEpilogueLoopID = makeFollowupLoopID(
339 OrigOuterLoopID, {LLVMLoopUnrollAndJamFollowupAll,
341 if (NewInnerEpilogueLoopID)
342 SubLoop->setLoopID(*NewInnerEpilogueLoopID);
343
344 // Find trip count and trip multiple
345 BasicBlock *Latch = L->getLoopLatch();
346 BasicBlock *SubLoopLatch = SubLoop->getLoopLatch();
347 unsigned OuterTripCount = SE.getSmallConstantTripCount(L, Latch);
348 unsigned OuterTripMultiple = SE.getSmallConstantTripMultiple(L, Latch);
349 unsigned InnerTripCount = SE.getSmallConstantTripCount(SubLoop, SubLoopLatch);
350
351 // Decide if, and by how much, to unroll
352 bool IsCountSetExplicitly = computeUnrollAndJamCount(
353 L, SubLoop, TTI, DT, LI, &AC, SE, EphValues, &ORE, OuterTripCount,
354 OuterTripMultiple, OuterUCE, InnerTripCount, InnerLoopSize, UP, PP);
355 if (UP.Count <= 1)
357 // Unroll factor (Count) must be less or equal to TripCount.
358 if (OuterTripCount && UP.Count > OuterTripCount)
359 UP.Count = OuterTripCount;
360
361 Loop *EpilogueOuterLoop = nullptr;
362 LoopUnrollResult UnrollResult = UnrollAndJamLoop(
363 L, UP.Count, OuterTripCount, OuterTripMultiple, UP.UnrollRemainder, LI,
364 &SE, &DT, &AC, &TTI, &ORE, &EpilogueOuterLoop);
365
366 // Assign new loop attributes.
367 if (EpilogueOuterLoop) {
368 std::optional<MDNode *> NewOuterEpilogueLoopID = makeFollowupLoopID(
369 OrigOuterLoopID, {LLVMLoopUnrollAndJamFollowupAll,
371 if (NewOuterEpilogueLoopID)
372 EpilogueOuterLoop->setLoopID(*NewOuterEpilogueLoopID);
373 }
374
375 std::optional<MDNode *> NewInnerLoopID =
378 if (NewInnerLoopID)
379 SubLoop->setLoopID(*NewInnerLoopID);
380 else
381 SubLoop->setLoopID(OrigSubLoopID);
382
383 if (UnrollResult == LoopUnrollResult::PartiallyUnrolled) {
384 std::optional<MDNode *> NewOuterLoopID = makeFollowupLoopID(
385 OrigOuterLoopID,
387 if (NewOuterLoopID) {
388 L->setLoopID(*NewOuterLoopID);
389
390 // Do not setLoopAlreadyUnrolled if a followup was given.
391 return UnrollResult;
392 }
393 }
394
395 // If loop has an unroll count pragma or unrolled by explicitly set count
396 // mark loop as unrolled to prevent unrolling beyond that requested.
397 if (UnrollResult != LoopUnrollResult::FullyUnrolled && IsCountSetExplicitly)
398 L->setLoopAlreadyUnrolled();
399
400 return UnrollResult;
401}
402
404 ScalarEvolution &SE,
407 OptimizationRemarkEmitter &ORE, int OptLevel,
408 LPMUpdater &U, bool &AnyLoopRemoved) {
409 bool DidSomething = false;
411 Loop *OutmostLoop = &LN.getOutermostLoop();
412
413 // Add the loop nests in the reverse order of LN. See method
414 // declaration.
416 appendLoopsToWorklist(Loops, Worklist);
417 while (!Worklist.empty()) {
418 Loop *L = Worklist.pop_back_val();
419 std::string LoopName = std::string(L->getName());
420 LoopUnrollResult Result =
421 tryToUnrollAndJamLoop(L, DT, &LI, SE, TTI, AC, DI, ORE, OptLevel);
422 if (Result != LoopUnrollResult::Unmodified)
423 DidSomething = true;
424 if (Result == LoopUnrollResult::FullyUnrolled) {
425 if (L == OutmostLoop)
426 U.markLoopAsDeleted(*L, LoopName);
427 AnyLoopRemoved = true;
428 }
429 }
430
431 return DidSomething;
432}
433
437 LPMUpdater &U) {
438 Function &F = *LN.getParent();
439
440 DependenceInfo DI(&F, &AR.AA, &AR.SE, &AR.LI);
442
443 bool AnyLoopRemoved = false;
444 if (!tryToUnrollAndJamLoop(LN, AR.DT, AR.LI, AR.SE, AR.TTI, AR.AC, DI, ORE,
445 OptLevel, U, AnyLoopRemoved))
446 return PreservedAnalyses::all();
447
449 if (!AnyLoopRemoved)
450 PA.preserve<LoopNestAnalysis>();
451 return PA;
452}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Hexagon Hardware Loops
This header defines various interfaces for pass management in LLVM.
This header provides classes for managing per-loop analyses.
This file defines the interface for the loop nest analysis.
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
static const char *const LLVMLoopUnrollAndJamFollowupInner
static const char *const LLVMLoopUnrollAndJamFollowupRemainderInner
static const char *const LLVMLoopUnrollAndJamFollowupRemainderOuter
static const char *const LLVMLoopUnrollAndJamFollowupOuter
static bool computeUnrollAndJamCount(Loop *L, Loop *SubLoop, const TargetTransformInfo &TTI, DominatorTree &DT, LoopInfo *LI, AssumptionCache *AC, ScalarEvolution &SE, const SmallPtrSetImpl< const Value * > &EphValues, OptimizationRemarkEmitter *ORE, unsigned OuterTripCount, unsigned OuterTripMultiple, const UnrollCostEstimator &OuterUCE, unsigned InnerTripCount, unsigned InnerLoopSize, TargetTransformInfo::UnrollingPreferences &UP, TargetTransformInfo::PeelingPreferences &PP)
static cl::opt< bool > AllowUnrollAndJam("allow-unroll-and-jam", cl::Hidden, cl::desc("Allows loops to be unroll-and-jammed."))
static uint64_t getUnrollAndJammedLoopSize(unsigned LoopSize, TargetTransformInfo::UnrollingPreferences &UP)
static cl::opt< unsigned > UnrollAndJamCount("unroll-and-jam-count", cl::Hidden, cl::desc("Use this unroll count for all loops including those with " "unroll_and_jam_count pragma values, for testing purposes"))
static LoopUnrollResult tryToUnrollAndJamLoop(Loop *L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution &SE, const TargetTransformInfo &TTI, AssumptionCache &AC, DependenceInfo &DI, OptimizationRemarkEmitter &ORE, int OptLevel)
static bool hasAnyUnrollPragma(const Loop *L, StringRef Prefix)
static cl::opt< unsigned > PragmaUnrollAndJamThreshold("pragma-unroll-and-jam-threshold", cl::init(1024), cl::Hidden, cl::desc("Unrolled size limit for loops with an unroll_and_jam(full) or " "unroll_count pragma."))
static cl::opt< unsigned > UnrollAndJamThreshold("unroll-and-jam-threshold", cl::init(60), cl::Hidden, cl::desc("Threshold to use for inner loop when doing unroll and jam."))
static unsigned unrollAndJamCountPragmaValue(const Loop *L)
static bool hasUnrollAndJamEnablePragma(const Loop *L)
static const char *const LLVMLoopUnrollAndJamFollowupAll
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file contains the declarations for metadata subclasses.
This file provides a priority worklist.
This file defines the SmallPtrSet class.
#define LLVM_DEBUG(...)
Definition Debug.h:114
This pass exposes codegen information to IR-level passes.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
DependenceInfo - This class is the main dependence-analysis driver.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:164
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
ArrayRef< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
This analysis provides information for a loop nest.
This class represents a loop nest and can be used to query its properties.
ArrayRef< Loop * > getLoops() const
Get the loops in the nest.
Function * getParent() const
Return the function to which the loop-nest belongs.
Loop & getOutermostLoop() const
Return the outermost loop in the loop nest.
PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
void setLoopID(MDNode *LoopID) const
Set the llvm.loop loop id metadata for this loop.
Definition LoopInfo.cpp:546
MDNode * getLoopID() const
Return the llvm.loop loop id metadata node for this loop if it is present.
Definition LoopInfo.cpp:522
Metadata node.
Definition Metadata.h:1080
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1444
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1450
A single uniqued string.
Definition Metadata.h:722
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:632
The optimization diagnostic interface.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
bool empty() const
Determine if the PriorityWorklist is empty or not.
This class represents an analyzed expression in the program.
The main scalar evolution driver.
LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI unsigned getSmallConstantTripMultiple(const Loop *L, const SCEV *ExitCount)
Returns the largest constant divisor of the trip count as a normal unsigned value,...
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI unsigned getSmallConstantTripCount(const Loop *L)
Returns the exact trip count of the loop if we can compute it, and the result is a small constant.
A version of PriorityWorklist that selects small size optimized data structures for the vector and ma...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Produce an estimate of the unrolled cost of the specified loop.
Definition UnrollLoop.h:150
ConvergenceKind Convergence
Definition UnrollLoop.h:156
LLVM_ABI bool canUnroll() const
Whether it is legal to unroll this loop.
uint64_t getRolledLoopSize() const
Definition UnrollLoop.h:166
LLVM Value Representation.
Definition Value.h:75
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
LLVM_ABI bool isSafeToUnrollAndJam(Loop *L, ScalarEvolution &SE, DominatorTree &DT, DependenceInfo &DI, LoopInfo &LI)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI std::optional< MDNode * > makeFollowupLoopID(MDNode *OrigLoopID, ArrayRef< StringRef > FollowupAttrs, const char *InheritOptionsAttrsPrefix="", bool AlwaysNew=false)
Create a new loop identifier for a loop created from a loop transformation.
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
TargetTransformInfo::PeelingPreferences gatherPeelingPreferences(Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI, std::optional< bool > UserAllowPeeling, std::optional< bool > UserAllowProfileBasedPeeling, bool UnrollingSpecficValues=false)
LLVM_ABI TransformationMode hasUnrollAndJamTransformation(const Loop *L)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
LLVM_TEMPLATE_ABI void appendLoopsToWorklist(RangeT &&, SmallPriorityWorklist< Loop *, 4 > &)
Utility that implements appending of loops onto a worklist given a range.
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
LoopUnrollResult
Represents the result of a UnrollLoop invocation.
Definition UnrollLoop.h:58
@ PartiallyUnrolled
The loop was partially unrolled – we still have a loop, but with a smaller trip count.
Definition UnrollLoop.h:65
@ Unmodified
The loop was not modified.
Definition UnrollLoop.h:60
@ FullyUnrolled
The loop was fully unrolled into straight-line code.
Definition UnrollLoop.h:69
TargetTransformInfo TTI
TransformationMode
The mode sets how eager a transformation should be applied.
Definition LoopUtils.h:283
@ TM_ForcedByUser
The transformation was directed by the user, e.g.
Definition LoopUtils.h:300
@ TM_Disable
The transformation should not be applied.
Definition LoopUtils.h:292
LLVM_ABI MDNode * getUnrollMetadataForLoop(const Loop *L, StringRef Name)
LLVM_ABI TargetTransformInfo::UnrollingPreferences gatherUnrollingPreferences(Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, llvm::OptimizationRemarkEmitter &ORE, int OptLevel, std::optional< unsigned > UserThreshold, std::optional< unsigned > UserCount, std::optional< bool > UserAllowPartial, std::optional< bool > UserRuntime, std::optional< bool > UserUpperBound, std::optional< unsigned > UserFullUnrollMaxCount)
Gather the various unrolling parameters based on the defaults, compiler flags, TTI overrides and user...
LLVM_ABI PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
LLVM_ABI LoopUnrollResult UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount, unsigned TripMultiple, bool UnrollRemainder, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, const TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE, Loop **EpilogueLoop=nullptr)
LLVM_ABI void computeUnrollCount(Loop *L, const TargetTransformInfo &TTI, DominatorTree &DT, LoopInfo *LI, AssumptionCache *AC, ScalarEvolution &SE, const SmallPtrSetImpl< const Value * > &EphValues, OptimizationRemarkEmitter *ORE, unsigned TripCount, unsigned MaxTripCount, bool MaxOrZero, unsigned TripMultiple, const UnrollCostEstimator &UCE, TargetTransformInfo::UnrollingPreferences &UP, TargetTransformInfo::PeelingPreferences &PP)
static LLVM_ABI void collectEphemeralValues(const Loop *L, AssumptionCache *AC, SmallPtrSetImpl< const Value * > &EphValues)
Collect a loop's ephemeral values (those used only by an assume or similar intrinsics in the loop).
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
Parameters that control the generic loop unrolling transformation.
unsigned Count
A forced unrolling factor (the number of concatenated bodies of the original loop in the unrolled loo...
unsigned Threshold
The cost threshold for the unrolled loop.
bool Force
Apply loop unroll on any kind of loop (mainly to loops that fail runtime unrolling).
unsigned UnrollAndJamInnerLoopThreshold
Threshold for unroll and jam, for inner loop size.
bool AllowRemainder
Allow generation of a loop remainder (extra iterations after unroll).
bool UnrollAndJam
Allow unroll and jam. Used to enable unroll and jam for the target.
bool UnrollRemainder
Allow unrolling of all the iterations of the runtime loop remainder.
bool Runtime
Allow runtime unrolling (unrolling of loops to expand the size of the loop body even when the number ...