LLVM 24.0.0git
SLPCostAnalysis.cpp
Go to the documentation of this file.
1//===- SLPCostAnalysis.cpp - SLP Vectorizer free cost helpers -------------===//
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#include "SLPCostAnalysis.h"
10#include "SLPTypeUtils.h"
11#include "SLPUtils.h"
12
13#include "llvm/ADT/APInt.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/Sequence.h"
20#include "llvm/IR/BasicBlock.h"
21#include "llvm/IR/DataLayout.h"
24#include "llvm/IR/Intrinsics.h"
25#include "llvm/IR/Operator.h"
27#include "llvm/IR/Type.h"
28#include "llvm/IR/Value.h"
32
33#include <cassert>
34#include <utility>
35
36using namespace llvm;
37using namespace llvm::PatternMatch;
38
39namespace llvm::slpvectorizer {
40
43 const TTI::TargetCostKind CostKind,
44 ArrayRef<int> Mask, int Index, VectorType *SubTp,
47 VectorType *DstTy = Tp;
48 if (!Mask.empty())
49 DstTy = FixedVectorType::get(Tp->getScalarType(), Mask.size());
50
51 if (Kind != TTI::SK_PermuteTwoSrc)
52 return TTI.getShuffleCost(Kind, DstTy, Tp, CostKind, Mask, Index, SubTp,
53 Args, /*CtxI=*/nullptr, VIC);
54 int NumSrcElts = Tp->getElementCount().getKnownMinValue();
55 int NumSubElts;
56 if (Mask.size() > 2 && ShuffleVectorInst::isInsertSubvectorMask(
57 Mask, NumSrcElts, NumSubElts, Index)) {
58 if (Index + NumSubElts > NumSrcElts &&
59 Index + NumSrcElts <= static_cast<int>(Mask.size()))
60 return TTI.getShuffleCost(TTI::SK_InsertSubvector, DstTy, Tp, CostKind,
61 Mask, Index, Tp);
62 }
63 return TTI.getShuffleCost(Kind, DstTy, Tp, CostKind, Mask, Index, SubTp, Args,
64 /*CtxI=*/nullptr, VIC);
65}
66
67std::pair<InstructionCost, InstructionCost>
69 Value *BasePtr, unsigned Opcode, const TTI::TargetCostKind CostKind,
70 Type *ScalarTy, VectorType *VecTy) {
71 InstructionCost ScalarCost = 0;
72 InstructionCost VecCost = 0;
73 // Here we differentiate two cases: (1) when Ptrs represent a regular
74 // vectorization tree node (as they are pointer arguments of scattered
75 // loads) or (2) when Ptrs are the arguments of loads or stores being
76 // vectorized as plane wide unit-stride load/store since all the
77 // loads/stores are known to be from/to adjacent locations.
78 if (Opcode == Instruction::Load || Opcode == Instruction::Store) {
79 // Case 2: estimate costs for pointer related costs when vectorizing to
80 // a wide load/store.
81 // Scalar cost is estimated as a set of pointers with known relationship
82 // between them.
83 // For vector code we will use BasePtr as argument for the wide load/store
84 // but we also need to account all the instructions which are going to
85 // stay in vectorized code due to uses outside of these scalar
86 // loads/stores.
87 ScalarCost = TTI.getPointersChainCost(
88 Ptrs, BasePtr, TTI::PointersChainInfo::getUnitStride(), ScalarTy,
89 CostKind);
90
91 SmallVector<const Value *> PtrsRetainedInVecCode;
92 for (Value *V : Ptrs) {
93 if (V == BasePtr) {
94 PtrsRetainedInVecCode.push_back(V);
95 continue;
96 }
97 auto *Ptr = dyn_cast<GetElementPtrInst>(V);
98 // For simplicity assume Ptr to stay in vectorized code if it's not a
99 // GEP instruction. We don't care since it's cost considered free.
100 // TODO: We should check for any uses outside of vectorizable tree
101 // rather than just single use.
102 if (!Ptr || !Ptr->hasOneUse())
103 PtrsRetainedInVecCode.push_back(V);
104 }
105
106 if (PtrsRetainedInVecCode.size() == Ptrs.size()) {
107 // If all pointers stay in vectorized code then we don't have
108 // any savings on that.
109 return std::make_pair(TTI::TCC_Free, TTI::TCC_Free);
110 }
111 VecCost = TTI.getPointersChainCost(PtrsRetainedInVecCode, BasePtr,
112 TTI::PointersChainInfo::getKnownStride(),
113 VecTy, CostKind);
114 } else {
115 // Case 1: Ptrs are the arguments of loads that we are going to transform
116 // into masked gather load intrinsic.
117 // All the scalar GEPs will be removed as a result of vectorization.
118 // For any external uses of some lanes extract element instructions will
119 // be generated (which cost is estimated separately).
120 TTI::PointersChainInfo PtrsInfo =
121 all_of(Ptrs,
122 [](const Value *V) {
123 auto *Ptr = dyn_cast<GetElementPtrInst>(V);
124 return Ptr && !Ptr->hasAllConstantIndices();
125 })
126 ? TTI::PointersChainInfo::getUnknownStride()
127 : TTI::PointersChainInfo::getKnownStride();
128
129 const bool IsSameBase =
131 all_equal(map_range(Ptrs, [](Value *V) {
132 return cast<GetElementPtrInst>(V)->getPointerOperand();
133 }));
134 // The GEPs of the masked gather loads are accessed with the loaded type
135 // and form a chain only if the lanes share the base.
136 Type *AccessTy = ScalarTy;
137 if (all_of(Ptrs, [](const Value *V) {
138 auto *Ptr = dyn_cast<GetElementPtrInst>(V);
139 return Ptr && Ptr->hasOneUse() && isa<LoadInst>(Ptr->user_back());
140 })) {
141 PtrsInfo.IsSameBaseAddress = IsSameBase;
142 AccessTy = Ptrs.front()->user_back()->getType();
143 }
144 ScalarCost =
145 TTI.getPointersChainCost(Ptrs, BasePtr, PtrsInfo, AccessTy, CostKind);
146 auto *BaseGEP = dyn_cast<GEPOperator>(BasePtr);
147 if (!BaseGEP) {
148 auto *It = find_if(Ptrs, IsaPred<GEPOperator>);
149 if (It != Ptrs.end())
150 BaseGEP = cast<GEPOperator>(*It);
151 }
152 if (!IsSameBase) {
153 // The different bases are not folded into the addressing of the vector
154 // access, the scaled indices are added to them.
155 const DataLayout &DL = cast<Instruction>(Ptrs.front())->getDataLayout();
156 Type *IdxTy = DL.getIndexType(VecTy);
157 VecCost = TTI.getArithmeticInstrCost(Instruction::Add, IdxTy, CostKind);
158 uint64_t Stride = DL.getTypeAllocSize(BaseGEP->getSourceElementType())
159 .getKnownMinValue();
160 if (Stride != 1 && !all_of(Ptrs, [](Value *V) {
161 return isa<Constant>(cast<GetElementPtrInst>(V)->getOperand(1));
162 }))
163 VecCost += TTI.getArithmeticInstrCost(
164 isPowerOf2_64(Stride) ? Instruction::Shl : Instruction::Mul, IdxTy,
166 } else if (BaseGEP) {
167 SmallVector<const Value *> Indices(BaseGEP->indices());
168 VecCost = TTI.getGEPCost(BaseGEP->getSourceElementType(),
169 BaseGEP->getPointerOperand(), Indices, CostKind,
170 VecTy);
171 }
172 }
173
174 return std::make_pair(ScalarCost, VecCost);
175}
176
178 Align Alignment, unsigned AddressSpace,
179 const TTI::TargetCostKind CostKind) {
180 Type *CmpTy = CmpInst::makeCmpResultType(VecTy);
181 return 2 * TTI.getMemIntrinsicInstrCost(
182 MemIntrinsicCostAttributes(Intrinsic::masked_load, VecTy,
183 Alignment, AddressSpace),
184 CostKind) +
185 TTI.getArithmeticInstrCost(Instruction::Xor, CmpTy, CostKind) +
186 TTI.getCmpSelInstrCost(Instruction::Select, VecTy, CmpTy,
188}
189
191 Type *SrcTy, Type *DstTy,
192 const DataLayout &DL,
194 TTI::TargetCostKind CostKind) {
195 bool ToPtr = cast<VectorType>(DstTy)->getElementType()->isPointerTy();
196 if (ToPtr == cast<VectorType>(SrcTy)->getElementType()->isPointerTy())
197 return TTI.getCastInstrCost(Instruction::BitCast, DstTy, SrcTy, CCH,
198 CostKind);
199 // The ptr/int conversion keeps the vector shape, the bitcast transforms the
200 // resulting integer vector.
201 if (ToPtr) {
202 Type *IntVecTy = DL.getIntPtrType(DstTy);
203 return TTI.getCastInstrCost(Instruction::IntToPtr, DstTy, IntVecTy, CCH,
204 CostKind) +
205 TTI.getCastInstrCost(Instruction::BitCast, IntVecTy, SrcTy, CCH,
206 CostKind);
207 }
208 Type *IntVecTy = DL.getIntPtrType(SrcTy);
209 return TTI.getCastInstrCost(Instruction::PtrToInt, IntVecTy, SrcTy, CCH,
210 CostKind) +
211 TTI.getCastInstrCost(Instruction::BitCast, DstTy, IntVecTy, CCH,
212 CostKind);
213}
214
216 unsigned Opcode, Type *ScalarTy,
217 unsigned NumElts,
218 const TTI::TargetCostKind CostKind,
219 FixedVectorType **PaddedTy) {
220 FixedVectorType *PaddedVecTy =
221 getMaskedDivRemType(TTI, Opcode, ScalarTy, NumElts, ReVec);
222 if (!PaddedVecTy)
224 // One mask bit per element of the padded vector, not per padded lane.
225 auto *MaskTy =
227 PaddedVecTy->getNumElements());
228 InstructionCost DirectCost = TTI.getArithmeticInstrCost(
229 Opcode, getWidenedType(ScalarTy, NumElts), CostKind);
230 IntrinsicCostAttributes ICA(getMaskedDivRemIntrinsic(Opcode), PaddedVecTy,
231 {PaddedVecTy, PaddedVecTy, MaskTy});
232 InstructionCost MaskedCost = TTI.getIntrinsicInstrCost(ICA, CostKind);
233 if (!MaskedCost.isValid() || MaskedCost >= DirectCost)
235 if (PaddedTy)
236 *PaddedTy = PaddedVecTy;
237 return MaskedCost;
238}
239
242 Type *ScalarTy, VectorType *Ty,
243 const APInt &DemandedElts, bool Insert, bool Extract,
244 const TTI::TargetCostKind CostKind, bool ForPoisonSrc,
247 "ScalableVectorType is not supported.");
248 assert(getNumElements(ScalarTy) * DemandedElts.getBitWidth() ==
249 getNumElements(Ty) &&
250 "Incorrect usage.");
251 if (auto *VecTy = dyn_cast<FixedVectorType>(ScalarTy)) {
252 assert(ReVec && "Only supported by REVEC.");
253 // If ScalarTy is FixedVectorType, we should use CreateInsertVector instead
254 // of CreateInsertElement.
255 unsigned ScalarTyNumElements = VecTy->getNumElements();
257 for (unsigned I : seq(DemandedElts.getBitWidth())) {
258 if (!DemandedElts[I])
259 continue;
260 if (Insert)
261 Cost += getShuffleCost(TTI, TTI::SK_InsertSubvector, Ty, CostKind, {},
262 I * ScalarTyNumElements, VecTy);
263 if (Extract)
264 Cost += getShuffleCost(TTI, TTI::SK_ExtractSubvector, Ty, CostKind, {},
265 I * ScalarTyNumElements, VecTy);
266 }
267 return Cost;
268 }
269 return TTI.getScalarizationOverhead(Ty, DemandedElts, Insert, Extract,
270 CostKind, ForPoisonSrc, VL, VIC);
271}
272
274 const TargetTransformInfo &TTI, bool ReVec, Type *ScalarTy, unsigned Opcode,
275 Type *Val, const TTI::TargetCostKind CostKind, unsigned Index,
276 Value *Scalar, ArrayRef<std::tuple<Value *, User *, int>> ScalarUserAndIdx,
278 if (Opcode == Instruction::ExtractElement) {
279 if (auto *VecTy = dyn_cast<FixedVectorType>(ScalarTy)) {
280 assert(ReVec && "Only supported by REVEC.");
281 assert(isa<VectorType>(Val) && "Val must be a vector type.");
283 cast<VectorType>(Val), CostKind, {},
284 Index * VecTy->getNumElements(), VecTy);
285 }
286 }
287 return TTI.getVectorInstrCost(Opcode, Val, CostKind, Index, Scalar,
288 ScalarUserAndIdx, VIC);
289}
290
292 bool ReVec, unsigned Opcode, Type *Dst,
293 VectorType *VecTy, unsigned Index,
294 const TTI::TargetCostKind CostKind) {
295 if (isVectorizedTy(Dst)) {
296 assert(ReVec && "Only supported by REVEC.");
297 auto *SubTp = cast<FixedVectorType>(
299 return getShuffleCost(TTI, TTI::SK_ExtractSubvector, VecTy, CostKind, {},
300 Index * getNumElements(Dst), SubTp) +
301 TTI.getCastInstrCost(Opcode, Dst, SubTp, TTI::CastContextHint::None,
302 CostKind);
303 }
304 return TTI.getExtractWithExtendCost(Opcode, Dst, VecTy, Index, CostKind);
305}
306
307/// Returns the cast context hint for the trunc of the booleanized reduction
308/// result, which inherits the uses of the reduction root \p Root.
321
323 RecurKind RdxKind,
324 FixedVectorType *VecTy,
325 const Value *Root, FastMathFlags FMF,
326 const TTI::TargetCostKind CostKind) {
327 Type *I1Ty = Type::getInt1Ty(VecTy->getContext());
328 return TTI.getArithmeticReductionCost(
329 RecurrenceDescriptor::getOpcode(RdxKind), VecTy, FMF, CostKind) +
330 TTI.getCastInstrCost(Instruction::Trunc, I1Ty, VecTy->getScalarType(),
331 getBoolReduxResultCCH(Root), CostKind);
332}
333
335 RecurKind RdxKind,
336 FixedVectorType *VecTy,
337 const Value *Root,
338 ArrayRef<Instruction *> ChainInsts,
339 const TTI::TargetCostKind CostKind) {
340 // The new instructions are costed in the context of the replaced cast chain
341 // instructions.
342 auto TruncIt =
343 find_if(ChainInsts, [](Instruction *I) { return isa<TruncInst>(I); });
344 const Instruction *TruncI = TruncIt == ChainInsts.end() ? nullptr : *TruncIt;
345 auto CmpIt =
346 find_if(ChainInsts, [](Instruction *I) { return isa<ICmpInst>(I); });
347 const Instruction *CmpI = CmpIt == ChainInsts.end() ? nullptr : *CmpIt;
348 unsigned VF = VecTy->getNumElements();
349 auto *I1VecTy =
351 Type *IntTy = IntegerType::get(VecTy->getContext(), VF);
352 Constant *CmpRHS = RdxKind == RecurKind::And
354 : Constant::getNullValue(IntTy);
355 return TTI.getCastInstrCost(Instruction::Trunc, I1VecTy, VecTy,
356 TTI.getCastContextHint(TruncI), CostKind,
357 TruncI) +
358 TTI.getCastInstrCost(Instruction::BitCast, IntTy, I1VecTy,
359 TTI.getCastContextHint(TruncI), CostKind) +
360 TTI.getCmpSelInstrCost(
361 Instruction::ICmp, IntTy, CmpInst::makeCmpResultType(IntTy),
363 CostKind, TTI.getOperandInfo(Root), TTI.getOperandInfo(CmpRHS),
364 CmpI);
365}
366
367static InstructionCost
370 TTI::TargetCostKind CostKind) {
371 assert((Kind == RecurKind::And || Kind == RecurKind::Or) &&
372 VectorTy->getElementType()->isIntegerTy(1) &&
373 "Expected and/or reduction of i1");
374 auto *IntTy =
375 IntegerType::get(VectorTy->getContext(), getNumElements(VectorTy));
376 CmpInst::Predicate Pred =
378 // The compare is against the all-ones (and) or zero (or) constant.
379 return TTI.getCastInstrCost(Instruction::BitCast, IntTy, VectorTy, Ctx,
380 CostKind) +
381 TTI.getCmpSelInstrCost(Instruction::ICmp, IntTy,
382 CmpInst::makeCmpResultType(IntTy), Pred,
383 CostKind, /*Op1Info=*/{},
385}
386
387std::pair<InstructionCost, bool>
389 FixedVectorType *VectorTy, Type *ScalarTy,
391 unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(Kind);
392 if (Kind == RecurKind::And || Kind == RecurKind::Or) {
393 InstructionCost RdxCost = TTI.getArithmeticReductionCost(
394 RdxOpcode, VectorTy, std::nullopt, CostKind);
395 InstructionCost BitcastCost =
396 getBoolLogicRdxBitcastCost(Kind, TTI, VectorTy, Ctx, CostKind);
397 return {std::min(RdxCost, BitcastCost), BitcastCost < RdxCost};
398 }
399 assert(Kind == RecurKind::Add && !ScalarTy->isIntegerTy(1) &&
400 "Expected add reduction of zexted i1 values");
401 // The bitcast+ctpop form is estimated as the cheaper of the extended
402 // reduction cost, which models it for the zexted i1 add reduction, and the
403 // explicitly priced components, including the cast of the ctpop result to
404 // the destination type.
405 auto *IntTy =
406 IntegerType::get(VectorTy->getContext(), getNumElements(VectorTy));
407 InstructionCost ExplicitCost =
408 TTI.getCastInstrCost(Instruction::BitCast, IntTy, VectorTy, Ctx,
409 CostKind) +
410 TTI.getIntrinsicInstrCost(
411 IntrinsicCostAttributes(Intrinsic::ctpop, IntTy, {IntTy}), CostKind);
412 if (IntTy != ScalarTy)
413 ExplicitCost += TTI.getCastInstrCost(IntTy->getBitWidth() <
414 ScalarTy->getIntegerBitWidth()
415 ? Instruction::ZExt
416 : Instruction::Trunc,
417 ScalarTy, IntTy, Ctx, CostKind);
418 InstructionCost CtpopCost = std::min(
419 TTI.getExtendedReductionCost(RdxOpcode, /*IsUnsigned=*/true, ScalarTy,
420 VectorTy, std::nullopt, CostKind),
421 ExplicitCost);
422 // The plain form is the zext to the wide vector type plus the reduction.
423 auto *ExtTy = VectorType::get(ScalarTy, VectorTy);
424 InstructionCost ExtRdxCost =
425 TTI.getCastInstrCost(Instruction::ZExt, ExtTy, VectorTy, Ctx, CostKind) +
426 TTI.getArithmeticReductionCost(RdxOpcode, ExtTy, std::nullopt, CostKind);
427 return {std::min(ExtRdxCost, CtpopCost), CtpopCost <= ExtRdxCost};
428}
429
431 FixedVectorType *SrcTy, Type *ResultTy,
432 const BitPackInfo &Info, unsigned ZExtSrcWidth,
434 TTI::TargetCostKind CostKind,
435 const TargetLibraryInfo *TLI,
436 const Instruction *CtxI, unsigned &ShiftWidth) {
437 unsigned BitWidth = SrcTy->getScalarSizeInBits();
438 unsigned NumElts = SrcTy->getNumElements();
439 uint64_t MaxAmt = *max_element(Info.LShrAmts);
440 // The shift amounts form a constant vector.
441 TTI::OperandValueInfo ShiftAmtInfo = {
444 all_of(Info.LShrAmts,
445 [](uint64_t A) { return A == 0 || isPowerOf2_64(A); })
447 : TTI::OP_None};
448 // After the shift the field content of each lane sits in the low bits of
449 // the lane, so the packing is a single byte shuffle of the shifted lanes.
450 // Pick the cheapest shift width: the narrowest type still holding the field
451 // content is not always the cheapest (e.g. missing narrow variable shifts).
452 Type *Int8Ty = Type::getInt8Ty(SrcTy->getContext());
453 assert(BitWidth % 8 == 0 &&
454 "The byte-multiple field width divides the result bit width.");
455 unsigned OutBytes = ResultTy->getScalarSizeInBits() / 8;
456 auto *PackTy = FixedVectorType::get(Int8Ty, OutBytes);
457 unsigned MinShiftWidth = 8;
458 while (MinShiftWidth < MaxAmt + Info.FieldWidth)
459 MinShiftWidth *= 2;
460 bool IsReversed = equal(Info.LaneOfField, reverse(seq<unsigned>(NumElts)));
461 bool IsTrunc = IsReversed || equal(Info.LaneOfField, seq<unsigned>(NumElts));
462 auto *FieldTy = FixedVectorType::get(
463 IntegerType::get(SrcTy->getContext(), Info.FieldWidth), NumElts);
465 ShiftWidth = 0;
466 for (unsigned W2 = MinShiftWidth; W2 <= BitWidth; W2 *= 2) {
467 auto *ShiftTy = FixedVectorType::get(
468 IntegerType::get(SrcTy->getContext(), W2), NumElts);
469 unsigned BytesPerLane = W2 / 8;
470 unsigned InBytes = NumElts * BytesPerLane;
471 SmallVector<int> Mask =
472 getBitPackMask(Info, OutBytes, NumElts, BytesPerLane);
473 InstructionCost C = TTI.getCastInstrCost(Instruction::BitCast, ResultTy,
474 PackTy, CCH, CostKind);
475 if (IsTrunc) {
476 // Fields in lane order, possibly reversed, are a truncation of the
477 // shifted lanes. A reversal of byte fields is a bswap.
478 if (Info.FieldWidth < W2)
479 C += TTI.getCastInstrCost(Instruction::Trunc, FieldTy, ShiftTy,
481 if (IsReversed && Info.FieldWidth == 8) {
482 IntrinsicCostAttributes CostAttrs(Intrinsic::bswap, ResultTy,
483 {ResultTy});
484 C += TTI.getIntrinsicInstrCost(CostAttrs, CostKind);
485 } else if (IsReversed) {
486 C += TTI.getShuffleCost(TargetTransformInfo::SK_Reverse, FieldTy,
487 FieldTy, CostKind);
488 }
489 } else {
490 // A narrowing shuffle is a shuffle at the source width followed by an
491 // extract of the low elements.
492 auto *SrcByteTy = FixedVectorType::get(Int8Ty, InBytes);
493 SmallVector<int> WideMask(Mask);
494 WideMask.resize(std::max(InBytes, OutBytes), PoisonMaskElem);
495 C += TTI.getShuffleCost(
496 is_contained(Info.LaneOfField, BitPackInfo::NoLane)
499 FixedVectorType::get(Int8Ty, WideMask.size()), SrcByteTy, CostKind,
500 WideMask, /*Index=*/0, /*SubTp=*/nullptr, /*Args=*/{}, CtxI);
501 if (InBytes > OutBytes)
503 PackTy, SrcByteTy, CostKind, /*Mask=*/{},
504 /*Index=*/0, PackTy, /*Args=*/{}, CtxI);
505 }
506 if (W2 != BitWidth && W2 != ZExtSrcWidth)
507 C += TTI.getCastInstrCost(Instruction::Trunc, ShiftTy, SrcTy, CCH,
508 CostKind);
509 if (Info.needsShift())
510 C += TTI.getArithmeticInstrCost(Instruction::LShr, ShiftTy, CostKind,
511 /*Opd1Info=*/{}, ShiftAmtInfo,
512 /*Args=*/{}, CtxI, TLI);
513 if (C.isValid() && (!NewCost.isValid() || C < NewCost)) {
514 NewCost = C;
515 ShiftWidth = W2;
516 }
517 }
518 return NewCost;
519}
520
522 bool NeedMask, Type *NarrowScalarTy,
523 Type *WideTy, unsigned VF,
524 ArrayRef<int> PermMask, const Value *Root,
525 const TTI::TargetCostKind CostKind) {
526 auto *NarrowVecTy = cast<VectorType>(getWidenedType(NarrowScalarTy, VF));
527 Type *CmpTy = CmpInst::makeCmpResultType(NarrowVecTy);
528 auto *MaskTy = IntegerType::get(WideTy->getContext(), VF);
529 // The result cast inherits the uses of the reduction root.
531 const auto *CtxI = cast<Instruction>(Root);
533 if (NeedMask)
534 Cost += TTI.getArithmeticInstrCost(
535 Instruction::And, NarrowVecTy, CostKind,
538 if (!ShuffleVectorInst::isIdentityMask(PermMask, VF))
539 Cost += getShuffleCost(TTI, TTI::SK_PermuteSingleSrc, NarrowVecTy, CostKind,
540 PermMask);
541 if (!NarrowScalarTy->isIntegerTy(1))
542 Cost += TTI.getCmpSelInstrCost(
543 Instruction::ICmp, NarrowVecTy, CmpTy, CmpInst::ICMP_NE, CostKind,
546 // Only the final cast inherits the uses of the reduction root.
547 Cost += TTI.getCastInstrCost(
548 Instruction::BitCast, MaskTy, CmpTy,
549 MaskTy == WideTy ? CCH : TTI::CastContextHint::None, CostKind);
550 if (MaskTy != WideTy)
551 Cost +=
552 TTI.getCastInstrCost(Instruction::ZExt, WideTy, MaskTy, CCH, CostKind);
553 return Cost;
554}
555
558 const SmallDenseMap<Value *, NarrowedLeafInfo> &NarrowedLeafShifts,
559 VectorType *NarrowVecTy, VectorType *WideVecTy, const Instruction *CtxI,
560 const TTI::TargetCostKind CostKind) {
562 if (any_of(NarrowedLeafShifts,
563 [](const auto &P) { return P.second.Shift != 0; }))
564 Cost += TTI.getArithmeticInstrCost(
565 Instruction::Shl, WideVecTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
566 {TTI::OK_NonUniformConstantValue, TTI::OP_None}, {}, CtxI);
567 if (any_of(NarrowedLeafShifts,
568 [](const auto &P) { return !P.second.Mask.isAllOnes(); }))
569 Cost += TTI.getArithmeticInstrCost(
570 Instruction::And, NarrowVecTy, CostKind,
571 {TTI::OK_AnyValue, TTI::OP_None},
572 {TTI::OK_NonUniformConstantValue, TTI::OP_None}, {}, CtxI);
573 return Cost;
574}
575
577 const Intrinsic::ID ID,
578 const unsigned VF, unsigned MinBW,
579 const TargetTransformInfo &TTI) {
580 SmallVector<Type *> ArgTys;
581 for (auto [Idx, Arg] : enumerate(CI->args())) {
582 if (ID != Intrinsic::not_intrinsic) {
584 ArgTys.push_back(Arg->getType());
585 continue;
586 }
587 if (MinBW > 0) {
588 ArgTys.push_back(
589 getWidenedType(IntegerType::get(CI->getContext(), MinBW), VF));
590 continue;
591 }
592 }
593 ArgTys.push_back(getWidenedType(Arg->getType(), VF));
594 }
595 return ArgTys;
596}
597
598std::pair<InstructionCost, InstructionCost>
601 const TTI::TargetCostKind CostKind) {
602 auto Shape = VFShape::get(CI->getFunctionType(),
604 false /*HasGlobalPred*/);
605 Function *VecFunc = VFDatabase(*CI).getVectorizedFunction(Shape);
606 auto LibCost = InstructionCost::getInvalid();
607 if (!CI->isNoBuiltin() && VecFunc) {
608 // Calculate the cost of the vector library call.
609 // If the corresponding vector call is cheaper, return its cost.
610 LibCost = TTI.getCallInstrCost(nullptr, VecTy, ArgTys, CostKind);
611 }
613
614 // Calculate the cost of the vector intrinsic call.
615 FastMathFlags FMF;
616 if (auto *FPCI = dyn_cast<FPMathOperator>(CI))
617 FMF = FPCI->getFastMathFlags();
618 const InstructionCost ScalarLimit = 10000;
619 IntrinsicCostAttributes CostAttrs(ID, VecTy, ArgTys, FMF,
621 LibCost.isValid() ? LibCost : ScalarLimit);
622 auto IntrinsicCost = TTI.getIntrinsicInstrCost(CostAttrs, CostKind);
623 if (LibCost.isValid()) {
624 if (IntrinsicCost > LibCost)
626 } else if (IntrinsicCost > ScalarLimit) {
627 // A type-based query always scalarizes struct-returning intrinsics (e.g.
628 // llvm.sincos), which do not have a VFDatabase name mapping. Retry with an
629 // argument-aware query (as the loop vectorizer does) so such lowerings are
630 // taken into account.
632 IntrinsicCostAttributes ArgAwareAttrs(
633 ID, VecTy, Args, ArgTys, FMF, dyn_cast<IntrinsicInst>(CI), ScalarLimit);
634 IntrinsicCost = TTI.getIntrinsicInstrCost(ArgAwareAttrs, CostKind);
635 if (IntrinsicCost > ScalarLimit)
637 }
638
639 return {IntrinsicCost, LibCost};
640}
641
642/// \returns the reciprocal-throughput cost of \p I widened to \p VF lanes (an
643/// arithmetic op or a vectorizable call).
646 const TargetLibraryInfo &TLI,
647 const TTI::TargetCostKind CostKind) {
649 "getVectorOpCost expects an arithmetic op or a vectorizable call.");
650 Type *VecTy = getWidenedType(I->getType(), VF);
651 if (auto *CI = dyn_cast<CallInst>(I)) {
653 SmallVector<Type *> ArgTys = buildIntrinsicArgTypes(CI, ID, VF, 0, TTI);
654 auto [IntrCost, LibCost] =
655 getVectorCallCosts(CI, VecTy, TTI, TLI, ArgTys, CostKind);
656 return std::min(IntrCost, LibCost);
657 }
658 SmallVector<const Value *, 2> Args{I->getOperand(0), I->getOperand(1)};
659 return TTI.getArithmeticInstrCost(
660 I->getOpcode(), VecTy, CostKind, TTI::getOperandInfo(I->getOperand(0)),
661 TTI::getOperandInfo(I->getOperand(1)), Args, I);
662}
663
664/// Packs a type's kind and scalar width into one key, so an opcode/intrinsic
665/// id reused across scalar widths (e.g. fdiv float vs. fdiv double) is cached
666/// per width instead of sharing one verdict.
667static unsigned getPoorThroughputTypeKey(Type *Ty) {
668 return (static_cast<unsigned>(Ty->getTypeID()) << 16) |
669 Ty->getScalarSizeInBits();
670}
671
674 const TargetLibraryInfo &TLI,
676 const TTI::TargetCostKind CostKind,
677 unsigned MaxVecRegSize) {
679 return false;
680 Type *Ty = I->getType();
681 if ((Ty->isVectorTy() && !ReVec) || Ty->isAggregateType() ||
682 !isValidElementType(Ty, ReVec))
683 return false;
684 auto Analyze = [&]() {
685 InstructionCost ScalarCost = TTI.getInstructionCost(I, CostKind);
686 if (ScalarCost < TTI::TCC_Expensive)
687 return false;
688 constexpr unsigned MinVF = 2;
689 if (getVectorOpCost(I, MinVF, TTI, TLI, CostKind) < ScalarCost * MinVF)
690 return true;
691 // Some ops (e.g. div by constant) scalarize at VF=2 but have a cheap
692 // vector form at the full register width.
693 unsigned TyBits = Ty->getPrimitiveSizeInBits().getFixedValue();
694 unsigned MaxVF = TyBits ? llvm::bit_floor(MaxVecRegSize / TyBits) : 0;
695 return MaxVF > MinVF &&
696 getVectorOpCost(I, MaxVF, TTI, TLI, CostKind) < ScalarCost * MaxVF;
697 };
698 auto CheckCached = [&](bool IsCheap, llvm::function_ref<void()> MarkCheap) {
699 if (IsCheap)
700 return false;
701 if (Analyze())
702 return true;
703 MarkCheap();
704 return false;
705 };
706 if (auto *CI = dyn_cast<CallInst>(I)) {
707 if (any_of(CI->args(), [&](const Value *Arg) {
708 return !isValidElementType(Arg->getType(), ReVec);
709 }))
710 return false;
711 // A call, used only as a select operand, may get the values rejected by the
712 // select condition, which the vector library call handles on its slow path.
713 if (!CI->use_empty() && !CI->hasNUsesOrMore(UsesLimit) &&
714 all_of(CI->users(), [&](User *U) {
715 return match(
716 U, m_Select(m_Unless(m_Specific(CI)), m_Value(), m_Value()));
717 }))
718 return false;
720 auto Key = std::make_pair(ID, getPoorThroughputTypeKey(Ty));
721 return CheckCached(Cache.CheapIntrinsics.contains(Key),
722 [&] { Cache.CheapIntrinsics.insert(Key); });
723 }
724 // A call without the vector variants is never vectorized.
725 if (VFDatabase::getMappings(*CI).empty())
726 return false;
727 const Function *Callee = CI->getCalledFunction();
728 if (!Callee)
729 return Analyze();
730 return CheckCached(Cache.CheapCallees.contains(Callee),
731 [&] { Cache.CheapCallees.insert(Callee); });
732 }
733 auto Key = std::make_pair(I->getOpcode(), getPoorThroughputTypeKey(Ty));
734 return CheckCached(Cache.CheapOpcodes.contains(Key),
735 [&] { Cache.CheapOpcodes.insert(Key); });
736}
737
739 const TargetTransformInfo &TTI) {
742 m_FMul(m_Value(), m_Value()))))))
743 return false;
744 if (FMul->getParent() == I->getParent())
745 return true;
746 SmallVector<Use *> OpsToSink;
747 return TTI.isProfitableToSinkOperands(I, OpsToSink) &&
748 any_of(OpsToSink, [&](const Use *U) { return U->get() == FMul; });
749}
750
751bool hasHighRegisterPressure(unsigned ScheduleBudget, const BasicBlock &BB,
752 Type *Ty, const TargetTransformInfo &TTI) {
753 if (hasNItemsOrMore(BB, ScheduleBudget))
754 return false;
755 const unsigned NumRegs = TTI.getNumberOfRegisters(
756 TTI.getRegisterClassForType(/*Vector=*/false, Ty));
757 auto IsLiveCandidate = [&](const Value *V) {
758 return isa<Instruction, Argument>(V) && V->getType()->getScalarType() == Ty;
759 };
761 for (const Instruction &I : reverse(BB)) {
762 // The operands of the PHIs are live in the predecessors.
763 if (isa<PHINode>(I))
764 break;
765 Live.erase(&I);
766 Live.insert_range(make_filter_range(I.operand_values(), IsLiveCandidate));
767 if (Live.size() > NumRegs)
768 return true;
769 }
770 return false;
771}
772
774 ArrayRef<SmallVector<Value *>> GatheredScalars, const DataLayout &DL,
775 const TargetTransformInfo &TTI, bool ReVec,
777 function_ref<std::optional<
778 std::tuple<const void *, FixedVectorType *, unsigned>>(Value *)>
779 GetVectorizedSource) {
780 struct SourceVector {
781 FixedVectorType *VecTy = nullptr;
782 APInt DemandedElts;
784 SmallVector<unsigned> Gathers;
785 };
787 SmallBitVector BSwapGathers(GatheredScalars.size());
788 for (auto [Idx, VL] : enumerate(GatheredScalars)) {
789 std::optional<std::tuple<Value *, unsigned, SmallVector<int>>> Fields =
791 if (!Fields)
792 continue;
793 auto &[Src, FieldWidth, Mask] = *Fields;
794 Type *SrcTy = Src->getType();
795 unsigned NumFields = SrcTy->getIntegerBitWidth() / FieldWidth;
796 if (FieldWidth != 8 || NumFields % 2 != 0 ||
797 !ShuffleVectorInst::isReverseMask(Mask, NumFields))
798 continue;
799 Type *ByteTy = Type::getInt8Ty(SrcTy->getContext());
800 auto *FieldVecTy = cast<VectorType>(getWidenedType(ByteTy, NumFields));
801 IntrinsicCostAttributes CostAttrs(Intrinsic::bswap, SrcTy, {SrcTy});
802 InstructionCost BSwapCost = TTI.getIntrinsicInstrCost(CostAttrs, CostKind);
804 FieldVecTy, CostKind, Mask);
805 std::optional<std::tuple<const void *, FixedVectorType *, unsigned>>
806 Source = GetVectorizedSource(Src);
807 if (!Source)
808 if (std::optional<unsigned> Lane = getElementIndex(Src)) {
809 auto *EE = cast<ExtractElementInst>(Src);
810 Source = std::make_tuple(
811 EE->getVectorOperand(),
812 cast<FixedVectorType>(EE->getVectorOperandType()), *Lane);
813 }
814 if (!Source) {
815 if (BSwapCost <= PermuteCost)
816 BSwapGathers.set(Idx);
817 continue;
818 }
819 auto &[Vec, VecTy, Lane] = *Source;
820 // The bytes of the scalar are either extracted from the vector as a
821 // subvector and permuted, or permuted from the whole vector directly.
822 auto *VecBytesTy = cast<VectorType>(
823 getWidenedType(ByteTy, NumFields * VecTy->getNumElements()));
824 for (int &I : Mask)
825 if (I != PoisonMaskElem)
826 I += Lane * NumFields;
827 PermuteCost =
828 std::min(PermuteCost + getShuffleCost(TTI, TTI::SK_ExtractSubvector,
829 VecBytesTy, CostKind, {},
830 Lane * NumFields, FieldVecTy),
832 CostKind, Mask));
833 auto [It, Inserted] = SourceVectors.try_emplace(Vec);
834 SourceVector &Info = It->second;
835 if (Inserted) {
836 Info.VecTy = VecTy;
837 Info.DemandedElts = APInt::getZero(VecTy->getNumElements());
838 }
839 Info.DemandedElts.setBit(Lane);
840 Info.Cost += BSwapCost - PermuteCost;
841 Info.Gathers.push_back(Idx);
842 }
843 for (const SourceVector &Info : make_second_range(SourceVectors)) {
845 TTI, ReVec, Info.VecTy->getElementType(), Info.VecTy, Info.DemandedElts,
846 /*Insert=*/false, /*Extract=*/true, CostKind);
847 if (Info.Cost + ExtractCost <= 0)
848 for (unsigned Idx : Info.Gathers)
849 BSwapGathers.set(Idx);
850 }
851 return BSwapGathers;
852}
853} // namespace llvm::slpvectorizer
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define I(x, y, z)
Definition MD5.cpp:57
#define P(N)
This file contains some templates that are useful if you are working with the STL at all.
Provides some synthesis utilities to produce sequences of values.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
Class for arbitrary precision integers.
Definition APInt.h:78
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:196
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & front() const
Get the first element.
Definition ArrayRef.h:144
iterator end() const
Definition ArrayRef.h:130
LLVM Basic Block Representation.
Definition BasicBlock.h:62
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_NE
not equal
Definition InstrTypes.h:762
This is an important base class in LLVM.
Definition Constant.h:44
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:856
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:306
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
static InstructionCost getInvalid(CostType Val=0)
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
Information for memory intrinsic cost model.
static LLVM_ABI unsigned getOpcode(RecurKind Kind)
Returns the opcode corresponding to the RecurrenceKind.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
static LLVM_ABI bool isReverseMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask swaps the order of elements from exactly one source vector.
static LLVM_ABI bool isInsertSubvectorMask(ArrayRef< int > Mask, int NumSrcElts, int &NumSubElts, int &Index)
Return true if this shuffle mask is an insert subvector mask.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
SmallBitVector & set()
size_type size() const
bool erase(PtrType Ptr)
Remove pointer from the set.
void insert_range(Range &&R)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Provides information about what library functions are available for the current target.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
static LLVM_ABI OperandValueInfo getOperandInfo(const Value *V)
Collect properties of V used in cost analysis, e.g. OP_PowerOf2.
TargetCostKind
The kind of cost model.
llvm::VectorInstrContext VectorInstrContext
@ TCC_Expensive
The cost of a 'div' instruction on x86.
@ TCC_Free
Expected to fold away in lowering.
ShuffleKind
The various kinds of shuffle patterns for vector queries.
@ SK_InsertSubvector
InsertSubvector. Index indicates start offset.
@ SK_PermuteSingleSrc
Shuffle elements of single source vector with any shuffle mask.
@ SK_PermuteTwoSrc
Merge elements from two source vectors into one with any shuffle mask.
@ SK_Reverse
Reverse the order of the vector.
@ SK_ExtractSubvector
ExtractSubvector Index indicates start offset.
CastContextHint
Represents a hint about the context in which a cast is used.
@ Masked
The cast is used with a masked load/store.
@ Normal
The cast is used with a normal load/store.
@ GatherScatter
The cast is used with a gather/scatter.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
The Vector Function Database.
Definition VectorUtils.h:35
static SmallVector< VFInfo, 8 > getMappings(const CallInst &CI)
Retrieve all the VFInfo instances associated to the CallInst CI.
Definition VectorUtils.h:76
LLVM Value Representation.
Definition Value.h:75
user_iterator user_begin()
Definition Value.h:404
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
Base class of all SIMD vector types.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Type * getElementType() const
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
An efficient, type-erasing, non-owning reference to a callable.
Function * getVectorizedFunction(const VFShape &Shape) const
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
AllowFmf_match< T, FastMathFlags::AllowContract > m_AllowContract(const T &SubPattern)
A private "module" namespace for types and utilities used by this pass.
std::pair< InstructionCost, bool > getI1ReductionCost(RecurKind Kind, const TargetTransformInfo &TTI, FixedVectorType *VectorTy, Type *ScalarTy, TTI::CastContextHint Ctx, TTI::TargetCostKind CostKind)
i1 reductions can be emitted as the plain target reduction or in the bitcast-based form (bitcast to a...
std::pair< InstructionCost, InstructionCost > getVectorCallCosts(CallInst *CI, Type *VecTy, const TargetTransformInfo &TTI, const TargetLibraryInfo &TLI, ArrayRef< Type * > ArgTys, const TTI::TargetCostKind CostKind)
Calculates the costs of vectorized intrinsic (if possible) and vectorized function (if possible) call...
InstructionCost getShuffleCost(const TargetTransformInfo &TTI, TTI::ShuffleKind Kind, VectorType *Tp, const TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args, TTI::VectorInstrContext VIC)
Returns the cost of the shuffle instructions with the given Kind, vector type Tp and optional Mask.
std::optional< unsigned > getElementIndex(const Value *Inst, unsigned Offset)
Definition SLPUtils.cpp:261
InstructionCost getNarrowedLeafOpsCost(const TargetTransformInfo &TTI, const SmallDenseMap< Value *, NarrowedLeafInfo > &NarrowedLeafShifts, VectorType *NarrowVecTy, VectorType *WideVecTy, const Instruction *CtxI, const TTI::TargetCostKind CostKind)
Returns the cost of the per-lane operations on the narrowed leaves NarrowedLeafShifts: the shl in the...
std::optional< std::tuple< Value *, unsigned, SmallVector< int > > > matchGatheredExtractedFields(ArrayRef< Value * > VL, const DataLayout &DL)
Checks if the values in VL are zero-extended sub-fields of the same wider integer scalar.
InstructionCost getBoolReduxBitcastCmpCost(const TargetTransformInfo &TTI, RecurKind RdxKind, FixedVectorType *VecTy, const Value *Root, ArrayRef< Instruction * > ChainInsts, const TTI::TargetCostKind CostKind)
Returns the cost of the booleanized logical and/or reduction of a vector of type VecTy with the i1 ro...
std::pair< InstructionCost, InstructionCost > getGEPCosts(const TargetTransformInfo &TTI, ArrayRef< Value * > Ptrs, Value *BasePtr, unsigned Opcode, const TTI::TargetCostKind CostKind, Type *ScalarTy, VectorType *VecTy)
Calculate the scalar and the vector costs from vectorizing set of GEPs.
Intrinsic::ID getMaskedDivRemIntrinsic(unsigned Opcode)
SmallVector< int > getBitPackMask(const BitPackInfo &Info, unsigned NumBytes, unsigned NumElts, unsigned BytesPerLane)
Returns the byte shuffle mask packing the per-lane fields of the shifted lanes (BytesPerLane bytes ea...
SmallVector< Type * > buildIntrinsicArgTypes(const CallInst *CI, const Intrinsic::ID ID, const unsigned VF, unsigned MinBW, const TargetTransformInfo &TTI)
Builds the arguments types vector for the given call instruction with the given ID for the specified ...
unsigned getNumElements(Type *Ty)
Definition SLPUtils.cpp:117
Type * getWidenedType(Type *ScalarTy, unsigned VF)
static unsigned getPoorThroughputTypeKey(Type *Ty)
Packs a type's kind and scalar width into one key, so an opcode/intrinsic id reused across scalar wid...
bool isPoorThroughputOp(bool ReVec, Instruction *I, const TargetTransformInfo &TTI, const TargetLibraryInfo &TLI, PoorThroughputOpCache &Cache, const TTI::TargetCostKind CostKind, unsigned MaxVecRegSize)
Returns true if I is an expensive scalar op whose vector form is cheaper per lane (e....
static TTI::CastContextHint getBoolReduxResultCCH(const Value *Root)
Returns the cast context hint for the trunc of the booleanized reduction result, which inherits the u...
InstructionCost getBlendedLoadCost(const TargetTransformInfo &TTI, Type *VecTy, Align Alignment, unsigned AddressSpace, const TTI::TargetCostKind CostKind)
Returns the cost of a BlendedLoadVectorize node loading VecTy: two masked loads (one per candidate ba...
FixedVectorType * getMaskedDivRemType(const TargetTransformInfo &TTI, unsigned Opcode, Type *ScalarTy, unsigned NumElts, bool ReVec)
For a non-power-of-2 NumElts-wide integer div/rem Opcode, returns the padded full-register vector typ...
InstructionCost getBoolBitmaskCost(const TargetTransformInfo &TTI, bool NeedMask, Type *NarrowScalarTy, Type *WideTy, unsigned VF, ArrayRef< int > PermMask, const Value *Root, const TTI::TargetCostKind CostKind)
Returns the cost of the boolean bitmask reduction of a vector of boolean leaves of type NarrowScalarT...
bool isFusableFMulOperand(Value *Op, Instruction *I, const TargetTransformInfo &TTI)
InstructionCost getBoolReduxWideRdxCost(const TargetTransformInfo &TTI, RecurKind RdxKind, FixedVectorType *VecTy, const Value *Root, FastMathFlags FMF, const TTI::TargetCostKind CostKind)
Returns the cost of the booleanized logical and/or reduction of a vector of type VecTy with the i1 ro...
InstructionCost getWidenedStridedCastCost(const TargetTransformInfo &TTI, Type *SrcTy, Type *DstTy, const DataLayout &DL, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind)
Returns the cost of the cast between the widened strided access type and the entry vector type.
bool isValidElementType(Type *Ty, bool ReVec)
Predicate for the element types that the SLP vectorizer supports.
InstructionCost getScalarizationOverhead(const TargetTransformInfo &TTI, bool ReVec, Type *ScalarTy, VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, const TTI::TargetCostKind CostKind, bool ForPoisonSrc, ArrayRef< Value * > VL, TTI::VectorInstrContext VIC)
This is similar to TargetTransformInfo::getScalarizationOverhead, but if ScalarTy is a FixedVectorTyp...
bool hasHighRegisterPressure(unsigned ScheduleBudget, const BasicBlock &BB, Type *Ty, const TargetTransformInfo &TTI)
SmallBitVector selectBSwapGathers(ArrayRef< SmallVector< Value * > > GatheredScalars, const DataLayout &DL, const TargetTransformInfo &TTI, bool ReVec, TargetTransformInfo::TargetCostKind CostKind, function_ref< std::optional< std::tuple< const void *, FixedVectorType *, unsigned > >(Value *)> GetVectorizedSource)
Selects the gathers of GatheredScalars, which fully reverse the bytes of a scalar and are emitted as ...
InstructionCost getExtractWithExtendCost(const TargetTransformInfo &TTI, bool ReVec, unsigned Opcode, Type *Dst, VectorType *VecTy, unsigned Index, const TTI::TargetCostKind CostKind)
This is similar to TargetTransformInfo::getExtractWithExtendCost, but if Dst is a FixedVectorType,...
static InstructionCost getVectorOpCost(Instruction *I, unsigned VF, const TargetTransformInfo &TTI, const TargetLibraryInfo &TLI, const TTI::TargetCostKind CostKind)
static InstructionCost getBoolLogicRdxBitcastCost(RecurKind Kind, const TargetTransformInfo &TTI, FixedVectorType *VectorTy, TTI::CastContextHint Ctx, TTI::TargetCostKind CostKind)
constexpr int UsesLimit
Limit of the number of uses for potentially transformed instructions/values, used in checks to avoid ...
Definition SLPUtils.h:59
InstructionCost getVectorInstrCost(const TargetTransformInfo &TTI, bool ReVec, Type *ScalarTy, unsigned Opcode, Type *Val, const TTI::TargetCostKind CostKind, unsigned Index, Value *Scalar, ArrayRef< std::tuple< Value *, User *, int > > ScalarUserAndIdx, TTI::VectorInstrContext VIC)
This is similar to TargetTransformInfo::getVectorInstrCost, but if ScalarTy is a FixedVectorType,...
InstructionCost getMaskedDivRemCost(const TargetTransformInfo &TTI, bool ReVec, unsigned Opcode, Type *ScalarTy, unsigned NumElts, const TTI::TargetCostKind CostKind, FixedVectorType **PaddedTy)
For a non-power-of-2 NumElts-wide integer div/rem Opcode, checks if padding to a full register and us...
InstructionCost getBitPackCost(const TargetTransformInfo &TTI, FixedVectorType *SrcTy, Type *ResultTy, const BitPackInfo &Info, unsigned ZExtSrcWidth, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const TargetLibraryInfo *TLI, const Instruction *CtxI, unsigned &ShiftWidth)
Returns the cost of the bitfield packing of SrcTy into ResultTy, picking the cheapest shift width.
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
LLVM_ABI Intrinsic::ID getVectorIntrinsicIDForCall(const CallInst *CI, const TargetLibraryInfo *TLI)
Returns intrinsic ID for call.
InstructionCost Cost
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
Type * toScalarizedTy(Type *Ty)
A helper for converting vectorized types to scalarized (non-vector) types.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool isVectorizedTy(Type *Ty)
Returns true if Ty is a vector type or a struct of vector types where all vector types share the same...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:366
bool hasNItemsOrMore(IterTy &&Begin, IterTy &&End, unsigned N, Pred &&ShouldBeCounted=[](const decltype(*std::declval< IterTy >()) &) { return true;}, std::enable_if_t< !std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< std::remove_reference_t< decltype(Begin)> >::iterator_category >::value, void > *=nullptr)
Return true if the sequence [Begin, End) has N or more items.
Definition STLExtras.h:2654
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
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
bool isPointerTy(const Type *T)
Definition SPIRVUtils.h:373
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:552
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
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
constexpr int PoisonMaskElem
TargetTransformInfo TTI
RecurKind
These are the kinds of recurrences that we support.
@ Or
Bitwise or logical OR of integers.
@ FMul
Product of floats.
@ And
Bitwise or logical AND of integers.
@ Add
Sum of integers.
LLVM_ABI bool isVectorIntrinsicWithScalarOpAtArg(Intrinsic::ID ID, unsigned ScalarOpdIdx, const TargetTransformInfo *TTI)
Identifies if the vector form of the intrinsic has a scalar operand.
DWARFExpression::Operation Op
auto max_element(R &&Range)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2104
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
Definition STLExtras.h:1425
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
Definition STLExtras.h:2182
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
Definition STLExtras.h:2162
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Describe known properties for a set of pointers.
unsigned IsSameBaseAddress
All the GEPs in a set have same base address.
static VFShape get(const FunctionType *FTy, ElementCount EC, bool HasGlobalPred)
Retrieve the basic vectorization shape of the function, where all parameters are mapped to VFParamKin...
Description of a bitfield packing of vector lanes into a scalar value: every lane contributes a disjo...
Definition SLPUtils.h:499
static constexpr unsigned NoLane
Definition SLPUtils.h:500
Memoizes opcode / intrinsic / callee kinds already ruled out as seeds.