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
16#include "VPlanUtils.h"
17#include "VectorizeOptions.h"
22#include "llvm/Support/Debug.h"
26
27using namespace llvm;
28using namespace LoopVectorizationUtils;
29
30#define DEBUG_TYPE "loop-vectorize"
31
32/// Write a \p DebugMsg about vectorization to the debug output stream. If \p I
33/// is passed, the message relates to that particular instruction.
34#ifndef NDEBUG
35static void debugVectorizationMessage(const StringRef Prefix,
36 const StringRef DebugMsg,
37 Instruction *I) {
38 dbgs() << "LV: " << Prefix << DebugMsg;
39 if (I != nullptr)
40 dbgs() << " " << *I;
41 else
42 dbgs() << '.';
43 dbgs() << '\n';
44}
45#endif
46
47/// Create an analysis remark that explains why vectorization failed
48/// \p RemarkName is the identifier for the remark. If \p I is passed it is an
49/// instruction that prevents vectorization. Otherwise \p TheLoop is used for
50/// the location of the remark. If \p DL is passed, use it as debug location for
51/// the remark. \return the remark object that can be streamed to.
53 const Loop *TheLoop,
55 DebugLoc DL = {}) {
56 BasicBlock *CodeRegion = I ? I->getParent() : TheLoop->getHeader();
57 // If debug location is attached to the instruction, use it. Otherwise if DL
58 // was not provided, use the loop's.
59 if (I && I->getDebugLoc())
60 DL = I->getDebugLoc();
61 else if (!DL)
62 DL = TheLoop->getStartLoc();
63
64 return OptimizationRemarkAnalysis(DEBUG_TYPE, RemarkName, DL, CodeRegion);
65}
66
68 const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag,
69 OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I) {
70 LLVM_DEBUG(debugVectorizationMessage("Not vectorizing: ", DebugMsg, I));
71 ORE->emit(createLVAnalysis(ORETag, TheLoop, I)
72 << "loop not vectorized: " << OREMsg);
73}
74
76 const StringRef Msg, const StringRef ORETag, OptimizationRemarkEmitter *ORE,
77 const Loop *TheLoop, Instruction *I, DebugLoc DL) {
79 ORE->emit(createLVAnalysis(ORETag, TheLoop, I, DL) << Msg);
80}
81
83 Loop *TheLoop,
84 ElementCount VFWidth,
85 unsigned IC) {
87 "Vectorizing: ", TheLoop->isInnermost() ? "innermost loop" : "outer loop",
88 nullptr));
89 StringRef LoopType = TheLoop->isInnermost() ? "" : "outer ";
90 ORE->emit([&]() {
91 return OptimizationRemark(DEBUG_TYPE, "Vectorized", TheLoop->getStartLoc(),
92 TheLoop->getHeader())
93 << "vectorized " << LoopType << "loop (vectorization width: "
94 << ore::NV("VectorizationFactor", VFWidth)
95 << ", interleaved count: " << ore::NV("InterleaveCount", IC) << ")";
96 });
97}
98
100 Align Alignment,
101 unsigned AddressSpace) const {
102 return Opts.force_target_supports_masked_memory_ops ||
103 (IsLoad ? TTI.isLegalMaskedLoad(ScalarTy, Alignment, AddressSpace)
104 : TTI.isLegalMaskedStore(ScalarTy, Alignment, AddressSpace));
105}
106
108 Align Alignment,
109 ElementCount VF) const {
110 Type *VectorTy = toVectorTy(ScalarTy, VF);
111 return Opts.force_target_supports_gather_scatter_ops ||
112 (IsLoad ? TTI.isLegalMaskedGather(VectorTy, Alignment)
113 : TTI.isLegalMaskedScatter(VectorTy, Alignment));
114}
115
117 return TTI.supportsScalableVectors() ||
118 Opts.force_target_supports_scalable_vectors ||
120}
121
122bool VFSelectionContext::useMaxBandwidth(bool IsScalable) const {
126 return valueOr(Opts.vectorizer_maximize_bandwidth,
127 TTI.shouldMaximizeVectorBandwidth(RegKind) ||
128 (Opts.vectorizer_maximize_bandwidth_for_vector_calls &&
129 Legal->hasVectorCallVariants()));
130}
131
133 if (Opts.vectorizer_consider_reg_pressure != BoolOrDefault::Default)
134 return Opts.vectorizer_consider_reg_pressure == BoolOrDefault::True;
135
136 // TODO: We should eventually consider register pressure for all targets. The
137 // TTI hook is temporary whilst target-specific issues are being fixed.
138 if (TTI.shouldConsiderVectorizationRegPressure())
139 return true;
140
141 if (!useMaxBandwidth(VF.isScalable()))
142 return false;
143 // Only calculate register pressure for VFs enabled by MaxBandwidth.
145 VF, VF.isScalable() ? MaxPermissibleVFWithoutMaxBW.ScalableVF
146 : MaxPermissibleVFWithoutMaxBW.FixedVF);
147}
148
149ElementCount VFSelectionContext::clampVFByMaxTripCount(
150 ElementCount VF, unsigned MaxTripCount, unsigned UserIC,
151 bool FoldTailByMasking, bool RequiresScalarEpilogue) const {
152 unsigned EstimatedVF = VF.getKnownMinValue();
153 if (VF.isScalable() && F.hasFnAttribute(Attribute::VScaleRange)) {
154 auto Attr = F.getFnAttribute(Attribute::VScaleRange);
155 auto Min = Attr.getVScaleRangeMin();
156 EstimatedVF *= Min;
157 }
158
159 // When a scalar epilogue is required, at least one iteration of the scalar
160 // loop has to execute. Adjust MaxTripCount accordingly to avoid picking a
161 // max VF that results in a dead vector loop.
162 if (MaxTripCount > 0 && RequiresScalarEpilogue)
163 MaxTripCount -= 1;
164
165 // When the user specifies an interleave count, we need to ensure that
166 // VF * UserIC <= MaxTripCount to avoid a dead vector loop.
167 unsigned IC = UserIC > 0 ? UserIC : 1;
168 unsigned EstimatedVFTimesIC = EstimatedVF * IC;
169
170 if (MaxTripCount && MaxTripCount <= EstimatedVFTimesIC &&
171 (!FoldTailByMasking || isPowerOf2_32(MaxTripCount))) {
172 // If upper bound loop trip count (TC) is known at compile time there is no
173 // point in choosing VF greater than TC / IC (as done in the loop below).
174 // Select maximum power of two which doesn't exceed TC / IC. If VF is
175 // scalable, we only fall back on a fixed VF when the TC is less than or
176 // equal to the known number of lanes.
177 auto ClampedUpperTripCount = llvm::bit_floor(MaxTripCount / IC);
178 if (ClampedUpperTripCount == 0)
179 ClampedUpperTripCount = 1;
180 LLVM_DEBUG(dbgs() << "LV: Clamping the MaxVF to maximum power of two not "
181 "exceeding the constant trip count"
182 << (UserIC > 0 ? " divided by UserIC" : "") << ": "
183 << ClampedUpperTripCount << "\n");
184 return ElementCount::get(ClampedUpperTripCount,
185 FoldTailByMasking ? VF.isScalable() : false);
186 }
187 return VF;
188}
189
190ElementCount VFSelectionContext::getMaximizedVFForTarget(
191 unsigned MaxTripCount, unsigned SmallestType, unsigned WidestType,
192 ElementCount MaxSafeVF, unsigned UserIC, bool FoldTailByMasking,
193 bool RequiresScalarEpilogue) {
194 bool ComputeScalableMaxVF = MaxSafeVF.isScalable();
195 const TypeSize WidestRegister = TTI.getRegisterBitWidth(
196 ComputeScalableMaxVF ? TargetTransformInfo::RGK_ScalableVector
198
199 // Convenience function to return the minimum of two ElementCounts.
200 auto MinVF = [](const ElementCount &LHS, const ElementCount &RHS) {
201 assert((LHS.isScalable() == RHS.isScalable()) &&
202 "Scalable flags must match");
204 };
205
206 // Ensure MaxVF is a power of 2; the dependence distance bound may not be.
207 // Note that both WidestRegister and WidestType may not be a powers of 2.
208 auto MaxVectorElementCount = ElementCount::get(
209 llvm::bit_floor(WidestRegister.getKnownMinValue() / WidestType),
210 ComputeScalableMaxVF);
211 MaxVectorElementCount = MinVF(MaxVectorElementCount, MaxSafeVF);
212 LLVM_DEBUG(dbgs() << "LV: The Widest register safe to use is: "
213 << (MaxVectorElementCount * WidestType) << " bits.\n");
214
215 if (!MaxVectorElementCount) {
216 LLVM_DEBUG(dbgs() << "LV: The target has no "
217 << (ComputeScalableMaxVF ? "scalable" : "fixed")
218 << " vector registers.\n");
219 return ElementCount::getFixed(1);
220 }
221
222 ElementCount MaxVF =
223 clampVFByMaxTripCount(MaxVectorElementCount, MaxTripCount, UserIC,
224 FoldTailByMasking, RequiresScalarEpilogue);
225 // If the MaxVF was already clamped, there's no point in trying to pick a
226 // larger one.
227 if (MaxVF != MaxVectorElementCount)
228 return MaxVF;
229
230 if (MaxVF.isScalable())
231 MaxPermissibleVFWithoutMaxBW.ScalableVF = MaxVF;
232 else
233 MaxPermissibleVFWithoutMaxBW.FixedVF = MaxVF;
234
235 if (useMaxBandwidth(ComputeScalableMaxVF)) {
236 auto MaxVectorElementCountMaxBW = ElementCount::get(
237 llvm::bit_floor(WidestRegister.getKnownMinValue() / SmallestType),
238 ComputeScalableMaxVF);
239 MaxVF = MinVF(MaxVectorElementCountMaxBW, MaxSafeVF);
240
241 if (ElementCount MinVF =
242 TTI.getMinimumVF(SmallestType, ComputeScalableMaxVF)) {
243 if (ElementCount::isKnownLT(MaxVF, MinVF)) {
244 LLVM_DEBUG(dbgs() << "LV: Overriding calculated MaxVF(" << MaxVF
245 << ") with target's minimum: " << MinVF << '\n');
246 MaxVF = MinVF;
247 }
248 }
249
250 MaxVF = clampVFByMaxTripCount(MaxVF, MaxTripCount, UserIC,
251 FoldTailByMasking, RequiresScalarEpilogue);
252 }
253 return MaxVF;
254}
255
256std::optional<unsigned> llvm::getMaxVScale(const Function &F) {
257 if (F.hasFnAttribute(Attribute::VScaleRange))
258 return F.getFnAttribute(Attribute::VScaleRange).getVScaleRangeMax();
259
260 return std::nullopt;
261}
262
263std::optional<uint64_t>
265 if (EC.isFixed())
266 return EC.getFixedValue();
267
268 if (std::optional<unsigned> MaxVScale = getMaxVScale(F))
269 return uint64_t(EC.getKnownMinValue()) * *MaxVScale;
270
271 return std::nullopt;
272}
273
274bool VFSelectionContext::isScalableVectorizationAllowed() {
275 if (IsScalableVectorizationAllowed)
276 return *IsScalableVectorizationAllowed;
277
278 IsScalableVectorizationAllowed = false;
280 return false;
281
282 if (Hints->isScalableVectorizationDisabled()) {
283 reportVectorizationInfo("Scalable vectorization is explicitly disabled",
284 "ScalableVectorizationDisabled", ORE, TheLoop);
285 return false;
286 }
287
288 LLVM_DEBUG(dbgs() << "LV: Scalable vectorization is available\n");
289
290 auto MaxScalableVF = ElementCount::getScalable(
291 std::numeric_limits<ElementCount::ScalarTy>::max());
292
293 // Test that the loop-vectorizer can legalize all operations for this MaxVF.
294 // FIXME: While for scalable vectors this is currently sufficient, this should
295 // be replaced by a more detailed mechanism that filters out specific VFs,
296 // instead of invalidating vectorization for a whole set of VFs based on the
297 // MaxVF.
298
299 // Disable scalable vectorization if the loop contains unsupported reductions.
300 if (!all_of(Legal->getReductionVars(), [&](const auto &Reduction) -> bool {
301 return TTI.isLegalToVectorizeReduction(Reduction.second, MaxScalableVF);
302 })) {
304 "Scalable vectorization not supported for the reduction "
305 "operations found in this loop.",
306 "ScalableVFUnfeasible", ORE, TheLoop);
307 return false;
308 }
309
310 // Disable scalable vectorization if the loop contains any instructions
311 // with element types not supported for scalable vectors.
312 if (any_of(ElementTypesInLoop, [&](Type *Ty) {
313 return !Ty->isVoidTy() && !TTI.isElementTypeLegalForScalableVector(Ty);
314 })) {
315 reportVectorizationInfo("Scalable vectorization is not supported "
316 "for all element types found in this loop.",
317 "ScalableVFUnfeasible", ORE, TheLoop);
318 return false;
319 }
320
321 if (!Legal->isSafeForAnyVectorWidth() && !getMaxVScale(F)) {
322 reportVectorizationInfo("The target does not provide maximum vscale value "
323 "for safe distance analysis.",
324 "ScalableVFUnfeasible", ORE, TheLoop);
325 return false;
326 }
327
328 IsScalableVectorizationAllowed = true;
329 return true;
330}
331
333VFSelectionContext::getMaxLegalScalableVF(unsigned MaxSafeElements) {
334 if (!isScalableVectorizationAllowed())
336
337 auto MaxScalableVF = ElementCount::getScalable(
338 std::numeric_limits<ElementCount::ScalarTy>::max());
339 if (Legal->isSafeForAnyVectorWidth())
340 return MaxScalableVF;
341
342 std::optional<unsigned> MaxVScale = getMaxVScale(F);
343 // Limit MaxScalableVF by the maximum safe dependence distance.
344 MaxScalableVF = ElementCount::getScalable(MaxSafeElements / *MaxVScale);
345
346 if (!MaxScalableVF)
348 "Max legal vector width too small, scalable vectorization "
349 "unfeasible.",
350 "ScalableVFUnfeasible", ORE, TheLoop);
351
352 return MaxScalableVF;
353}
354
356 unsigned MaxTripCount, ElementCount UserVF, unsigned UserIC,
357 bool FoldTailByMasking, bool RequiresScalarEpilogue) {
358 auto [SmallestType, WidestType] = getSmallestAndWidestTypes();
359
360 // Get the maximum safe dependence distance in bits computed by LAA.
361 // It is computed by MaxVF * sizeOf(type) * 8, where type is taken from
362 // the memory accesses that is most restrictive (involved in the smallest
363 // dependence distance).
364 unsigned MaxSafeElementsPowerOf2 =
365 llvm::bit_floor(Legal->getMaxSafeVectorWidthInBits() / WidestType);
366 if (!Legal->isSafeForAnyStoreLoadForwardDistances()) {
367 unsigned SLDist = Legal->getMaxStoreLoadForwardSafeDistanceInBits();
368 MaxSafeElementsPowerOf2 =
369 std::min(MaxSafeElementsPowerOf2, SLDist / WidestType);
370 }
371
372 auto MaxSafeFixedVF = ElementCount::getFixed(MaxSafeElementsPowerOf2);
373 auto MaxSafeScalableVF = getMaxLegalScalableVF(MaxSafeElementsPowerOf2);
374
375 if (!Legal->isSafeForAnyVectorWidth())
376 MaxSafeElements = MaxSafeElementsPowerOf2;
377
378 LLVM_DEBUG(dbgs() << "LV: The max safe fixed VF is: " << MaxSafeFixedVF
379 << ".\n");
380 LLVM_DEBUG(dbgs() << "LV: The max safe scalable VF is: " << MaxSafeScalableVF
381 << ".\n");
382
383 // First analyze the UserVF, fall back if the UserVF should be ignored.
384 if (UserVF) {
385 auto MaxSafeUserVF =
386 UserVF.isScalable() ? MaxSafeScalableVF : MaxSafeFixedVF;
387
388 if (ElementCount::isKnownLE(UserVF, MaxSafeUserVF)) {
389 // If `VF=vscale x N` is safe, then so is `VF=N`
390 if (UserVF.isScalable())
391 return FixedScalableVFPair(
392 ElementCount::getFixed(UserVF.getKnownMinValue()), UserVF);
393
394 return UserVF;
395 }
396
397 assert(ElementCount::isKnownGT(UserVF, MaxSafeUserVF));
398
399 // Only clamp if the UserVF is not scalable. If the UserVF is scalable, it
400 // is better to ignore the hint and let the compiler choose a suitable VF.
401 if (!UserVF.isScalable()) {
402 LLVM_DEBUG(dbgs() << "LV: User VF=" << UserVF
403 << " is unsafe, clamping to max safe VF="
404 << MaxSafeFixedVF << ".\n");
405 ORE->emit([&]() {
406 return OptimizationRemarkAnalysis(DEBUG_TYPE, "VectorizationFactor",
407 TheLoop->getStartLoc(),
408 TheLoop->getHeader())
409 << "User-specified vectorization factor "
410 << ore::NV("UserVectorizationFactor", UserVF)
411 << " is unsafe, clamping to maximum safe vectorization factor "
412 << ore::NV("VectorizationFactor", MaxSafeFixedVF);
413 });
414 return MaxSafeFixedVF;
415 }
416
418 LLVM_DEBUG(dbgs() << "LV: User VF=" << UserVF
419 << " is ignored because scalable vectors are not "
420 "available.\n");
421 ORE->emit([&]() {
422 return OptimizationRemarkAnalysis(DEBUG_TYPE, "VectorizationFactor",
423 TheLoop->getStartLoc(),
424 TheLoop->getHeader())
425 << "User-specified vectorization factor "
426 << ore::NV("UserVectorizationFactor", UserVF)
427 << " is ignored because the target does not support scalable "
428 "vectors. The compiler will pick a more suitable value.";
429 });
430 } else {
431 LLVM_DEBUG(dbgs() << "LV: User VF=" << UserVF
432 << " is unsafe. Ignoring scalable UserVF.\n");
433 ORE->emit([&]() {
434 return OptimizationRemarkAnalysis(DEBUG_TYPE, "VectorizationFactor",
435 TheLoop->getStartLoc(),
436 TheLoop->getHeader())
437 << "User-specified vectorization factor "
438 << ore::NV("UserVectorizationFactor", UserVF)
439 << " is unsafe. Ignoring the hint to let the compiler pick a "
440 "more suitable value.";
441 });
442 }
443 }
444
445 LLVM_DEBUG(dbgs() << "LV: The Smallest and Widest types: " << SmallestType
446 << " / " << WidestType << " bits.\n");
447
450 if (auto MaxVF = getMaximizedVFForTarget(
451 MaxTripCount, SmallestType, WidestType, MaxSafeFixedVF, UserIC,
452 FoldTailByMasking, RequiresScalarEpilogue))
453 Result.FixedVF = MaxVF;
454
455 if (auto MaxVF = getMaximizedVFForTarget(
456 MaxTripCount, SmallestType, WidestType, MaxSafeScalableVF, UserIC,
457 FoldTailByMasking, RequiresScalarEpilogue))
458 if (MaxVF.isScalable()) {
459 Result.ScalableVF = MaxVF;
460 LLVM_DEBUG(dbgs() << "LV: Found feasible scalable VF = " << MaxVF
461 << "\n");
462 }
463
464 return Result;
465}
466
467std::pair<unsigned, unsigned>
469 unsigned MinWidth = -1U;
470 unsigned MaxWidth = 8;
471 const DataLayout &DL = F.getDataLayout();
472 // For in-loop reductions, no element types are added to ElementTypesInLoop
473 // if there are no loads/stores in the loop. In this case, check through the
474 // reduction variables to determine the maximum width.
475 if (ElementTypesInLoop.empty()) {
476 for (const RecurrenceDescriptor &RdxDesc :
477 Legal->getReductionVars().values()) {
478 // When finding the min width used by the recurrence we need to account
479 // for casts on the input operands of the recurrence.
480 MinWidth = std::min(
481 MinWidth,
482 std::min(RdxDesc.getMinWidthCastToRecurrenceTypeInBits(),
483 RdxDesc.getRecurrenceType()->getScalarSizeInBits()));
484 MaxWidth = std::max(MaxWidth,
485 RdxDesc.getRecurrenceType()->getScalarSizeInBits());
486 }
487 } else {
488 for (Type *T : ElementTypesInLoop) {
489 MinWidth = std::min<unsigned>(
490 MinWidth, DL.getTypeSizeInBits(T->getScalarType()).getFixedValue());
491 MaxWidth = std::max<unsigned>(
492 MaxWidth, DL.getTypeSizeInBits(T->getScalarType()).getFixedValue());
493 }
494 }
495
496 // If the loop has no loads/stores or reductions (e.g. a search loop with an
497 // early exit), MinWidth is never updated and is left at its sentinel value.
498 // Fall back to MaxWidth to keep the SmallestType <= WidestType invariant, so
499 // callers such as the max-bandwidth VF computation don't divide by the
500 // sentinel and collapse the VF to zero.
501 if (MinWidth == -1U)
502 MinWidth = MaxWidth;
503
504 return {MinWidth, MaxWidth};
505}
506
508 const SmallPtrSetImpl<const Value *> *ValuesToIgnore) {
509 ElementTypesInLoop.clear();
510 // For each block.
511 for (BasicBlock *BB : TheLoop->blocks()) {
512 // For each instruction in the loop.
513 for (Instruction &I : *BB) {
514 Type *T = I.getType();
515
516 // Skip ignored values.
517 if (ValuesToIgnore && ValuesToIgnore->contains(&I))
518 continue;
519
520 // Only examine Loads, Stores and PHINodes.
522 continue;
523
524 // Examine PHI nodes that are reduction variables. Update the type to
525 // account for the recurrence type.
526 if (auto *PN = dyn_cast<PHINode>(&I)) {
527 if (!Legal->isReductionVariable(PN))
528 continue;
529 const RecurrenceDescriptor &RdxDesc =
530 Legal->getRecurrenceDescriptor(PN);
531 if (Opts.prefer_inloop_reductions || useOrderedReductions(RdxDesc) ||
532 TTI.preferInLoopReduction(RdxDesc.getRecurrenceKind(),
533 RdxDesc.getRecurrenceType()))
534 continue;
535 T = RdxDesc.getRecurrenceType();
536 }
537
538 // Examine the stored values.
539 if (auto *ST = dyn_cast<StoreInst>(&I))
540 T = ST->getValueOperand()->getType();
541
542 assert(T->isSized() &&
543 "Expected the load/store/recurrence type to be sized");
544
545 ElementTypesInLoop.insert(T);
546 }
547 }
548}
549
550void VFSelectionContext::initializeVScaleForTuning() {
552 return;
553
554 if (F.hasFnAttribute(Attribute::VScaleRange)) {
555 auto Attr = F.getFnAttribute(Attribute::VScaleRange);
556 auto Min = Attr.getVScaleRangeMin();
557 auto Max = Attr.getVScaleRangeMax();
558 if (Max && Min == Max) {
559 VScaleForTuning = Max;
560 return;
561 }
562 }
563
564 VScaleForTuning = TTI.getVScaleForTuning();
565}
566
568 const RecurrenceDescriptor &RdxDesc) const {
569 return !Hints->allowReordering() && RdxDesc.isOrdered();
570}
571
573 LLVM_DEBUG(dbgs() << "LV: Performing code size checks.\n");
574
575 Loop *L = const_cast<Loop *>(TheLoop);
576 if (Legal->getRuntimePointerChecking()->Need) {
578 "Runtime ptr check is required with -Os/-Oz",
579 "runtime pointer checks needed. Enable vectorization of this "
580 "loop with '#pragma clang loop vectorize(enable)' when "
581 "compiling with -Os/-Oz",
582 "CantVersionLoopWithOptForSize", ORE, L);
583 return true;
584 }
585
586 if (!PSE.getPredicate().isAlwaysTrue()) {
588 "Runtime SCEV check is required with -Os/-Oz",
589 "runtime SCEV checks needed. Enable vectorization of this "
590 "loop with '#pragma clang loop vectorize(enable)' when "
591 "compiling with -Os/-Oz",
592 "CantVersionLoopWithOptForSize", ORE, L);
593 return true;
594 }
595
596 // FIXME: Avoid specializing for stride==1 instead of bailing out.
597 if (!Legal->getLAI()->getSymbolicStrides().empty()) {
599 "Runtime stride check for small trip count",
600 "runtime stride == 1 checks needed. Enable vectorization of "
601 "this loop without such check by compiling with -Os/-Oz",
602 "CantVersionLoopWithOptForSize", ORE, L);
603 return true;
604 }
605
606 return false;
607}
608
610 MinBWs = computeMinimumValueSizes(TheLoop->getBlocks(), *DB, &TTI);
611}
612
614 // Avoid duplicating work finding in-loop reductions.
615 if (!InLoopReductions.empty())
616 return;
617
618 for (const auto &Reduction : Legal->getReductionVars()) {
619 PHINode *Phi = Reduction.first;
620 const RecurrenceDescriptor &RdxDesc = Reduction.second;
621
622 // Multi-use reductions (e.g., used in FindLastIV patterns) are handled
623 // separately and should not be considered for in-loop reductions.
624 if (RdxDesc.hasUsesOutsideReductionChain())
625 continue;
626
627 // We don't collect reductions that are type promoted (yet).
628 if (RdxDesc.getRecurrenceType() != Phi->getType())
629 continue;
630
631 // In-loop AnyOf and FindIV reductions are not yet supported.
632 RecurKind Kind = RdxDesc.getRecurrenceKind();
636 continue;
637
638 // If the target would prefer this reduction to happen "in-loop", then we
639 // want to record it as such.
640 if (!Opts.prefer_inloop_reductions && !useOrderedReductions(RdxDesc) &&
641 !TTI.preferInLoopReduction(Kind, Phi->getType()))
642 continue;
643
644 // Check that we can correctly put the reductions into the loop, by
645 // finding the chain of operations that leads from the phi to the loop
646 // exit value.
647 SmallVector<Instruction *, 4> ReductionOperations =
648 RdxDesc.getReductionOpChain(Phi, const_cast<Loop *>(TheLoop));
649 bool InLoop = !ReductionOperations.empty();
650
651 if (InLoop)
652 InLoopReductions.insert(Phi);
653 LLVM_DEBUG(dbgs() << "LV: Using " << (InLoop ? "inloop" : "out of loop")
654 << " reduction for phi: " << *Phi << "\n");
655 }
656}
657
658bool LoopVectorizationPlanner::isMoreProfitable(const VectorizationFactor &A,
659 const VectorizationFactor &B,
660 const unsigned MaxTripCount,
661 bool HasTail,
662 bool IsEpilogue) const {
663 InstructionCost CostA = A.Cost;
664 InstructionCost CostB = B.Cost;
665
666 // When there is a hint to always prefer scalable vectors, honour that hint.
668 if (A.Width.isScalable() && CostA.isValid() && !B.Width.isScalable() &&
669 !B.Width.isScalar())
670 return true;
671
672 // Favor fixed VFs for epilogue loops by scaling the costs of scalable VFs
673 // 'ScalableEpilogueVFCostScaleFactor' (default 2.0). This is intended to
674 // model that fixed VFs are more likely to be fully unrolled (or optimized
675 // out) post vectorization. TODO: Reconsider this restriction for predicated
676 // epilogues (once supported).
677 if (IsEpilogue && A.Width.isScalable() != B.Width.isScalable() &&
678 A.Cost.isValid() && B.Cost.isValid()) {
679 auto [FixedCost, ScalableCost] = std::make_pair(CostA, CostB);
680 if (B.Width.isFixed())
681 std::swap(FixedCost, ScalableCost);
682
683 ScalableCost *= Opts.scalable_epilogue_vf_cost_scale_factor;
684
685 if (FixedCost <= ScalableCost)
686 return A.Width.isFixed();
687 }
688
689 // Improve estimate for the vector width if it is scalable.
690 unsigned EstimatedWidthA = A.Width.getKnownMinValue();
691 unsigned EstimatedWidthB = B.Width.getKnownMinValue();
692 if (std::optional<unsigned> VScale = Config.getVScaleForTuning()) {
693 if (A.Width.isScalable())
694 EstimatedWidthA *= *VScale;
695 if (B.Width.isScalable())
696 EstimatedWidthB *= *VScale;
697 }
698
699 // When optimizing for size choose whichever is smallest, which will be the
700 // one with the smallest cost for the whole loop. On a tie pick the larger
701 // vector width, on the assumption that throughput will be greater.
702 if (Config.CostKind == TTI::TCK_CodeSize)
703 return CostA < CostB ||
704 (CostA == CostB && EstimatedWidthA > EstimatedWidthB);
705
706 // Assume vscale may be larger than 1 (or the value being tuned for),
707 // so that scalable vectorization is slightly favorable over fixed-width
708 // vectorization.
709 bool PreferScalable = !TTI.preferFixedOverScalableIfEqualCost() &&
710 A.Width.isScalable() && !B.Width.isScalable();
711
712 auto CmpFn = [PreferScalable](const InstructionCost &LHS,
713 const InstructionCost &RHS) {
714 return PreferScalable ? LHS <= RHS : LHS < RHS;
715 };
716
717 // To avoid the need for FP division:
718 // (CostA / EstimatedWidthA) < (CostB / EstimatedWidthB)
719 // <=> (CostA * EstimatedWidthB) < (CostB * EstimatedWidthA)
720 bool LowerCostWithoutTC =
721 CmpFn(CostA * EstimatedWidthB, CostB * EstimatedWidthA);
722 if (!MaxTripCount)
723 return LowerCostWithoutTC;
724
725 auto GetCostForTC = [MaxTripCount, HasTail](unsigned VF,
726 InstructionCost VectorCost,
727 InstructionCost ScalarCost) {
728 // If the trip count is a known (possibly small) constant, the trip count
729 // will be rounded up to an integer number of iterations under
730 // FoldTailByMasking. The total cost in that case will be
731 // VecCost*ceil(TripCount/VF). When not folding the tail, the total
732 // cost will be VecCost*floor(TC/VF) + ScalarCost*(TC%VF). There will be
733 // some extra overheads, but for the purpose of comparing the costs of
734 // different VFs we can use this to compare the total loop-body cost
735 // expected after vectorization.
736 if (HasTail)
737 return VectorCost * (MaxTripCount / VF) +
738 ScalarCost * (MaxTripCount % VF);
739 return VectorCost * divideCeil(MaxTripCount, VF);
740 };
741
742 auto RTCostA = GetCostForTC(EstimatedWidthA, CostA, A.ScalarCost);
743 auto RTCostB = GetCostForTC(EstimatedWidthB, CostB, B.ScalarCost);
744 bool LowerCostWithTC = CmpFn(RTCostA, RTCostB);
745 LLVM_DEBUG(if (LowerCostWithTC != LowerCostWithoutTC) {
746 dbgs() << "LV: VF " << (LowerCostWithTC ? A.Width : B.Width)
747 << " has lower cost than VF "
748 << (LowerCostWithTC ? B.Width : A.Width)
749 << " when taking the cost of the remaining scalar loop iterations "
750 "into consideration for a maximum trip count of "
751 << MaxTripCount << ".\n";
752 });
753 return LowerCostWithTC;
754}
755
756bool LoopVectorizationPlanner::isMoreProfitable(const VectorizationFactor &A,
757 const VectorizationFactor &B,
758 bool HasTail,
759 bool IsEpilogue) const {
760 const unsigned MaxTripCount = PSE.getSmallConstantMaxTripCount();
761 return LoopVectorizationPlanner::isMoreProfitable(A, B, MaxTripCount, HasTail,
762 IsEpilogue);
763}
764
765// TODO: we could return a pair of values that specify the max VF and
766// min VF, to be used in `buildVPlans(MinVF, MaxVF)` instead of
767// `buildVPlans(VF, VF)`. We cannot do it because VPLAN at the moment
768// doesn't have a cost model that can choose which plan to execute if
769// more than one is generated.
772 if (UserVF.isScalable() && !supportsScalableVectors()) {
774 "Scalable vectorization requested but not supported by the target",
775 "the scalable user-specified vectorization width for outer-loop "
776 "vectorization cannot be used because the target does not support "
777 "scalable vectors.",
778 "ScalableVFUnfeasible", ORE, TheLoop);
780 }
781
782 ElementCount VF = UserVF;
783 if (VF.isZero()) {
784 auto [_, WidestType] = getSmallestAndWidestTypes();
785
786 auto RegKind = TTI.enableScalableVectorization()
789
790 TypeSize RegSize = TTI.getRegisterBitWidth(RegKind);
791 // The widest type may be wider than the register width and WidestType may
792 // not be a power of two; round the element count down to a power of two.
793 unsigned N = std::max<uint64_t>(
794 1, llvm::bit_floor(RegSize.getKnownMinValue() / WidestType));
795 VF = ElementCount::get(N, RegSize.isScalable());
796 LLVM_DEBUG(dbgs() << "LV: VPlan computed VF " << VF << ".\n");
797
798 // Make sure we have a VF > 1 for stress testing.
799 if (Opts.vplan_build_outerloop_stress_test && VF.isScalar()) {
800 LLVM_DEBUG(dbgs() << "LV: VPlan stress testing: "
801 << "overriding computed VF.\n");
803 }
804 }
806 "VF needs to be a power of two");
807 if (VF.isScalar())
809 LLVM_DEBUG(dbgs() << "LV: Using " << (!UserVF.isZero() ? "user " : "")
810 << "VF " << VF << " to build VPlans.\n");
811 return FixedScalableVFPair(VF);
812}
813
814/// \returns true if the VPlan contains header phi recipes that are not
815/// currently supported for epilogue vectorization.
817 return any_of(
819 [](VPRecipeBase &R) {
820 switch (R.getVPRecipeID()) {
821 case VPRecipeBase::VPFirstOrderRecurrencePHISC:
822 // TODO: Add support for fixed-order recurrences.
823 return true;
824 case VPRecipeBase::VPWidenIntOrFpInductionSC:
825 return !cast<VPWidenIntOrFpInductionRecipe>(&R)->getPHINode();
826 case VPRecipeBase::VPReductionPHISC: {
827 auto *RedPhi = cast<VPReductionPHIRecipe>(&R);
828 // TODO: Support FMinNum/FMaxNum, FindLast reductions, and reductions
829 // without underlying values.
830 RecurKind Kind = RedPhi->getRecurrenceKind();
831 if (RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind(Kind) ||
832 RecurrenceDescriptor::isFindLastRecurrenceKind(Kind) ||
833 !RedPhi->getUnderlyingValue())
834 return true;
835 // TODO: Add support for FindIV reductions with sunk expressions: the
836 // resume value from the main loop is in expression domain (e.g.,
837 // mul(ReducedIV, 3)), but the epilogue tracks raw IV values. A sunk
838 // expression is identified by a non-VPInstruction user of
839 // ComputeReductionResult.
840 if (RecurrenceDescriptor::isFindIVRecurrenceKind(Kind))
841 return RedPhi->isExpressionSunk();
842 return false;
843 }
844 default:
845 return false;
846 };
847 });
848}
849
850bool LoopVectorizationPlanner::isCandidateForEpilogueVectorization(
851 VPlan &MainPlan) const {
852 // Bail out if the plan contains header phi recipes not yet supported
853 // for epilogue vectorization.
854 if (hasUnsupportedHeaderPhiRecipe(MainPlan))
855 return false;
856
857 // Epilogue vectorization code has not been auditted to ensure it handles
858 // non-latch exits properly. It may be fine, but it needs auditted and
859 // tested.
860 // TODO: Add support for loops with an early exit.
861 if (OrigLoop->getExitingBlock() != OrigLoop->getLoopLatch() ||
862 Legal->hasUncountableEarlyExit())
863 return false;
864
865 return true;
866}
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
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 bool hasUnsupportedHeaderPhiRecipe(VPlan &Plan)
static void debugVectorizationMessage(const StringRef Prefix, const StringRef DebugMsg, Instruction *I)
Write a DebugMsg about vectorization to the debug output stream.
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...
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
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition TypeSize.h:308
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:305
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
Definition TypeSize.h:311
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:316
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
@ 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(bool IsLoad, Type *ScalarTy, Align Alignment, ElementCount VF) const
Returns true if the target machine supports a gather (if IsLoad) or scatter of scalar type ScalarTy w...
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.
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4517
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:183
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:403
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4841
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1030
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.
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:1755
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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:1762
std::optional< uint64_t > getMaxRuntimeElementCount(ElementCount EC, const Function &F)
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
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:389
TargetTransformInfo TTI
RecurKind
These are the kinds of recurrences that we support.
std::optional< unsigned > getMaxVScale(const Function &F)
constexpr bool valueOr(BoolOrDefault X, bool Default)
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
Type * toVectorTy(Type *Scalar, ElementCount EC)
A helper function for converting Scalar types to vector types.
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.
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.