LLVM 24.0.0git
LoopVectorizationPlanner.cpp
Go to the documentation of this file.
1//===- LoopVectorizationPlanner.cpp - VF selection and planning -----------===//
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/// \file
10/// This file implements VFSelectionContext methods for loop vectorization
11/// VF selection, independent of cost-modeling decisions.
12///
13//===----------------------------------------------------------------------===//
14
21#include "llvm/Support/Debug.h"
25
26using namespace llvm;
27using namespace LoopVectorizationUtils;
28
29#define DEBUG_TYPE "loop-vectorize"
30
32
34 "vectorizer-maximize-bandwidth", cl::init(false), cl::Hidden,
35 cl::desc("Maximize bandwidth when selecting vectorization factor which "
36 "will be determined by the smallest type in loop."));
37
39 "vectorizer-maximize-bandwidth-for-vector-calls", cl::init(true),
41 cl::desc("Try wider VFs if they enable the use of vector variants"));
42
44 "vectorizer-consider-reg-pressure", cl::init(false), cl::Hidden,
45 cl::desc("Discard VFs if their register pressure is too high."));
46
48 "force-target-supports-scalable-vectors", cl::init(false), cl::Hidden,
50 "Pretend that scalable vectors are supported, even if the target does "
51 "not support them. This flag should only be used for testing."));
52
54 "prefer-inloop-reductions", cl::init(false), cl::Hidden,
55 cl::desc("Prefer in-loop vector reductions, "
56 "overriding the targets preference."));
57
58/// Note: This currently only applies to `llvm.masked.load` and
59/// `llvm.masked.store`. TODO: Extend this to cover other operations as needed.
61 "force-target-supports-masked-memory-ops", cl::init(false), cl::Hidden,
62 cl::desc("Assume the target supports masked memory operations (used for "
63 "testing)."));
64
66 "force-target-supports-gather-scatter-ops", cl::init(false), cl::Hidden,
67 cl::desc("Assume the target supports gather/scatter operations (used for "
68 "testing)."));
69
71 "scalable-epilogue-vf-cost-scale-factor", cl::init(2.0), cl::Hidden,
72 cl::desc("Scale the cost of scalable epilogue VFs by this factor."));
73
74/// Write a \p DebugMsg about vectorization to the debug output stream. If \p I
75/// is passed, the message relates to that particular instruction.
76#ifndef NDEBUG
77static void debugVectorizationMessage(const StringRef Prefix,
78 const StringRef DebugMsg,
79 Instruction *I) {
80 dbgs() << "LV: " << Prefix << DebugMsg;
81 if (I != nullptr)
82 dbgs() << " " << *I;
83 else
84 dbgs() << '.';
85 dbgs() << '\n';
86}
87#endif
88
89/// Create an analysis remark that explains why vectorization failed
90/// \p RemarkName is the identifier for the remark. If \p I is passed it is an
91/// instruction that prevents vectorization. Otherwise \p TheLoop is used for
92/// the location of the remark. If \p DL is passed, use it as debug location for
93/// the remark. \return the remark object that can be streamed to.
95 const Loop *TheLoop,
97 DebugLoc DL = {}) {
98 BasicBlock *CodeRegion = I ? I->getParent() : TheLoop->getHeader();
99 // If debug location is attached to the instruction, use it. Otherwise if DL
100 // was not provided, use the loop's.
101 if (I && I->getDebugLoc())
102 DL = I->getDebugLoc();
103 else if (!DL)
104 DL = TheLoop->getStartLoc();
105
106 return OptimizationRemarkAnalysis(DEBUG_TYPE, RemarkName, DL, CodeRegion);
107}
108
110 const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag,
111 OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I) {
112 LLVM_DEBUG(debugVectorizationMessage("Not vectorizing: ", DebugMsg, I));
113 ORE->emit(createLVAnalysis(ORETag, TheLoop, I)
114 << "loop not vectorized: " << OREMsg);
115}
116
118 const StringRef Msg, const StringRef ORETag, OptimizationRemarkEmitter *ORE,
119 const Loop *TheLoop, Instruction *I, DebugLoc DL) {
121 ORE->emit(createLVAnalysis(ORETag, TheLoop, I, DL) << Msg);
122}
123
125 Loop *TheLoop,
126 ElementCount VFWidth,
127 unsigned IC) {
129 "Vectorizing: ", TheLoop->isInnermost() ? "innermost loop" : "outer loop",
130 nullptr));
131 StringRef LoopType = TheLoop->isInnermost() ? "" : "outer ";
132 ORE->emit([&]() {
133 return OptimizationRemark(DEBUG_TYPE, "Vectorized", TheLoop->getStartLoc(),
134 TheLoop->getHeader())
135 << "vectorized " << LoopType << "loop (vectorization width: "
136 << ore::NV("VectorizationFactor", VFWidth)
137 << ", interleaved count: " << ore::NV("InterleaveCount", IC) << ")";
138 });
139}
140
142 Align Alignment,
143 unsigned AddressSpace) const {
145 (IsLoad ? TTI.isLegalMaskedLoad(ScalarTy, Alignment, AddressSpace)
146 : TTI.isLegalMaskedStore(ScalarTy, Alignment, AddressSpace));
147}
148
150 ElementCount VF) const {
151 bool LI = isa<LoadInst>(V);
152 bool SI = isa<StoreInst>(V);
153 if (!LI && !SI)
154 return false;
155 auto *Ty = getLoadStoreType(V);
157 if (VF.isVector())
158 Ty = VectorType::get(Ty, VF);
160 (LI && TTI.isLegalMaskedGather(Ty, Align)) ||
161 (SI && TTI.isLegalMaskedScatter(Ty, Align));
162}
163
165 return TTI.supportsScalableVectors() || ForceTargetSupportsScalableVectors ||
167}
168
169bool VFSelectionContext::useMaxBandwidth(bool IsScalable) const {
173 return MaximizeBandwidth || (MaximizeBandwidth.getNumOccurrences() == 0 &&
174 (TTI.shouldMaximizeVectorBandwidth(RegKind) ||
176 Legal->hasVectorCallVariants())));
177}
178
180 if (ConsiderRegPressure.getNumOccurrences())
181 return ConsiderRegPressure;
182
183 // TODO: We should eventually consider register pressure for all targets. The
184 // TTI hook is temporary whilst target-specific issues are being fixed.
185 if (TTI.shouldConsiderVectorizationRegPressure())
186 return true;
187
188 if (!useMaxBandwidth(VF.isScalable()))
189 return false;
190 // Only calculate register pressure for VFs enabled by MaxBandwidth.
192 VF, VF.isScalable() ? MaxPermissibleVFWithoutMaxBW.ScalableVF
193 : MaxPermissibleVFWithoutMaxBW.FixedVF);
194}
195
196ElementCount VFSelectionContext::clampVFByMaxTripCount(
197 ElementCount VF, unsigned MaxTripCount, unsigned UserIC,
198 bool FoldTailByMasking, bool RequiresScalarEpilogue) const {
199 unsigned EstimatedVF = VF.getKnownMinValue();
200 if (VF.isScalable() && F.hasFnAttribute(Attribute::VScaleRange)) {
201 auto Attr = F.getFnAttribute(Attribute::VScaleRange);
202 auto Min = Attr.getVScaleRangeMin();
203 EstimatedVF *= Min;
204 }
205
206 // When a scalar epilogue is required, at least one iteration of the scalar
207 // loop has to execute. Adjust MaxTripCount accordingly to avoid picking a
208 // max VF that results in a dead vector loop.
209 if (MaxTripCount > 0 && RequiresScalarEpilogue)
210 MaxTripCount -= 1;
211
212 // When the user specifies an interleave count, we need to ensure that
213 // VF * UserIC <= MaxTripCount to avoid a dead vector loop.
214 unsigned IC = UserIC > 0 ? UserIC : 1;
215 unsigned EstimatedVFTimesIC = EstimatedVF * IC;
216
217 if (MaxTripCount && MaxTripCount <= EstimatedVFTimesIC &&
218 (!FoldTailByMasking || isPowerOf2_32(MaxTripCount))) {
219 // If upper bound loop trip count (TC) is known at compile time there is no
220 // point in choosing VF greater than TC / IC (as done in the loop below).
221 // Select maximum power of two which doesn't exceed TC / IC. If VF is
222 // scalable, we only fall back on a fixed VF when the TC is less than or
223 // equal to the known number of lanes.
224 auto ClampedUpperTripCount = llvm::bit_floor(MaxTripCount / IC);
225 if (ClampedUpperTripCount == 0)
226 ClampedUpperTripCount = 1;
227 LLVM_DEBUG(dbgs() << "LV: Clamping the MaxVF to maximum power of two not "
228 "exceeding the constant trip count"
229 << (UserIC > 0 ? " divided by UserIC" : "") << ": "
230 << ClampedUpperTripCount << "\n");
231 return ElementCount::get(ClampedUpperTripCount,
232 FoldTailByMasking ? VF.isScalable() : false);
233 }
234 return VF;
235}
236
237ElementCount VFSelectionContext::getMaximizedVFForTarget(
238 unsigned MaxTripCount, unsigned SmallestType, unsigned WidestType,
239 ElementCount MaxSafeVF, unsigned UserIC, bool FoldTailByMasking,
240 bool RequiresScalarEpilogue) {
241 bool ComputeScalableMaxVF = MaxSafeVF.isScalable();
242 const TypeSize WidestRegister = TTI.getRegisterBitWidth(
243 ComputeScalableMaxVF ? TargetTransformInfo::RGK_ScalableVector
245
246 // Convenience function to return the minimum of two ElementCounts.
247 auto MinVF = [](const ElementCount &LHS, const ElementCount &RHS) {
248 assert((LHS.isScalable() == RHS.isScalable()) &&
249 "Scalable flags must match");
251 };
252
253 // Ensure MaxVF is a power of 2; the dependence distance bound may not be.
254 // Note that both WidestRegister and WidestType may not be a powers of 2.
255 auto MaxVectorElementCount = ElementCount::get(
256 llvm::bit_floor(WidestRegister.getKnownMinValue() / WidestType),
257 ComputeScalableMaxVF);
258 MaxVectorElementCount = MinVF(MaxVectorElementCount, MaxSafeVF);
259 LLVM_DEBUG(dbgs() << "LV: The Widest register safe to use is: "
260 << (MaxVectorElementCount * WidestType) << " bits.\n");
261
262 if (!MaxVectorElementCount) {
263 LLVM_DEBUG(dbgs() << "LV: The target has no "
264 << (ComputeScalableMaxVF ? "scalable" : "fixed")
265 << " vector registers.\n");
266 return ElementCount::getFixed(1);
267 }
268
269 ElementCount MaxVF =
270 clampVFByMaxTripCount(MaxVectorElementCount, MaxTripCount, UserIC,
271 FoldTailByMasking, RequiresScalarEpilogue);
272 // If the MaxVF was already clamped, there's no point in trying to pick a
273 // larger one.
274 if (MaxVF != MaxVectorElementCount)
275 return MaxVF;
276
277 if (MaxVF.isScalable())
278 MaxPermissibleVFWithoutMaxBW.ScalableVF = MaxVF;
279 else
280 MaxPermissibleVFWithoutMaxBW.FixedVF = MaxVF;
281
282 if (useMaxBandwidth(ComputeScalableMaxVF)) {
283 auto MaxVectorElementCountMaxBW = ElementCount::get(
284 llvm::bit_floor(WidestRegister.getKnownMinValue() / SmallestType),
285 ComputeScalableMaxVF);
286 MaxVF = MinVF(MaxVectorElementCountMaxBW, MaxSafeVF);
287
288 if (ElementCount MinVF =
289 TTI.getMinimumVF(SmallestType, ComputeScalableMaxVF)) {
290 if (ElementCount::isKnownLT(MaxVF, MinVF)) {
291 LLVM_DEBUG(dbgs() << "LV: Overriding calculated MaxVF(" << MaxVF
292 << ") with target's minimum: " << MinVF << '\n');
293 MaxVF = MinVF;
294 }
295 }
296
297 MaxVF = clampVFByMaxTripCount(MaxVF, MaxTripCount, UserIC,
298 FoldTailByMasking, RequiresScalarEpilogue);
299 }
300 return MaxVF;
301}
302
303std::optional<unsigned> llvm::getMaxVScale(const Function &F,
304 const TargetTransformInfo &TTI) {
305 if (std::optional<unsigned> MaxVScale = TTI.getMaxVScale())
306 return MaxVScale;
307
308 if (F.hasFnAttribute(Attribute::VScaleRange))
309 return F.getFnAttribute(Attribute::VScaleRange).getVScaleRangeMax();
310
311 return std::nullopt;
312}
313
314bool VFSelectionContext::isScalableVectorizationAllowed() {
315 if (IsScalableVectorizationAllowed)
316 return *IsScalableVectorizationAllowed;
317
318 IsScalableVectorizationAllowed = false;
320 return false;
321
322 if (Hints->isScalableVectorizationDisabled()) {
323 reportVectorizationInfo("Scalable vectorization is explicitly disabled",
324 "ScalableVectorizationDisabled", ORE, TheLoop);
325 return false;
326 }
327
328 LLVM_DEBUG(dbgs() << "LV: Scalable vectorization is available\n");
329
330 auto MaxScalableVF = ElementCount::getScalable(
331 std::numeric_limits<ElementCount::ScalarTy>::max());
332
333 // Test that the loop-vectorizer can legalize all operations for this MaxVF.
334 // FIXME: While for scalable vectors this is currently sufficient, this should
335 // be replaced by a more detailed mechanism that filters out specific VFs,
336 // instead of invalidating vectorization for a whole set of VFs based on the
337 // MaxVF.
338
339 // Disable scalable vectorization if the loop contains unsupported reductions.
340 if (!all_of(Legal->getReductionVars(), [&](const auto &Reduction) -> bool {
341 return TTI.isLegalToVectorizeReduction(Reduction.second, MaxScalableVF);
342 })) {
344 "Scalable vectorization not supported for the reduction "
345 "operations found in this loop.",
346 "ScalableVFUnfeasible", ORE, TheLoop);
347 return false;
348 }
349
350 // Disable scalable vectorization if the loop contains any instructions
351 // with element types not supported for scalable vectors.
352 if (any_of(ElementTypesInLoop, [&](Type *Ty) {
353 return !Ty->isVoidTy() && !TTI.isElementTypeLegalForScalableVector(Ty);
354 })) {
355 reportVectorizationInfo("Scalable vectorization is not supported "
356 "for all element types found in this loop.",
357 "ScalableVFUnfeasible", ORE, TheLoop);
358 return false;
359 }
360
361 if (!Legal->isSafeForAnyVectorWidth() && !getMaxVScale(F, TTI)) {
362 reportVectorizationInfo("The target does not provide maximum vscale value "
363 "for safe distance analysis.",
364 "ScalableVFUnfeasible", ORE, TheLoop);
365 return false;
366 }
367
368 IsScalableVectorizationAllowed = true;
369 return true;
370}
371
373VFSelectionContext::getMaxLegalScalableVF(unsigned MaxSafeElements) {
374 if (!isScalableVectorizationAllowed())
376
377 auto MaxScalableVF = ElementCount::getScalable(
378 std::numeric_limits<ElementCount::ScalarTy>::max());
379 if (Legal->isSafeForAnyVectorWidth())
380 return MaxScalableVF;
381
382 std::optional<unsigned> MaxVScale = getMaxVScale(F, TTI);
383 // Limit MaxScalableVF by the maximum safe dependence distance.
384 MaxScalableVF = ElementCount::getScalable(MaxSafeElements / *MaxVScale);
385
386 if (!MaxScalableVF)
388 "Max legal vector width too small, scalable vectorization "
389 "unfeasible.",
390 "ScalableVFUnfeasible", ORE, TheLoop);
391
392 return MaxScalableVF;
393}
394
396 unsigned MaxTripCount, ElementCount UserVF, unsigned UserIC,
397 bool FoldTailByMasking, bool RequiresScalarEpilogue) {
398 auto [SmallestType, WidestType] = getSmallestAndWidestTypes();
399
400 // Get the maximum safe dependence distance in bits computed by LAA.
401 // It is computed by MaxVF * sizeOf(type) * 8, where type is taken from
402 // the memory accesses that is most restrictive (involved in the smallest
403 // dependence distance).
404 unsigned MaxSafeElementsPowerOf2 =
405 llvm::bit_floor(Legal->getMaxSafeVectorWidthInBits() / WidestType);
406 if (!Legal->isSafeForAnyStoreLoadForwardDistances()) {
407 unsigned SLDist = Legal->getMaxStoreLoadForwardSafeDistanceInBits();
408 MaxSafeElementsPowerOf2 =
409 std::min(MaxSafeElementsPowerOf2, SLDist / WidestType);
410 }
411
412 auto MaxSafeFixedVF = ElementCount::getFixed(MaxSafeElementsPowerOf2);
413 auto MaxSafeScalableVF = getMaxLegalScalableVF(MaxSafeElementsPowerOf2);
414
415 if (!Legal->isSafeForAnyVectorWidth())
416 MaxSafeElements = MaxSafeElementsPowerOf2;
417
418 LLVM_DEBUG(dbgs() << "LV: The max safe fixed VF is: " << MaxSafeFixedVF
419 << ".\n");
420 LLVM_DEBUG(dbgs() << "LV: The max safe scalable VF is: " << MaxSafeScalableVF
421 << ".\n");
422
423 // First analyze the UserVF, fall back if the UserVF should be ignored.
424 if (UserVF) {
425 auto MaxSafeUserVF =
426 UserVF.isScalable() ? MaxSafeScalableVF : MaxSafeFixedVF;
427
428 if (ElementCount::isKnownLE(UserVF, MaxSafeUserVF)) {
429 // If `VF=vscale x N` is safe, then so is `VF=N`
430 if (UserVF.isScalable())
431 return FixedScalableVFPair(
432 ElementCount::getFixed(UserVF.getKnownMinValue()), UserVF);
433
434 return UserVF;
435 }
436
437 assert(ElementCount::isKnownGT(UserVF, MaxSafeUserVF));
438
439 // Only clamp if the UserVF is not scalable. If the UserVF is scalable, it
440 // is better to ignore the hint and let the compiler choose a suitable VF.
441 if (!UserVF.isScalable()) {
442 LLVM_DEBUG(dbgs() << "LV: User VF=" << UserVF
443 << " is unsafe, clamping to max safe VF="
444 << MaxSafeFixedVF << ".\n");
445 ORE->emit([&]() {
446 return OptimizationRemarkAnalysis(DEBUG_TYPE, "VectorizationFactor",
447 TheLoop->getStartLoc(),
448 TheLoop->getHeader())
449 << "User-specified vectorization factor "
450 << ore::NV("UserVectorizationFactor", UserVF)
451 << " is unsafe, clamping to maximum safe vectorization factor "
452 << ore::NV("VectorizationFactor", MaxSafeFixedVF);
453 });
454 return MaxSafeFixedVF;
455 }
456
458 LLVM_DEBUG(dbgs() << "LV: User VF=" << UserVF
459 << " is ignored because scalable vectors are not "
460 "available.\n");
461 ORE->emit([&]() {
462 return OptimizationRemarkAnalysis(DEBUG_TYPE, "VectorizationFactor",
463 TheLoop->getStartLoc(),
464 TheLoop->getHeader())
465 << "User-specified vectorization factor "
466 << ore::NV("UserVectorizationFactor", UserVF)
467 << " is ignored because the target does not support scalable "
468 "vectors. The compiler will pick a more suitable value.";
469 });
470 } else {
471 LLVM_DEBUG(dbgs() << "LV: User VF=" << UserVF
472 << " is unsafe. Ignoring scalable UserVF.\n");
473 ORE->emit([&]() {
474 return OptimizationRemarkAnalysis(DEBUG_TYPE, "VectorizationFactor",
475 TheLoop->getStartLoc(),
476 TheLoop->getHeader())
477 << "User-specified vectorization factor "
478 << ore::NV("UserVectorizationFactor", UserVF)
479 << " is unsafe. Ignoring the hint to let the compiler pick a "
480 "more suitable value.";
481 });
482 }
483 }
484
485 LLVM_DEBUG(dbgs() << "LV: The Smallest and Widest types: " << SmallestType
486 << " / " << WidestType << " bits.\n");
487
490 if (auto MaxVF = getMaximizedVFForTarget(
491 MaxTripCount, SmallestType, WidestType, MaxSafeFixedVF, UserIC,
492 FoldTailByMasking, RequiresScalarEpilogue))
493 Result.FixedVF = MaxVF;
494
495 if (auto MaxVF = getMaximizedVFForTarget(
496 MaxTripCount, SmallestType, WidestType, MaxSafeScalableVF, UserIC,
497 FoldTailByMasking, RequiresScalarEpilogue))
498 if (MaxVF.isScalable()) {
499 Result.ScalableVF = MaxVF;
500 LLVM_DEBUG(dbgs() << "LV: Found feasible scalable VF = " << MaxVF
501 << "\n");
502 }
503
504 return Result;
505}
506
507std::pair<unsigned, unsigned>
509 unsigned MinWidth = -1U;
510 unsigned MaxWidth = 8;
511 const DataLayout &DL = F.getDataLayout();
512 // For in-loop reductions, no element types are added to ElementTypesInLoop
513 // if there are no loads/stores in the loop. In this case, check through the
514 // reduction variables to determine the maximum width.
515 if (ElementTypesInLoop.empty() && !Legal->getReductionVars().empty()) {
516 for (const auto &[_, RdxDesc] : Legal->getReductionVars()) {
517 // When finding the min width used by the recurrence we need to account
518 // for casts on the input operands of the recurrence.
519 MinWidth = std::min(
520 MinWidth,
521 std::min(RdxDesc.getMinWidthCastToRecurrenceTypeInBits(),
522 RdxDesc.getRecurrenceType()->getScalarSizeInBits()));
523 MaxWidth = std::max(MaxWidth,
524 RdxDesc.getRecurrenceType()->getScalarSizeInBits());
525 }
526 } else {
527 for (Type *T : ElementTypesInLoop) {
528 MinWidth = std::min<unsigned>(
529 MinWidth, DL.getTypeSizeInBits(T->getScalarType()).getFixedValue());
530 MaxWidth = std::max<unsigned>(
531 MaxWidth, DL.getTypeSizeInBits(T->getScalarType()).getFixedValue());
532 }
533 }
534
535 // If the loop has no loads/stores or reductions (e.g. a search loop with an
536 // early exit), MinWidth is never updated and is left at its sentinel value.
537 // Fall back to MaxWidth to keep the SmallestType <= WidestType invariant, so
538 // callers such as the max-bandwidth VF computation don't divide by the
539 // sentinel and collapse the VF to zero.
540 if (MinWidth == -1U)
541 MinWidth = MaxWidth;
542
543 return {MinWidth, MaxWidth};
544}
545
547 const SmallPtrSetImpl<const Value *> *ValuesToIgnore) {
548 ElementTypesInLoop.clear();
549 // For each block.
550 for (BasicBlock *BB : TheLoop->blocks()) {
551 // For each instruction in the loop.
552 for (Instruction &I : *BB) {
553 Type *T = I.getType();
554
555 // Skip ignored values.
556 if (ValuesToIgnore && ValuesToIgnore->contains(&I))
557 continue;
558
559 // Only examine Loads, Stores and PHINodes.
561 continue;
562
563 // Examine PHI nodes that are reduction variables. Update the type to
564 // account for the recurrence type.
565 if (auto *PN = dyn_cast<PHINode>(&I)) {
566 if (!Legal->isReductionVariable(PN))
567 continue;
568 const RecurrenceDescriptor &RdxDesc =
569 Legal->getRecurrenceDescriptor(PN);
571 TTI.preferInLoopReduction(RdxDesc.getRecurrenceKind(),
572 RdxDesc.getRecurrenceType()))
573 continue;
574 T = RdxDesc.getRecurrenceType();
575 }
576
577 // Examine the stored values.
578 if (auto *ST = dyn_cast<StoreInst>(&I))
579 T = ST->getValueOperand()->getType();
580
581 assert(T->isSized() &&
582 "Expected the load/store/recurrence type to be sized");
583
584 ElementTypesInLoop.insert(T);
585 }
586 }
587}
588
589void VFSelectionContext::initializeVScaleForTuning() {
591 return;
592
593 if (F.hasFnAttribute(Attribute::VScaleRange)) {
594 auto Attr = F.getFnAttribute(Attribute::VScaleRange);
595 auto Min = Attr.getVScaleRangeMin();
596 auto Max = Attr.getVScaleRangeMax();
597 if (Max && Min == Max) {
598 VScaleForTuning = Max;
599 return;
600 }
601 }
602
603 VScaleForTuning = TTI.getVScaleForTuning();
604}
605
607 const RecurrenceDescriptor &RdxDesc) const {
608 return !Hints->allowReordering() && RdxDesc.isOrdered();
609}
610
612 LLVM_DEBUG(dbgs() << "LV: Performing code size checks.\n");
613
614 Loop *L = const_cast<Loop *>(TheLoop);
615 if (Legal->getRuntimePointerChecking()->Need) {
617 "Runtime ptr check is required with -Os/-Oz",
618 "runtime pointer checks needed. Enable vectorization of this "
619 "loop with '#pragma clang loop vectorize(enable)' when "
620 "compiling with -Os/-Oz",
621 "CantVersionLoopWithOptForSize", ORE, L);
622 return true;
623 }
624
625 if (!PSE.getPredicate().isAlwaysTrue()) {
627 "Runtime SCEV check is required with -Os/-Oz",
628 "runtime SCEV checks needed. Enable vectorization of this "
629 "loop with '#pragma clang loop vectorize(enable)' when "
630 "compiling with -Os/-Oz",
631 "CantVersionLoopWithOptForSize", ORE, L);
632 return true;
633 }
634
635 // FIXME: Avoid specializing for stride==1 instead of bailing out.
636 if (!Legal->getLAI()->getSymbolicStrides().empty()) {
638 "Runtime stride check for small trip count",
639 "runtime stride == 1 checks needed. Enable vectorization of "
640 "this loop without such check by compiling with -Os/-Oz",
641 "CantVersionLoopWithOptForSize", ORE, L);
642 return true;
643 }
644
645 return false;
646}
647
649 MinBWs = computeMinimumValueSizes(TheLoop->getBlocks(), *DB, &TTI);
650}
651
653 // Avoid duplicating work finding in-loop reductions.
654 if (!InLoopReductions.empty())
655 return;
656
657 for (const auto &Reduction : Legal->getReductionVars()) {
658 PHINode *Phi = Reduction.first;
659 const RecurrenceDescriptor &RdxDesc = Reduction.second;
660
661 // Multi-use reductions (e.g., used in FindLastIV patterns) are handled
662 // separately and should not be considered for in-loop reductions.
663 if (RdxDesc.hasUsesOutsideReductionChain())
664 continue;
665
666 // We don't collect reductions that are type promoted (yet).
667 if (RdxDesc.getRecurrenceType() != Phi->getType())
668 continue;
669
670 // In-loop AnyOf and FindIV reductions are not yet supported.
671 RecurKind Kind = RdxDesc.getRecurrenceKind();
675 continue;
676
677 // If the target would prefer this reduction to happen "in-loop", then we
678 // want to record it as such.
680 !TTI.preferInLoopReduction(Kind, Phi->getType()))
681 continue;
682
683 // Check that we can correctly put the reductions into the loop, by
684 // finding the chain of operations that leads from the phi to the loop
685 // exit value.
686 SmallVector<Instruction *, 4> ReductionOperations =
687 RdxDesc.getReductionOpChain(Phi, const_cast<Loop *>(TheLoop));
688 bool InLoop = !ReductionOperations.empty();
689
690 if (InLoop) {
691 InLoopReductions.insert(Phi);
692 // Add the elements to InLoopReductionImmediateChains for cost modelling.
693 Instruction *LastChain = Phi;
694 for (auto *I : ReductionOperations) {
695 InLoopReductionImmediateChains[I] = LastChain;
696 LastChain = I;
697 }
698 }
699 LLVM_DEBUG(dbgs() << "LV: Using " << (InLoop ? "inloop" : "out of loop")
700 << " reduction for phi: " << *Phi << "\n");
701 }
702}
703
704bool LoopVectorizationPlanner::isMoreProfitable(const VectorizationFactor &A,
705 const VectorizationFactor &B,
706 const unsigned MaxTripCount,
707 bool HasTail,
708 bool IsEpilogue) const {
709 InstructionCost CostA = A.Cost;
710 InstructionCost CostB = B.Cost;
711
712 // When there is a hint to always prefer scalable vectors, honour that hint.
714 if (A.Width.isScalable() && CostA.isValid() && !B.Width.isScalable() &&
715 !B.Width.isScalar())
716 return true;
717
718 // Favor fixed VFs for epilogue loops by scaling the costs of scalable VFs
719 // 'ScalableEpilogueVFCostScaleFactor' (default 2.0). This is intended to
720 // model that fixed VFs are more likely to be fully unrolled (or optimized
721 // out) post vectorization. TODO: Reconsider this restriction for predicated
722 // epilogues (once supported).
723 if (IsEpilogue && A.Width.isScalable() != B.Width.isScalable() &&
724 A.Cost.isValid() && B.Cost.isValid()) {
725 auto [FixedCost, ScalableCost] = std::make_pair(CostA, CostB);
726 if (B.Width.isFixed())
727 std::swap(FixedCost, ScalableCost);
728
729 ScalableCost *= ScalableEpilogueVFCostScaleFactor;
730
731 if (FixedCost <= ScalableCost)
732 return A.Width.isFixed();
733 }
734
735 // Improve estimate for the vector width if it is scalable.
736 unsigned EstimatedWidthA = A.Width.getKnownMinValue();
737 unsigned EstimatedWidthB = B.Width.getKnownMinValue();
738 if (std::optional<unsigned> VScale = Config.getVScaleForTuning()) {
739 if (A.Width.isScalable())
740 EstimatedWidthA *= *VScale;
741 if (B.Width.isScalable())
742 EstimatedWidthB *= *VScale;
743 }
744
745 // When optimizing for size choose whichever is smallest, which will be the
746 // one with the smallest cost for the whole loop. On a tie pick the larger
747 // vector width, on the assumption that throughput will be greater.
748 if (Config.CostKind == TTI::TCK_CodeSize)
749 return CostA < CostB ||
750 (CostA == CostB && EstimatedWidthA > EstimatedWidthB);
751
752 // Assume vscale may be larger than 1 (or the value being tuned for),
753 // so that scalable vectorization is slightly favorable over fixed-width
754 // vectorization.
755 bool PreferScalable = !TTI.preferFixedOverScalableIfEqualCost() &&
756 A.Width.isScalable() && !B.Width.isScalable();
757
758 auto CmpFn = [PreferScalable](const InstructionCost &LHS,
759 const InstructionCost &RHS) {
760 return PreferScalable ? LHS <= RHS : LHS < RHS;
761 };
762
763 // To avoid the need for FP division:
764 // (CostA / EstimatedWidthA) < (CostB / EstimatedWidthB)
765 // <=> (CostA * EstimatedWidthB) < (CostB * EstimatedWidthA)
766 bool LowerCostWithoutTC =
767 CmpFn(CostA * EstimatedWidthB, CostB * EstimatedWidthA);
768 if (!MaxTripCount)
769 return LowerCostWithoutTC;
770
771 auto GetCostForTC = [MaxTripCount, HasTail](unsigned VF,
772 InstructionCost VectorCost,
773 InstructionCost ScalarCost) {
774 // If the trip count is a known (possibly small) constant, the trip count
775 // will be rounded up to an integer number of iterations under
776 // FoldTailByMasking. The total cost in that case will be
777 // VecCost*ceil(TripCount/VF). When not folding the tail, the total
778 // cost will be VecCost*floor(TC/VF) + ScalarCost*(TC%VF). There will be
779 // some extra overheads, but for the purpose of comparing the costs of
780 // different VFs we can use this to compare the total loop-body cost
781 // expected after vectorization.
782 if (HasTail)
783 return VectorCost * (MaxTripCount / VF) +
784 ScalarCost * (MaxTripCount % VF);
785 return VectorCost * divideCeil(MaxTripCount, VF);
786 };
787
788 auto RTCostA = GetCostForTC(EstimatedWidthA, CostA, A.ScalarCost);
789 auto RTCostB = GetCostForTC(EstimatedWidthB, CostB, B.ScalarCost);
790 bool LowerCostWithTC = CmpFn(RTCostA, RTCostB);
791 LLVM_DEBUG(if (LowerCostWithTC != LowerCostWithoutTC) {
792 dbgs() << "LV: VF " << (LowerCostWithTC ? A.Width : B.Width)
793 << " has lower cost than VF "
794 << (LowerCostWithTC ? B.Width : A.Width)
795 << " when taking the cost of the remaining scalar loop iterations "
796 "into consideration for a maximum trip count of "
797 << MaxTripCount << ".\n";
798 });
799 return LowerCostWithTC;
800}
801
802bool LoopVectorizationPlanner::isMoreProfitable(const VectorizationFactor &A,
803 const VectorizationFactor &B,
804 bool HasTail,
805 bool IsEpilogue) const {
806 const unsigned MaxTripCount = PSE.getSmallConstantMaxTripCount();
807 return LoopVectorizationPlanner::isMoreProfitable(A, B, MaxTripCount, HasTail,
808 IsEpilogue);
809}
810
811// TODO: we could return a pair of values that specify the max VF and
812// min VF, to be used in `buildVPlans(MinVF, MaxVF)` instead of
813// `buildVPlans(VF, VF)`. We cannot do it because VPLAN at the moment
814// doesn't have a cost model that can choose which plan to execute if
815// more than one is generated.
818 if (UserVF.isScalable() && !supportsScalableVectors()) {
820 "Scalable vectorization requested but not supported by the target",
821 "the scalable user-specified vectorization width for outer-loop "
822 "vectorization cannot be used because the target does not support "
823 "scalable vectors.",
824 "ScalableVFUnfeasible", ORE, TheLoop);
826 }
827
828 ElementCount VF = UserVF;
829 if (VF.isZero()) {
830 auto [_, WidestType] = getSmallestAndWidestTypes();
831
832 auto RegKind = TTI.enableScalableVectorization()
835
836 TypeSize RegSize = TTI.getRegisterBitWidth(RegKind);
837 // The widest type may be wider than the register width and WidestType may
838 // not be a power of two; round the element count down to a power of two.
839 unsigned N = std::max<uint64_t>(
840 1, llvm::bit_floor(RegSize.getKnownMinValue() / WidestType));
841 VF = ElementCount::get(N, RegSize.isScalable());
842 LLVM_DEBUG(dbgs() << "LV: VPlan computed VF " << VF << ".\n");
843
844 // Make sure we have a VF > 1 for stress testing.
846 LLVM_DEBUG(dbgs() << "LV: VPlan stress testing: "
847 << "overriding computed VF.\n");
849 }
850 }
852 "VF needs to be a power of two");
853 if (VF.isScalar())
855 LLVM_DEBUG(dbgs() << "LV: Using " << (!UserVF.isZero() ? "user " : "")
856 << "VF " << VF << " to build VPlans.\n");
857 return FixedScalableVFPair(VF);
858}
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define DEBUG_TYPE
#define _
loop Loop Strength Reduction
This file defines the LoopVectorizationLegality class.
static cl::opt< float > ScalableEpilogueVFCostScaleFactor("scalable-epilogue-vf-cost-scale-factor", cl::init(2.0), cl::Hidden, cl::desc("Scale the cost of scalable epilogue VFs by this factor."))
static void debugVectorizationMessage(const StringRef Prefix, const StringRef DebugMsg, Instruction *I)
Write a DebugMsg about vectorization to the debug output stream.
static cl::opt< bool > ForceTargetSupportsGatherScatterOps("force-target-supports-gather-scatter-ops", cl::init(false), cl::Hidden, cl::desc("Assume the target supports gather/scatter operations (used for " "testing)."))
cl::opt< bool > VPlanBuildOuterloopStressTest
static cl::opt< bool > ForceTargetSupportsScalableVectors("force-target-supports-scalable-vectors", cl::init(false), cl::Hidden, cl::desc("Pretend that scalable vectors are supported, even if the target does " "not support them. This flag should only be used for testing."))
static cl::opt< bool > ConsiderRegPressure("vectorizer-consider-reg-pressure", cl::init(false), cl::Hidden, cl::desc("Discard VFs if their register pressure is too high."))
static cl::opt< bool > UseWiderVFIfCallVariantsPresent("vectorizer-maximize-bandwidth-for-vector-calls", cl::init(true), cl::Hidden, cl::desc("Try wider VFs if they enable the use of vector variants"))
static OptimizationRemarkAnalysis createLVAnalysis(StringRef RemarkName, const Loop *TheLoop, Instruction *I, DebugLoc DL={})
Create an analysis remark that explains why vectorization failed RemarkName is the identifier for the...
static cl::opt< bool > ForceTargetSupportsMaskedMemoryOps("force-target-supports-masked-memory-ops", cl::init(false), cl::Hidden, cl::desc("Assume the target supports masked memory operations (used for " "testing)."))
Note: This currently only applies to llvm.masked.load and llvm.masked.store.
static cl::opt< bool > MaximizeBandwidth("vectorizer-maximize-bandwidth", cl::init(false), cl::Hidden, cl::desc("Maximize bandwidth when selecting vectorization factor which " "will be determined by the smallest type in loop."))
This file provides a LoopVectorizationPlanner class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
const char * Msg
#define LLVM_DEBUG(...)
Definition Debug.h:119
Value * RHS
Value * LHS
LLVM Basic Block Representation.
Definition BasicBlock.h:62
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
constexpr bool isVector() const
One or more elements.
Definition TypeSize.h:324
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition TypeSize.h:312
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:309
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
Definition TypeSize.h:315
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:320
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
BlockT * getHeader() const
bool hasVectorCallVariants() const
Returns true if there is at least one function call in the loop which has a vectorized variant availa...
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
Definition LoopInfo.cpp:695
Diagnostic information for optimization analysis remarks.
The optimization diagnostic interface.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
Diagnostic information for applied optimization remarks.
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
Type * getRecurrenceType() const
Returns the type of the recurrence.
bool hasUsesOutsideReductionChain() const
Returns true if the reduction PHI has any uses outside the reduction chain.
static bool isFindLastRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
LLVM_ABI SmallVector< Instruction *, 4 > getReductionOpChain(PHINode *Phi, Loop *L) const
Attempts to find a chain of operations from Phi to LoopExitInst that can be treated as a set of reduc...
static bool isAnyOfRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
RecurKind getRecurrenceKind() const
bool isOrdered() const
Expose an ordered FP reduction to the instance users.
static bool isFindIVRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool contains(ConstPtrType Ptr) const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
@ TCK_CodeSize
Instruction code size.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
FixedScalableVFPair computeVPlanOuterloopVF(ElementCount UserVF)
Returns a scalable VF to use for outer-loop vectorization if the target supports it and a fixed VF ot...
std::pair< unsigned, unsigned > getSmallestAndWidestTypes() const
bool runtimeChecksRequired()
Check whether vectorization would require runtime checks.
bool isLegalGatherOrScatter(Value *V, ElementCount VF) const
Returns true if the target machine can represent V as a masked gather or scatter operation.
bool isLegalMaskedLoadOrStore(bool IsLoad, Type *ScalarTy, Align Alignment, unsigned AddressSpace) const
Returns true if the target machine supports a masked load (if IsLoad) or masked store of scalar type ...
void collectInLoopReductions()
Split reductions into those that happen in the loop, and those that happen outside.
FixedScalableVFPair computeFeasibleMaxVF(unsigned MaxTripCount, ElementCount UserVF, unsigned UserIC, bool FoldTailByMasking, bool RequiresScalarEpilogue)
const LoopVectorizeHints & getHints() const
bool useOrderedReductions(const RecurrenceDescriptor &RdxDesc) const
Returns true if we should use strict in-order reductions for the given RdxDesc.
bool shouldConsiderRegPressureForVF(ElementCount VF) const
void collectElementTypesForWidening(const SmallPtrSetImpl< const Value * > *ValuesToIgnore=nullptr)
Collect element types in the loop that need widening.
std::optional< unsigned > getVScaleForTuning() const
void computeMinimalBitwidths()
Compute smallest bitwidth each instruction can be represented with.
LLVM Value Representation.
Definition Value.h:75
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:230
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:216
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
constexpr bool isZero() const
Definition TypeSize.h:153
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:223
void reportVectorizationFailure(const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr)
Reports a vectorization failure: print DebugMsg for debugging purposes along with the corresponding o...
void reportVectorizationInfo(const StringRef Msg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr, DebugLoc DL={})
Reports an informative message: print Msg for debugging purposes as well as an optimization remark.
void reportVectorization(OptimizationRemarkEmitter *ORE, Loop *TheLoop, ElementCount VFWidth, unsigned IC)
Report successful vectorization of the loop.
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
Align getLoadStoreAlignment(const Value *I)
A helper function that returns the alignment of load or store instruction.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
std::optional< unsigned > getMaxVScale(const Function &F, const TargetTransformInfo &TTI)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:395
TargetTransformInfo TTI
RecurKind
These are the kinds of recurrences that we support.
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
LLVM_ABI MapVector< Instruction *, uint64_t > computeMinimumValueSizes(ArrayRef< BasicBlock * > Blocks, DemandedBits &DB, const TargetTransformInfo *TTI=nullptr)
Compute a map of integer instructions to their minimum legal type size.
cl::opt< bool > PreferInLoopReductions
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
A class that represents two vectorization factors (initialized with 0 by default).
static FixedScalableVFPair getNone()
TODO: The following VectorizationFactor was pulled out of LoopVectorizationCostModel class.
static LLVM_ABI ElementCount VectorizationFactor
VF as overridden by the user.