LLVM 24.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 "ScalarOptions.h"
15#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/StringRef.h"
29#include "llvm/IR/BasicBlock.h"
30#include "llvm/IR/Constants.h"
31#include "llvm/IR/Dominators.h"
32#include "llvm/IR/Function.h"
34#include "llvm/IR/Metadata.h"
35#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
69// Returns true if the loop has any metadata starting with Prefix. For example a
70// Prefix of "llvm.loop.unroll." returns true if we have any unroll metadata.
71static bool hasAnyUnrollPragma(const Loop *L, StringRef Prefix) {
72 if (MDNode *LoopID = L->getLoopID()) {
73 // First operand should refer to the loop id itself.
74 assert(LoopID->getNumOperands() > 0 && "requires at least one operand");
75 assert(LoopID->getOperand(0) == LoopID && "invalid loop id");
76
77 for (unsigned I = 1, E = LoopID->getNumOperands(); I < E; ++I) {
78 MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(I));
79 if (!MD)
80 continue;
81
83 if (!S)
84 continue;
85
86 if (S->getString().starts_with(Prefix))
87 return true;
88 }
89 }
90 return false;
91}
92
93// Returns true if the loop has an unroll_and_jam(enable) pragma.
94static bool hasUnrollAndJamEnablePragma(const Loop *L) {
95 return getUnrollMetadataForLoop(L, "llvm.loop.unroll_and_jam.enable");
96}
97
98// If loop has an unroll_and_jam_count pragma return the (necessarily
99// positive) value from the pragma. Otherwise return 0.
100static unsigned unrollAndJamCountPragmaValue(const Loop *L) {
101 MDNode *MD = getUnrollMetadataForLoop(L, "llvm.loop.unroll_and_jam.count");
102 if (MD) {
103 assert(MD->getNumOperands() == 2 &&
104 "Unroll count hint metadata should have two operands.");
105 unsigned Count =
106 mdconst::extract<ConstantInt>(MD->getOperand(1))->getZExtValue();
107 assert(Count >= 1 && "Unroll count must be positive.");
108 return Count;
109 }
110 return 0;
111}
112
113// Returns loop size estimation for an unrolled-and-jammed loop with the given
114// unroll count.
115static uint64_t
118 unsigned Count) {
119 assert(LoopSize >= UP.BEInsns && "LoopSize should not be less than BEInsns!");
120 return static_cast<uint64_t>(LoopSize - UP.BEInsns) * Count + UP.BEInsns;
121}
122
123// Calculates unroll and jam count.
125 const ScalarOptions &Opts, Loop *L, Loop *SubLoop,
128 const SmallPtrSetImpl<const Value *> &EphValues,
129 OptimizationRemarkEmitter *ORE, unsigned OuterTripCount,
130 unsigned OuterTripMultiple, const UnrollCostEstimator &OuterUCE,
131 unsigned InnerTripCount, unsigned InnerLoopSize,
132 bool &IsExplicitUnrollAndJam, TargetTransformInfo::UnrollingPreferences &UP,
134 unsigned OuterLoopSize = OuterUCE.getRolledLoopSize();
135 IsExplicitUnrollAndJam = false;
136
137 // Use computeUnrollCount from the loop unroller to get a count for
138 // unrolling the outer loop. This uses UP.Threshold / UP.PartialThreshold /
139 // UP.MaxCount to come up with sensible loop values.
140 // We have already checked that the loop has no unroll.* pragmas.
141 unsigned Count =
142 computeUnrollCount(L, TTI, DT, LI, AC, SE, EphValues, ORE, OuterTripCount,
143 /*MaxTripCount*/ 0, /*MaxOrZero*/ false,
144 OuterTripMultiple, OuterUCE, UP, PP);
145
146 // Override with any explicit count from the "unroll-and-jam-count" option.
147 bool UserUnrollCount = Opts.unroll_and_jam_count.has_value();
148 if (UserUnrollCount) {
149 Count = *Opts.unroll_and_jam_count;
150 UP.Force = true;
151 if (UP.AllowRemainder &&
152 getUnrollAndJammedLoopSize(OuterLoopSize, UP, Count) < UP.Threshold &&
153 getUnrollAndJammedLoopSize(InnerLoopSize, UP, Count) <
155 IsExplicitUnrollAndJam = true;
156 return Count;
157 }
158 }
159
160 // Check for unroll_and_jam pragmas
161 unsigned PragmaCount = unrollAndJamCountPragmaValue(L);
162 if (PragmaCount > 0) {
163 Count = PragmaCount;
164 UP.Runtime = true;
165 UP.Force = true;
166 if ((UP.AllowRemainder || (OuterTripMultiple % PragmaCount == 0)) &&
167 getUnrollAndJammedLoopSize(OuterLoopSize, UP, Count) < UP.Threshold &&
168 getUnrollAndJammedLoopSize(InnerLoopSize, UP, Count) <
170 IsExplicitUnrollAndJam = true;
171 return Count;
172 }
173 }
174
175 bool PragmaEnableUnroll = hasUnrollAndJamEnablePragma(L);
176 bool ExplicitUnrollAndJamCount = PragmaCount > 0 || UserUnrollCount;
177 bool ExplicitUnrollAndJam = PragmaEnableUnroll || ExplicitUnrollAndJamCount;
178
179 // If the loop has an unrolling pragma, we want to be more aggressive with
180 // unrolling limits.
181 if (ExplicitUnrollAndJam)
182 UP.UnrollAndJamInnerLoopThreshold = Opts.pragma_unroll_and_jam_threshold;
183
184 if (!UP.AllowRemainder &&
185 getUnrollAndJammedLoopSize(InnerLoopSize, UP, Count) >=
187 LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; can't create remainder and "
188 "inner loop too large\n");
189 return 0;
190 }
191
192 // We have a sensible limit for the outer loop, now adjust it for the inner
193 // loop and UP.UnrollAndJamInnerLoopThreshold. If the outer limit was set
194 // explicitly, we want to stick to it.
195 if (!ExplicitUnrollAndJamCount && UP.AllowRemainder) {
196 while (Count != 0 && getUnrollAndJammedLoopSize(InnerLoopSize, UP, Count) >=
198 Count--;
199 }
200
201 // If we are explicitly unroll and jamming, we are done. Otherwise there are a
202 // number of extra performance heuristics to check.
203 if (ExplicitUnrollAndJam) {
204 IsExplicitUnrollAndJam = true;
205 return Count;
206 }
207
208 // If the inner loop count is known and small, leave the entire loop nest to
209 // be the unroller
210 if (InnerTripCount && InnerLoopSize * InnerTripCount < UP.Threshold) {
211 LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; small inner loop count is "
212 "being left for the unroller\n");
213 return 0;
214 }
215
216 // Check for situations where UnJ is likely to be unprofitable. Including
217 // subloops with more than 1 block.
218 if (SubLoop->getBlocks().size() != 1) {
220 dbgs() << "Won't unroll-and-jam; More than one inner loop block\n");
221 return 0;
222 }
223
224 // Limit to loops where there is something to gain from unrolling and
225 // jamming the loop. In this case, look for loads that are invariant in the
226 // outer loop and can become shared.
227 unsigned NumInvariant = 0;
228 for (BasicBlock *BB : SubLoop->getBlocks()) {
229 for (Instruction &I : *BB) {
230 if (auto *Ld = dyn_cast<LoadInst>(&I)) {
231 Value *V = Ld->getPointerOperand();
232 const SCEV *LSCEV = SE.getSCEVAtScope(V, L);
233 if (SE.isLoopInvariant(LSCEV, L))
234 NumInvariant++;
235 }
236 }
237 }
238 if (NumInvariant == 0) {
239 LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; No loop invariant loads\n");
240 return 0;
241 }
242
243 return Count;
244}
245
246static LoopUnrollResult
250 OptimizationRemarkEmitter &ORE, int OptLevel) {
251 const ScalarOptions &Opts =
252 L->getHeader()->getContext().getLibraryOptions().get<ScalarOptions>();
254 L, SE, TTI, nullptr, nullptr, ORE, OptLevel, std::nullopt, std::nullopt,
255 std::nullopt, std::nullopt, std::nullopt);
257 gatherPeelingPreferences(L, SE, TTI, std::nullopt, std::nullopt);
258
260 if (EnableMode & TM_Disable)
262 if (EnableMode & TM_ForcedByUser)
263 UP.UnrollAndJam = true;
264
265 UP.UnrollAndJam = valueOr(Opts.allow_unroll_and_jam, UP.UnrollAndJam);
266 if (Opts.unroll_and_jam_threshold)
267 UP.UnrollAndJamInnerLoopThreshold = *Opts.unroll_and_jam_threshold;
268 // Exit early if unrolling is disabled.
269 if (!UP.UnrollAndJam || UP.UnrollAndJamInnerLoopThreshold == 0)
271
272 LLVM_DEBUG(dbgs() << "Loop Unroll and Jam: F["
273 << L->getHeader()->getParent()->getName() << "] Loop %"
274 << L->getHeader()->getName() << "\n");
275
276 // A loop with any unroll pragma (enabling/disabling/count/etc) is left for
277 // the unroller, so long as it does not explicitly have unroll_and_jam
278 // metadata. This means #pragma nounroll will disable unroll and jam as well
279 // as unrolling
280 if (hasAnyUnrollPragma(L, "llvm.loop.unroll.") &&
281 !hasAnyUnrollPragma(L, "llvm.loop.unroll_and_jam.")) {
282 LLVM_DEBUG(dbgs() << " Disabled due to pragma.\n");
284 }
285
286 if (!isSafeToUnrollAndJam(L, SE, DT, DI, *LI)) {
287 LLVM_DEBUG(dbgs() << " Disabled due to not being safe.\n");
289 }
290
291 // Approximate the loop size and collect useful info
293 CodeMetrics::collectEphemeralValues(L, &AC, EphValues);
294 Loop *SubLoop = L->getSubLoops()[0];
295 UnrollCostEstimator InnerUCE(SubLoop, TTI, EphValues, UP.BEInsns);
296 UnrollCostEstimator OuterUCE(L, TTI, EphValues, UP.BEInsns);
297
298 if (!InnerUCE.canUnroll() || !OuterUCE.canUnroll()) {
299 LLVM_DEBUG(dbgs() << " Loop not considered unrollable\n");
301 }
302
303 unsigned InnerLoopSize = InnerUCE.getRolledLoopSize();
304 LLVM_DEBUG(dbgs() << " Outer Loop Size: " << OuterUCE.getRolledLoopSize()
305 << "\n");
306 LLVM_DEBUG(dbgs() << " Inner Loop Size: " << InnerLoopSize << "\n");
307
308 if (InnerUCE.NumInlineCandidates != 0 || OuterUCE.NumInlineCandidates != 0) {
309 LLVM_DEBUG(dbgs() << " Not unrolling loop with inlinable calls.\n");
311 }
312 // FIXME: The call to canUnroll() allows some controlled convergent
313 // operations, but we block them here for future changes.
314 if (InnerUCE.Convergence != ConvergenceKind::None ||
317 dbgs() << " Not unrolling loop with convergent instructions.\n");
319 }
320
321 // Save original loop IDs for after the transformation.
322 MDNode *OrigOuterLoopID = L->getLoopID();
323 MDNode *OrigSubLoopID = SubLoop->getLoopID();
324
325 // To assign the loop id of the epilogue, assign it before unrolling it so it
326 // is applied to every inner loop of the epilogue. We later apply the loop ID
327 // for the jammed inner loop.
328 std::optional<MDNode *> NewInnerEpilogueLoopID = makeFollowupLoopID(
329 OrigOuterLoopID, {LLVMLoopUnrollAndJamFollowupAll,
331 if (NewInnerEpilogueLoopID)
332 SubLoop->setLoopID(*NewInnerEpilogueLoopID);
333
334 // Find trip count and trip multiple
335 BasicBlock *Latch = L->getLoopLatch();
336 BasicBlock *SubLoopLatch = SubLoop->getLoopLatch();
337 unsigned OuterTripCount = SE.getSmallConstantTripCount(L, Latch);
338 unsigned OuterTripMultiple = SE.getSmallConstantTripMultiple(L, Latch);
339 unsigned InnerTripCount = SE.getSmallConstantTripCount(SubLoop, SubLoopLatch);
340
341 // Decide if, and by how much, to unroll
342 bool IsExplicitUnrollAndJam = false;
344 Opts, L, SubLoop, TTI, DT, LI, &AC, SE, EphValues, &ORE, OuterTripCount,
345 OuterTripMultiple, OuterUCE, InnerTripCount, InnerLoopSize,
346 IsExplicitUnrollAndJam, UP, PP);
347 if (Count <= 1)
349 // Unroll factor (Count) must be less or equal to TripCount.
350 if (OuterTripCount && Count > OuterTripCount)
351 Count = OuterTripCount;
352
353 Loop *EpilogueOuterLoop = nullptr;
354 LoopUnrollResult UnrollResult = UnrollAndJamLoop(
355 L, Count, OuterTripCount, OuterTripMultiple, UP.UnrollRemainder, LI, &SE,
356 &DT, &AC, &TTI, &ORE, &EpilogueOuterLoop);
357
358 // Assign new loop attributes.
359 if (EpilogueOuterLoop) {
360 std::optional<MDNode *> NewOuterEpilogueLoopID = makeFollowupLoopID(
361 OrigOuterLoopID, {LLVMLoopUnrollAndJamFollowupAll,
363 if (NewOuterEpilogueLoopID)
364 EpilogueOuterLoop->setLoopID(*NewOuterEpilogueLoopID);
365 }
366
367 std::optional<MDNode *> NewInnerLoopID =
370 if (NewInnerLoopID)
371 SubLoop->setLoopID(*NewInnerLoopID);
372 else
373 SubLoop->setLoopID(OrigSubLoopID);
374
375 if (UnrollResult == LoopUnrollResult::PartiallyUnrolled) {
376 std::optional<MDNode *> NewOuterLoopID = makeFollowupLoopID(
377 OrigOuterLoopID,
379 if (NewOuterLoopID) {
380 L->setLoopID(*NewOuterLoopID);
381
382 // Do not setLoopAlreadyUnrolled if a followup was given.
383 return UnrollResult;
384 }
385 }
386
387 // If unroll-and-jam was explicitly requested, mark the loop as already
388 // unrolled to prevent unrolling beyond that request.
389 if (UnrollResult != LoopUnrollResult::FullyUnrolled && IsExplicitUnrollAndJam)
390 L->setLoopAlreadyUnrolled();
391
392 return UnrollResult;
393}
394
396 ScalarEvolution &SE,
399 OptimizationRemarkEmitter &ORE, int OptLevel,
400 LPMUpdater &U, bool &AnyLoopRemoved) {
401 bool DidSomething = false;
403 Loop *OutmostLoop = &LN.getOutermostLoop();
404
405 // Add the loop nests in the reverse order of LN. See method
406 // declaration.
408 appendLoopsToWorklist(Loops, Worklist);
409 while (!Worklist.empty()) {
410 Loop *L = Worklist.pop_back_val();
411 std::string LoopName = std::string(L->getName());
412 LoopUnrollResult Result =
413 tryToUnrollAndJamLoop(L, DT, &LI, SE, TTI, AC, DI, ORE, OptLevel);
414 if (Result != LoopUnrollResult::Unmodified)
415 DidSomething = true;
416 if (Result == LoopUnrollResult::FullyUnrolled) {
417 if (L == OutmostLoop)
418 U.markLoopAsDeleted(*L, LoopName);
419 AnyLoopRemoved = true;
420 }
421 }
422
423 return DidSomething;
424}
425
429 LPMUpdater &U) {
430 Function &F = *LN.getParent();
431
432 DependenceInfo DI(&F, &AR.AA, &AR.SE, &AR.LI);
434
435 bool AnyLoopRemoved = false;
436 if (!tryToUnrollAndJamLoop(LN, AR.DT, AR.LI, AR.SE, AR.TTI, AR.AC, DI, ORE,
437 OptLevel, U, AnyLoopRemoved))
438 return PreservedAnalyses::all();
439
441 if (!AnyLoopRemoved)
442 PA.preserve<LoopNestAnalysis>();
443 return PA;
444}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
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 unsigned computeUnrollAndJamCount(const ScalarOptions &Opts, 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, bool &IsExplicitUnrollAndJam, TargetTransformInfo::UnrollingPreferences &UP, TargetTransformInfo::PeelingPreferences &PP)
static const char *const LLVMLoopUnrollAndJamFollowupRemainderOuter
static const char *const LLVMLoopUnrollAndJamFollowupOuter
static LoopUnrollResult tryToUnrollAndJamLoop(Loop *L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution &SE, const TargetTransformInfo &TTI, AssumptionCache &AC, DependenceInfo &DI, OptimizationRemarkEmitter &ORE, int OptLevel)
static uint64_t getUnrollAndJammedLoopSize(unsigned LoopSize, const TargetTransformInfo::UnrollingPreferences &UP, unsigned Count)
static bool hasAnyUnrollPragma(const Loop *L, StringRef Prefix)
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:119
This pass exposes codegen information to IR-level passes.
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:122
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.
LLVM_ABI 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:584
MDNode * getLoopID() const
Return the llvm.loop loop id metadata node for this loop if it is present.
Definition LoopInfo.cpp:560
Metadata node.
Definition Metadata.h:1081
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1437
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1443
A single uniqued string.
Definition Metadata.h:733
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:615
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 unsigned getSmallConstantTripMultiple(const Loop *L, const SCEV *ExitCount)
Returns the largest constant divisor of the trip count as a normal unsigned value,...
LLVM_ABI SCEVUse getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
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.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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(OptimizationRemarkEmitter *ORE=nullptr, const Loop *L=nullptr) const
Whether it is legal to unroll this loop.
uint64_t getRolledLoopSize() const
Definition UnrollLoop.h:174
LLVM Value Representation.
Definition Value.h:75
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:679
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool isSafeToUnrollAndJam(Loop *L, ScalarEvolution &SE, DominatorTree &DT, DependenceInfo &DI, LoopInfo &LI)
LLVM_ABI unsigned 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)
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.
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< 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...
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
LLVM_ABI 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:209
LLVM_TEMPLATE_ABI void appendLoopsToWorklist(RangeT &&, SmallPriorityWorklist< Loop *, 4 > &)
Utility that implements appending of loops onto a worklist given a range.
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:288
@ TM_ForcedByUser
The transformation was directed by the user, e.g.
Definition LoopUtils.h:305
@ TM_Disable
The transformation should not be applied.
Definition LoopUtils.h:297
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
LLVM_ABI MDNode * getUnrollMetadataForLoop(const Loop *L, StringRef Name)
LLVM_ABI PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
constexpr bool valueOr(BoolOrDefault X, bool Default)
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)
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 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 Runtime
Allow runtime unrolling (unrolling of loops to expand the size of the loop body even when the number ...