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
11#include "llvm/ADT/STLExtras.h"
15#include "llvm/IR/Operator.h"
16#include "llvm/IR/Value.h"
18
19#include <utility>
20
21using namespace llvm;
22
23namespace llvm::slpvectorizer {
24
28 int Index, VectorType *SubTp,
30 VectorType *DstTy = Tp;
31 if (!Mask.empty())
32 DstTy = FixedVectorType::get(Tp->getScalarType(), Mask.size());
33
34 if (Kind != TTI::SK_PermuteTwoSrc)
35 return TTI.getShuffleCost(Kind, DstTy, Tp, Mask, CostKind, Index, SubTp,
36 Args);
37 int NumSrcElts = Tp->getElementCount().getKnownMinValue();
38 int NumSubElts;
39 if (Mask.size() > 2 && ShuffleVectorInst::isInsertSubvectorMask(
40 Mask, NumSrcElts, NumSubElts, Index)) {
41 if (Index + NumSubElts > NumSrcElts &&
42 Index + NumSrcElts <= static_cast<int>(Mask.size()))
43 return TTI.getShuffleCost(TTI::SK_InsertSubvector, DstTy, Tp, Mask,
44 TTI::TCK_RecipThroughput, Index, Tp);
45 }
46 return TTI.getShuffleCost(Kind, DstTy, Tp, Mask, CostKind, Index, SubTp,
47 Args);
48}
49
50std::pair<InstructionCost, InstructionCost>
52 Value *BasePtr, unsigned Opcode, TTI::TargetCostKind CostKind,
53 Type *ScalarTy, VectorType *VecTy) {
54 InstructionCost ScalarCost = 0;
55 InstructionCost VecCost = 0;
56 // Here we differentiate two cases: (1) when Ptrs represent a regular
57 // vectorization tree node (as they are pointer arguments of scattered
58 // loads) or (2) when Ptrs are the arguments of loads or stores being
59 // vectorized as plane wide unit-stride load/store since all the
60 // loads/stores are known to be from/to adjacent locations.
61 if (Opcode == Instruction::Load || Opcode == Instruction::Store) {
62 // Case 2: estimate costs for pointer related costs when vectorizing to
63 // a wide load/store.
64 // Scalar cost is estimated as a set of pointers with known relationship
65 // between them.
66 // For vector code we will use BasePtr as argument for the wide load/store
67 // but we also need to account all the instructions which are going to
68 // stay in vectorized code due to uses outside of these scalar
69 // loads/stores.
70 ScalarCost = TTI.getPointersChainCost(
71 Ptrs, BasePtr, TTI::PointersChainInfo::getUnitStride(), ScalarTy,
72 CostKind);
73
74 SmallVector<const Value *> PtrsRetainedInVecCode;
75 for (Value *V : Ptrs) {
76 if (V == BasePtr) {
77 PtrsRetainedInVecCode.push_back(V);
78 continue;
79 }
80 auto *Ptr = dyn_cast<GetElementPtrInst>(V);
81 // For simplicity assume Ptr to stay in vectorized code if it's not a
82 // GEP instruction. We don't care since it's cost considered free.
83 // TODO: We should check for any uses outside of vectorizable tree
84 // rather than just single use.
85 if (!Ptr || !Ptr->hasOneUse())
86 PtrsRetainedInVecCode.push_back(V);
87 }
88
89 if (PtrsRetainedInVecCode.size() == Ptrs.size()) {
90 // If all pointers stay in vectorized code then we don't have
91 // any savings on that.
92 return std::make_pair(TTI::TCC_Free, TTI::TCC_Free);
93 }
94 VecCost = TTI.getPointersChainCost(PtrsRetainedInVecCode, BasePtr,
95 TTI::PointersChainInfo::getKnownStride(),
96 VecTy, CostKind);
97 } else {
98 // Case 1: Ptrs are the arguments of loads that we are going to transform
99 // into masked gather load intrinsic.
100 // All the scalar GEPs will be removed as a result of vectorization.
101 // For any external uses of some lanes extract element instructions will
102 // be generated (which cost is estimated separately).
103 TTI::PointersChainInfo PtrsInfo =
104 all_of(Ptrs,
105 [](const Value *V) {
106 auto *Ptr = dyn_cast<GetElementPtrInst>(V);
107 return Ptr && !Ptr->hasAllConstantIndices();
108 })
109 ? TTI::PointersChainInfo::getUnknownStride()
110 : TTI::PointersChainInfo::getKnownStride();
111
112 ScalarCost =
113 TTI.getPointersChainCost(Ptrs, BasePtr, PtrsInfo, ScalarTy, CostKind);
114 auto *BaseGEP = dyn_cast<GEPOperator>(BasePtr);
115 if (!BaseGEP) {
116 auto *It = find_if(Ptrs, IsaPred<GEPOperator>);
117 if (It != Ptrs.end())
118 BaseGEP = cast<GEPOperator>(*It);
119 }
120 if (BaseGEP) {
121 SmallVector<const Value *> Indices(BaseGEP->indices());
122 VecCost = TTI.getGEPCost(BaseGEP->getSourceElementType(),
123 BaseGEP->getPointerOperand(), Indices, VecTy,
124 CostKind);
125 }
126 }
127
128 return std::make_pair(ScalarCost, VecCost);
129}
130
131} // namespace llvm::slpvectorizer
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")))
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallVector class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:867
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 push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ 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_PermuteTwoSrc
Merge elements from two source vectors into one with any shuffle mask.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
LLVM Value Representation.
Definition Value.h:75
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...
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
A private "module" namespace for types and utilities used by this pass.
std::pair< InstructionCost, InstructionCost > getGEPCosts(const TargetTransformInfo &TTI, ArrayRef< Value * > Ptrs, Value *BasePtr, unsigned Opcode, TTI::TargetCostKind CostKind, Type *ScalarTy, VectorType *VecTy)
Calculate the scalar and the vector costs from vectorizing set of GEPs.
InstructionCost getShuffleCost(const TargetTransformInfo &TTI, TTI::ShuffleKind Kind, VectorType *Tp, ArrayRef< int > Mask, TTI::TargetCostKind CostKind, int Index, VectorType *SubTp, ArrayRef< const Value * > Args)
Returns the cost of the shuffle instructions with the given Kind, vector type Tp and optional Mask.
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
TargetTransformInfo TTI
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:1772
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
Describe known properties for a set of pointers.