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"
18#include "llvm/IR/Constants.h"
19#include "llvm/IR/DataLayout.h"
23#include "llvm/IR/Intrinsics.h"
24#include "llvm/IR/Operator.h"
26#include "llvm/IR/Type.h"
27#include "llvm/IR/Value.h"
31
32#include <cassert>
33#include <utility>
34
35using namespace llvm;
36using namespace llvm::PatternMatch;
37
38namespace llvm::slpvectorizer {
39
43 ArrayRef<int> Mask, int Index, VectorType *SubTp,
46 VectorType *DstTy = Tp;
47 if (!Mask.empty())
48 DstTy = FixedVectorType::get(Tp->getScalarType(), Mask.size());
49
50 if (Kind != TTI::SK_PermuteTwoSrc)
51 return TTI.getShuffleCost(Kind, DstTy, Tp, CostKind, Mask, Index, SubTp,
52 Args, /*CtxI=*/nullptr, VIC);
53 int NumSrcElts = Tp->getElementCount().getKnownMinValue();
54 int NumSubElts;
55 if (Mask.size() > 2 && ShuffleVectorInst::isInsertSubvectorMask(
56 Mask, NumSrcElts, NumSubElts, Index)) {
57 if (Index + NumSubElts > NumSrcElts &&
58 Index + NumSrcElts <= static_cast<int>(Mask.size()))
59 return TTI.getShuffleCost(TTI::SK_InsertSubvector, DstTy, Tp, CostKind,
60 Mask, Index, Tp);
61 }
62 return TTI.getShuffleCost(Kind, DstTy, Tp, CostKind, Mask, Index, SubTp, Args,
63 /*CtxI=*/nullptr, VIC);
64}
65
66std::pair<InstructionCost, InstructionCost>
68 Value *BasePtr, unsigned Opcode, const TTI::TargetCostKind CostKind,
69 Type *ScalarTy, VectorType *VecTy) {
70 InstructionCost ScalarCost = 0;
71 InstructionCost VecCost = 0;
72 // Here we differentiate two cases: (1) when Ptrs represent a regular
73 // vectorization tree node (as they are pointer arguments of scattered
74 // loads) or (2) when Ptrs are the arguments of loads or stores being
75 // vectorized as plane wide unit-stride load/store since all the
76 // loads/stores are known to be from/to adjacent locations.
77 if (Opcode == Instruction::Load || Opcode == Instruction::Store) {
78 // Case 2: estimate costs for pointer related costs when vectorizing to
79 // a wide load/store.
80 // Scalar cost is estimated as a set of pointers with known relationship
81 // between them.
82 // For vector code we will use BasePtr as argument for the wide load/store
83 // but we also need to account all the instructions which are going to
84 // stay in vectorized code due to uses outside of these scalar
85 // loads/stores.
86 ScalarCost = TTI.getPointersChainCost(
87 Ptrs, BasePtr, TTI::PointersChainInfo::getUnitStride(), ScalarTy,
88 CostKind);
89
90 SmallVector<const Value *> PtrsRetainedInVecCode;
91 for (Value *V : Ptrs) {
92 if (V == BasePtr) {
93 PtrsRetainedInVecCode.push_back(V);
94 continue;
95 }
96 auto *Ptr = dyn_cast<GetElementPtrInst>(V);
97 // For simplicity assume Ptr to stay in vectorized code if it's not a
98 // GEP instruction. We don't care since it's cost considered free.
99 // TODO: We should check for any uses outside of vectorizable tree
100 // rather than just single use.
101 if (!Ptr || !Ptr->hasOneUse())
102 PtrsRetainedInVecCode.push_back(V);
103 }
104
105 if (PtrsRetainedInVecCode.size() == Ptrs.size()) {
106 // If all pointers stay in vectorized code then we don't have
107 // any savings on that.
108 return std::make_pair(TTI::TCC_Free, TTI::TCC_Free);
109 }
110 VecCost = TTI.getPointersChainCost(PtrsRetainedInVecCode, BasePtr,
111 TTI::PointersChainInfo::getKnownStride(),
112 VecTy, CostKind);
113 } else {
114 // Case 1: Ptrs are the arguments of loads that we are going to transform
115 // into masked gather load intrinsic.
116 // All the scalar GEPs will be removed as a result of vectorization.
117 // For any external uses of some lanes extract element instructions will
118 // be generated (which cost is estimated separately).
119 TTI::PointersChainInfo PtrsInfo =
120 all_of(Ptrs,
121 [](const Value *V) {
122 auto *Ptr = dyn_cast<GetElementPtrInst>(V);
123 return Ptr && !Ptr->hasAllConstantIndices();
124 })
125 ? TTI::PointersChainInfo::getUnknownStride()
126 : TTI::PointersChainInfo::getKnownStride();
127
128 const bool IsSameBase =
130 all_equal(map_range(Ptrs, [](Value *V) {
131 return cast<GetElementPtrInst>(V)->getPointerOperand();
132 }));
133 // The GEPs of the masked gather loads are accessed with the loaded type
134 // and form a chain only if the lanes share the base.
135 Type *AccessTy = ScalarTy;
136 if (all_of(Ptrs, [](const Value *V) {
137 auto *Ptr = dyn_cast<GetElementPtrInst>(V);
138 return Ptr && Ptr->hasOneUse() && isa<LoadInst>(Ptr->user_back());
139 })) {
140 PtrsInfo.IsSameBaseAddress = IsSameBase;
141 AccessTy = Ptrs.front()->user_back()->getType();
142 }
143 ScalarCost =
144 TTI.getPointersChainCost(Ptrs, BasePtr, PtrsInfo, AccessTy, CostKind);
145 auto *BaseGEP = dyn_cast<GEPOperator>(BasePtr);
146 if (!BaseGEP) {
147 auto *It = find_if(Ptrs, IsaPred<GEPOperator>);
148 if (It != Ptrs.end())
149 BaseGEP = cast<GEPOperator>(*It);
150 }
151 if (!IsSameBase) {
152 // The different bases are not folded into the addressing of the vector
153 // access, the scaled indices are added to them.
154 const DataLayout &DL = cast<Instruction>(Ptrs.front())->getDataLayout();
155 Type *IdxTy = DL.getIndexType(VecTy);
156 VecCost = TTI.getArithmeticInstrCost(Instruction::Add, IdxTy, CostKind);
157 uint64_t Stride = DL.getTypeAllocSize(BaseGEP->getSourceElementType())
158 .getKnownMinValue();
159 if (Stride != 1 && !all_of(Ptrs, [](Value *V) {
160 return isa<Constant>(cast<GetElementPtrInst>(V)->getOperand(1));
161 }))
162 VecCost += TTI.getArithmeticInstrCost(
163 isPowerOf2_64(Stride) ? Instruction::Shl : Instruction::Mul, IdxTy,
165 } else if (BaseGEP) {
166 SmallVector<const Value *> Indices(BaseGEP->indices());
167 VecCost = TTI.getGEPCost(BaseGEP->getSourceElementType(),
168 BaseGEP->getPointerOperand(), Indices, CostKind,
169 VecTy);
170 }
171 }
172
173 return std::make_pair(ScalarCost, VecCost);
174}
175
177 Align Alignment, unsigned AddressSpace,
179 Type *CmpTy = CmpInst::makeCmpResultType(VecTy);
180 return 2 * TTI.getMemIntrinsicInstrCost(
181 MemIntrinsicCostAttributes(Intrinsic::masked_load, VecTy,
182 Alignment, AddressSpace),
183 CostKind) +
184 TTI.getArithmeticInstrCost(Instruction::Xor, CmpTy, CostKind) +
185 TTI.getCmpSelInstrCost(Instruction::Select, VecTy, CmpTy,
187}
188
190 Type *SrcTy, Type *DstTy,
191 const DataLayout &DL,
194 bool ToPtr = cast<VectorType>(DstTy)->getElementType()->isPointerTy();
195 if (ToPtr == cast<VectorType>(SrcTy)->getElementType()->isPointerTy())
196 return TTI.getCastInstrCost(Instruction::BitCast, DstTy, SrcTy, CCH,
197 CostKind);
198 // The ptr/int conversion keeps the vector shape, the bitcast transforms the
199 // resulting integer vector.
200 if (ToPtr) {
201 Type *IntVecTy = DL.getIntPtrType(DstTy);
202 return TTI.getCastInstrCost(Instruction::IntToPtr, DstTy, IntVecTy, CCH,
203 CostKind) +
204 TTI.getCastInstrCost(Instruction::BitCast, IntVecTy, SrcTy, CCH,
205 CostKind);
206 }
207 Type *IntVecTy = DL.getIntPtrType(SrcTy);
208 return TTI.getCastInstrCost(Instruction::PtrToInt, IntVecTy, SrcTy, CCH,
209 CostKind) +
210 TTI.getCastInstrCost(Instruction::BitCast, DstTy, IntVecTy, CCH,
211 CostKind);
212}
213
215 unsigned Opcode, Type *ScalarTy,
216 unsigned NumElts,
218 FixedVectorType **PaddedTy) {
219 FixedVectorType *PaddedVecTy =
220 getMaskedDivRemType(TTI, Opcode, ScalarTy, NumElts, ReVec);
221 if (!PaddedVecTy)
223 // One mask bit per element of the padded vector, not per padded lane.
224 auto *MaskTy =
226 PaddedVecTy->getNumElements());
227 InstructionCost DirectCost = TTI.getArithmeticInstrCost(
228 Opcode, getWidenedType(ScalarTy, NumElts), CostKind);
229 IntrinsicCostAttributes ICA(getMaskedDivRemIntrinsic(Opcode), PaddedVecTy,
230 {PaddedVecTy, PaddedVecTy, MaskTy});
231 InstructionCost MaskedCost = TTI.getIntrinsicInstrCost(ICA, CostKind);
232 if (!MaskedCost.isValid() || MaskedCost >= DirectCost)
234 if (PaddedTy)
235 *PaddedTy = PaddedVecTy;
236 return MaskedCost;
237}
238
241 Type *ScalarTy, VectorType *Ty,
242 const APInt &DemandedElts, bool Insert, bool Extract,
243 const TTI::TargetCostKind CostKind, bool ForPoisonSrc,
246 "ScalableVectorType is not supported.");
247 assert(getNumElements(ScalarTy) * DemandedElts.getBitWidth() ==
248 getNumElements(Ty) &&
249 "Incorrect usage.");
250 if (auto *VecTy = dyn_cast<FixedVectorType>(ScalarTy)) {
251 assert(ReVec && "Only supported by REVEC.");
252 // If ScalarTy is FixedVectorType, we should use CreateInsertVector instead
253 // of CreateInsertElement.
254 unsigned ScalarTyNumElements = VecTy->getNumElements();
256 for (unsigned I : seq(DemandedElts.getBitWidth())) {
257 if (!DemandedElts[I])
258 continue;
259 if (Insert)
261 I * ScalarTyNumElements, VecTy);
262 if (Extract)
264 I * ScalarTyNumElements, VecTy);
265 }
266 return Cost;
267 }
268 return TTI.getScalarizationOverhead(Ty, DemandedElts, Insert, Extract,
269 CostKind, ForPoisonSrc, VL, VIC);
270}
271
273 const TargetTransformInfo &TTI, bool ReVec, Type *ScalarTy, unsigned Opcode,
274 Type *Val, const TTI::TargetCostKind CostKind, unsigned Index,
275 Value *Scalar, ArrayRef<std::tuple<Value *, User *, int>> ScalarUserAndIdx,
277 if (Opcode == Instruction::ExtractElement) {
278 if (auto *VecTy = dyn_cast<FixedVectorType>(ScalarTy)) {
279 assert(ReVec && "Only supported by REVEC.");
280 assert(isa<VectorType>(Val) && "Val must be a vector type.");
282 cast<VectorType>(Val), CostKind, {},
283 Index * VecTy->getNumElements(), VecTy);
284 }
285 }
286 return TTI.getVectorInstrCost(Opcode, Val, CostKind, Index, Scalar,
287 ScalarUserAndIdx, VIC);
288}
289
291 bool ReVec, unsigned Opcode, Type *Dst,
292 VectorType *VecTy, unsigned Index,
294 if (isVectorizedTy(Dst)) {
295 assert(ReVec && "Only supported by REVEC.");
296 auto *SubTp = cast<FixedVectorType>(
299 Index * getNumElements(Dst), SubTp) +
300 TTI.getCastInstrCost(Opcode, Dst, SubTp, TTI::CastContextHint::None,
301 CostKind);
302 }
303 return TTI.getExtractWithExtendCost(Opcode, Dst, VecTy, Index, CostKind);
304}
305
306/// Returns the cast context hint for the trunc of the booleanized reduction
307/// result, which inherits the uses of the reduction root \p Root.
320
322 RecurKind RdxKind,
323 FixedVectorType *VecTy,
324 const Value *Root, FastMathFlags FMF,
326 Type *I1Ty = Type::getInt1Ty(VecTy->getContext());
327 return TTI.getArithmeticReductionCost(
328 RecurrenceDescriptor::getOpcode(RdxKind), VecTy, FMF, CostKind) +
329 TTI.getCastInstrCost(Instruction::Trunc, I1Ty, VecTy->getScalarType(),
331}
332
334 RecurKind RdxKind,
335 FixedVectorType *VecTy,
336 const Value *Root,
337 ArrayRef<Instruction *> ChainInsts,
339 // The new instructions are costed in the context of the replaced cast chain
340 // instructions.
341 auto TruncIt =
342 find_if(ChainInsts, [](Instruction *I) { return isa<TruncInst>(I); });
343 const Instruction *TruncI = TruncIt == ChainInsts.end() ? nullptr : *TruncIt;
344 auto CmpIt =
345 find_if(ChainInsts, [](Instruction *I) { return isa<ICmpInst>(I); });
346 const Instruction *CmpI = CmpIt == ChainInsts.end() ? nullptr : *CmpIt;
347 unsigned VF = VecTy->getNumElements();
348 auto *I1VecTy =
350 Type *IntTy = IntegerType::get(VecTy->getContext(), VF);
351 Constant *CmpRHS = RdxKind == RecurKind::And
353 : Constant::getNullValue(IntTy);
354 return TTI.getCastInstrCost(Instruction::Trunc, I1VecTy, VecTy,
355 TTI.getCastContextHint(TruncI), CostKind,
356 TruncI) +
357 TTI.getCastInstrCost(Instruction::BitCast, IntTy, I1VecTy,
358 TTI.getCastContextHint(TruncI), CostKind) +
359 TTI.getCmpSelInstrCost(
360 Instruction::ICmp, IntTy, CmpInst::makeCmpResultType(IntTy),
362 CostKind, TTI.getOperandInfo(Root), TTI.getOperandInfo(CmpRHS),
363 CmpI);
364}
365
366static InstructionCost
370 assert((Kind == RecurKind::And || Kind == RecurKind::Or) &&
371 VectorTy->getElementType()->isIntegerTy(1) &&
372 "Expected and/or reduction of i1");
373 auto *IntTy =
374 IntegerType::get(VectorTy->getContext(), getNumElements(VectorTy));
375 CmpInst::Predicate Pred =
377 // The compare is against the all-ones (and) or zero (or) constant.
378 return TTI.getCastInstrCost(Instruction::BitCast, IntTy, VectorTy, Ctx,
379 CostKind) +
380 TTI.getCmpSelInstrCost(Instruction::ICmp, IntTy,
381 CmpInst::makeCmpResultType(IntTy), Pred,
382 CostKind, /*Op1Info=*/{},
384}
385
386std::pair<InstructionCost, bool>
388 FixedVectorType *VectorTy, Type *ScalarTy,
390 unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(Kind);
391 if (Kind == RecurKind::And || Kind == RecurKind::Or) {
392 InstructionCost RdxCost = TTI.getArithmeticReductionCost(
393 RdxOpcode, VectorTy, std::nullopt, CostKind);
394 InstructionCost BitcastCost =
395 getBoolLogicRdxBitcastCost(Kind, TTI, VectorTy, Ctx, CostKind);
396 return {std::min(RdxCost, BitcastCost), BitcastCost < RdxCost};
397 }
398 assert(Kind == RecurKind::Add && !ScalarTy->isIntegerTy(1) &&
399 "Expected add reduction of zexted i1 values");
400 // The bitcast+ctpop form is estimated as the cheaper of the extended
401 // reduction cost, which models it for the zexted i1 add reduction, and the
402 // explicitly priced components, including the cast of the ctpop result to
403 // the destination type.
404 auto *IntTy =
405 IntegerType::get(VectorTy->getContext(), getNumElements(VectorTy));
406 InstructionCost ExplicitCost =
407 TTI.getCastInstrCost(Instruction::BitCast, IntTy, VectorTy, Ctx,
408 CostKind) +
409 TTI.getIntrinsicInstrCost(
410 IntrinsicCostAttributes(Intrinsic::ctpop, IntTy, {IntTy}), CostKind);
411 if (IntTy != ScalarTy)
412 ExplicitCost += TTI.getCastInstrCost(IntTy->getBitWidth() <
413 ScalarTy->getIntegerBitWidth()
414 ? Instruction::ZExt
415 : Instruction::Trunc,
416 ScalarTy, IntTy, Ctx, CostKind);
417 InstructionCost CtpopCost = std::min(
418 TTI.getExtendedReductionCost(RdxOpcode, /*IsUnsigned=*/true, ScalarTy,
419 VectorTy, std::nullopt, CostKind),
420 ExplicitCost);
421 // The plain form is the zext to the wide vector type plus the reduction.
422 auto *ExtTy = VectorType::get(ScalarTy, VectorTy);
423 InstructionCost ExtRdxCost =
424 TTI.getCastInstrCost(Instruction::ZExt, ExtTy, VectorTy, Ctx, CostKind) +
425 TTI.getArithmeticReductionCost(RdxOpcode, ExtTy, std::nullopt, CostKind);
426 return {std::min(ExtRdxCost, CtpopCost), CtpopCost <= ExtRdxCost};
427}
428
430 FixedVectorType *SrcTy, Type *ResultTy,
431 const BitPackInfo &Info, unsigned ZExtSrcWidth,
434 const TargetLibraryInfo *TLI,
435 const Instruction *CtxI, unsigned &ShiftWidth) {
436 unsigned BitWidth = SrcTy->getScalarSizeInBits();
437 unsigned NumElts = SrcTy->getNumElements();
438 uint64_t MaxAmt = *max_element(Info.LShrAmts);
439 // The shift amounts form a constant vector.
440 TTI::OperandValueInfo ShiftAmtInfo = {
443 all_of(Info.LShrAmts,
444 [](uint64_t A) { return A == 0 || isPowerOf2_64(A); })
446 : TTI::OP_None};
447 // After the shift the field content of each lane sits in the low bits of
448 // the lane, so the packing is a single byte shuffle of the shifted lanes.
449 // Pick the cheapest shift width: the narrowest type still holding the field
450 // content is not always the cheapest (e.g. missing narrow variable shifts).
451 Type *Int8Ty = Type::getInt8Ty(SrcTy->getContext());
452 assert(BitWidth % 8 == 0 &&
453 "The byte-multiple field width divides the result bit width.");
454 unsigned OutBytes = ResultTy->getScalarSizeInBits() / 8;
455 auto *PackTy = FixedVectorType::get(Int8Ty, OutBytes);
456 unsigned MinShiftWidth = 8;
457 while (MinShiftWidth < MaxAmt + Info.FieldWidth)
458 MinShiftWidth *= 2;
459 bool IsReversed = equal(Info.LaneOfField, reverse(seq<unsigned>(NumElts)));
460 bool IsTrunc = IsReversed || equal(Info.LaneOfField, seq<unsigned>(NumElts));
461 auto *FieldTy = FixedVectorType::get(
462 IntegerType::get(SrcTy->getContext(), Info.FieldWidth), NumElts);
464 ShiftWidth = 0;
465 for (unsigned W2 = MinShiftWidth; W2 <= BitWidth; W2 *= 2) {
466 auto *ShiftTy = FixedVectorType::get(
467 IntegerType::get(SrcTy->getContext(), W2), NumElts);
468 unsigned BytesPerLane = W2 / 8;
469 unsigned InBytes = NumElts * BytesPerLane;
470 SmallVector<int> Mask =
471 getBitPackMask(Info, OutBytes, NumElts, BytesPerLane);
472 InstructionCost C = TTI.getCastInstrCost(Instruction::BitCast, ResultTy,
473 PackTy, CCH, CostKind);
474 if (IsTrunc) {
475 // Fields in lane order, possibly reversed, are a truncation of the
476 // shifted lanes. A reversal of byte fields is a bswap.
477 if (Info.FieldWidth < W2)
478 C += TTI.getCastInstrCost(Instruction::Trunc, FieldTy, ShiftTy,
480 if (IsReversed && Info.FieldWidth == 8) {
481 IntrinsicCostAttributes CostAttrs(Intrinsic::bswap, ResultTy,
482 {ResultTy});
483 C += TTI.getIntrinsicInstrCost(CostAttrs, CostKind);
484 } else if (IsReversed) {
485 C += TTI.getShuffleCost(TargetTransformInfo::SK_Reverse, FieldTy,
486 FieldTy, CostKind);
487 }
488 } else {
489 // A narrowing shuffle is a shuffle at the source width followed by an
490 // extract of the low elements.
491 auto *SrcByteTy = FixedVectorType::get(Int8Ty, InBytes);
492 SmallVector<int> WideMask(Mask);
493 WideMask.resize(std::max(InBytes, OutBytes), PoisonMaskElem);
494 C += TTI.getShuffleCost(
495 is_contained(Info.LaneOfField, BitPackInfo::NoLane)
498 FixedVectorType::get(Int8Ty, WideMask.size()), SrcByteTy, CostKind,
499 WideMask, /*Index=*/0, /*SubTp=*/nullptr, /*Args=*/{}, CtxI);
500 if (InBytes > OutBytes)
502 PackTy, SrcByteTy, CostKind, /*Mask=*/{},
503 /*Index=*/0, PackTy, /*Args=*/{}, CtxI);
504 }
505 if (W2 != BitWidth && W2 != ZExtSrcWidth)
506 C += TTI.getCastInstrCost(Instruction::Trunc, ShiftTy, SrcTy, CCH,
507 CostKind);
508 if (Info.needsShift())
509 C += TTI.getArithmeticInstrCost(Instruction::LShr, ShiftTy, CostKind,
510 /*Opd1Info=*/{}, ShiftAmtInfo,
511 /*Args=*/{}, CtxI, TLI);
512 if (C.isValid() && (!NewCost.isValid() || C < NewCost)) {
513 NewCost = C;
514 ShiftWidth = W2;
515 }
516 }
517 return NewCost;
518}
519
521 bool NeedMask, Type *NarrowScalarTy,
522 Type *WideTy, unsigned VF,
523 ArrayRef<int> PermMask, const Value *Root,
525 auto *NarrowVecTy = cast<VectorType>(getWidenedType(NarrowScalarTy, VF));
526 Type *CmpTy = CmpInst::makeCmpResultType(NarrowVecTy);
527 auto *MaskTy = IntegerType::get(WideTy->getContext(), VF);
528 // The result cast inherits the uses of the reduction root.
530 const auto *CtxI = cast<Instruction>(Root);
532 if (NeedMask)
533 Cost += TTI.getArithmeticInstrCost(
534 Instruction::And, NarrowVecTy, CostKind,
537 if (!ShuffleVectorInst::isIdentityMask(PermMask, VF))
539 PermMask);
540 if (!NarrowScalarTy->isIntegerTy(1))
541 Cost += TTI.getCmpSelInstrCost(
542 Instruction::ICmp, NarrowVecTy, CmpTy, CmpInst::ICMP_NE, CostKind,
545 // Only the final cast inherits the uses of the reduction root.
546 Cost += TTI.getCastInstrCost(
547 Instruction::BitCast, MaskTy, CmpTy,
548 MaskTy == WideTy ? CCH : TTI::CastContextHint::None, CostKind);
549 if (MaskTy != WideTy)
550 Cost +=
551 TTI.getCastInstrCost(Instruction::ZExt, WideTy, MaskTy, CCH, CostKind);
552 return Cost;
553}
554
557 const SmallDenseMap<Value *, NarrowedLeafInfo> &NarrowedLeafShifts,
558 VectorType *NarrowVecTy, VectorType *WideVecTy, const Instruction *CtxI,
561 if (any_of(NarrowedLeafShifts,
562 [](const auto &P) { return P.second.Shift != 0; }))
563 Cost += TTI.getArithmeticInstrCost(
564 Instruction::Shl, WideVecTy, CostKind, {TTI::OK_AnyValue, TTI::OP_None},
565 {TTI::OK_NonUniformConstantValue, TTI::OP_None}, {}, CtxI);
566 if (any_of(NarrowedLeafShifts,
567 [](const auto &P) { return !P.second.Mask.isAllOnes(); }))
568 Cost += TTI.getArithmeticInstrCost(
569 Instruction::And, NarrowVecTy, CostKind,
570 {TTI::OK_AnyValue, TTI::OP_None},
571 {TTI::OK_NonUniformConstantValue, TTI::OP_None}, {}, CtxI);
572 return Cost;
573}
574} // namespace llvm::slpvectorizer
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")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
#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 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
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
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:43
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
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 isInsertSubvectorMask(ArrayRef< int > Mask, int NumSrcElts, int &NumSubElts, int &Index)
Return true if this shuffle mask is an insert subvector mask.
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.
TargetCostKind
The kind of cost model.
llvm::VectorInstrContext VectorInstrContext
@ 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
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
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
bool match(Val *V, const Pattern &P)
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
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...
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.
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...
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...
unsigned getNumElements(Type *Ty)
Definition SLPUtils.cpp:110
Type * getWidenedType(Type *ScalarTy, unsigned VF)
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...
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.
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...
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 getBoolLogicRdxBitcastCost(RecurKind Kind, const TargetTransformInfo &TTI, FixedVectorType *VectorTy, TTI::CastContextHint Ctx, TTI::TargetCostKind CostKind)
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
InstructionCost Cost
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 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:381
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 int PoisonMaskElem
TargetTransformInfo TTI
RecurKind
These are the kinds of recurrences that we support.
@ Or
Bitwise or logical OR of integers.
@ And
Bitwise or logical AND of integers.
@ Add
Sum of integers.
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
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
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.
Description of a bitfield packing of vector lanes into a scalar value: every lane contributes a disjo...
Definition SLPUtils.h:489
static constexpr unsigned NoLane
Definition SLPUtils.h:490