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