LLVM 23.0.0git
SLPUtils.cpp
Go to the documentation of this file.
1//===- SLPUtils.cpp - SLP Vectorizer free utility 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 "SLPUtils.h"
10
11#include "llvm/ADT/STLExtras.h"
13#include "llvm/IR/Constants.h"
18
19#include <type_traits>
20
21using namespace llvm;
22
23namespace llvm::slpvectorizer {
24
28
32 return false;
33 auto *I = dyn_cast<Instruction>(V);
34 if (!I || isa<ExtractValueInst>(I))
35 return true;
37 return isa<FixedVectorType>(I->getOperand(0)->getType()) &&
38 isConstant(I->getOperand(1));
40 return isa<FixedVectorType>(I->getOperand(0)->getType()) &&
41 isConstant(I->getOperand(2));
42 assert(isa<InsertValueInst>(I) && "Expected InsertValueInst");
43 return true;
44}
45
46unsigned getNumElements(Type *Ty) {
48 "ScalableVectorType is not supported.");
49 if (isVectorizedTy(Ty))
51 return 1;
52}
53
54unsigned getPartNumElems(unsigned Size, unsigned NumParts) {
55 return std::min<unsigned>(Size, bit_ceil(divideCeil(Size, NumParts)));
56}
57
58unsigned getNumElems(unsigned Size, unsigned PartNumElems, unsigned Part) {
59 return std::min<unsigned>(PartNumElems, Size - Part * PartNumElems);
60}
61
63 auto *It = find_if(VL, IsaPred<Instruction>);
64 if (It == VL.end())
65 return false;
68 return true;
69
70 BasicBlock *BB = I0->getParent();
71 for (Value *V : iterator_range(It, VL.end())) {
72 if (isa<PoisonValue>(V))
73 continue;
74 auto *II = dyn_cast<Instruction>(V);
75 if (!II)
76 return false;
77
78 if (BB != II->getParent())
79 return false;
80 }
81 return true;
82}
83
85 // Constant expressions and globals can't be vectorized like normal integer/FP
86 // constants.
87 return all_of(VL, isConstant);
88}
89
91 Value *FirstNonUndef = nullptr;
92 for (Value *V : VL) {
93 if (isa<UndefValue>(V))
94 continue;
95 if (!FirstNonUndef) {
96 FirstNonUndef = V;
97 continue;
98 }
99 if (V != FirstNonUndef)
100 return false;
101 }
102 return FirstNonUndef != nullptr;
103}
104
106 auto *It = find_if(VL, IsaPred<Instruction>);
107 if (It == VL.end())
108 return true;
109 Instruction *MainOp = cast<Instruction>(*It);
110 unsigned Opcode = MainOp->getOpcode();
111 bool IsCmpOp = isa<CmpInst>(MainOp);
112 CmpInst::Predicate BasePred = IsCmpOp ? cast<CmpInst>(MainOp)->getPredicate()
114 return std::all_of(It, VL.end(), [&](Value *V) {
115 if (auto *CI = dyn_cast<CmpInst>(V))
116 return BasePred == CI->getPredicate();
117 if (auto *I = dyn_cast<Instruction>(V))
118 return I->getOpcode() == Opcode;
119 return isa<PoisonValue>(V);
120 });
121}
122
123std::optional<unsigned> getExtractIndex(const Instruction *E) {
124 unsigned Opcode = E->getOpcode();
125 assert((Opcode == Instruction::ExtractElement ||
126 Opcode == Instruction::ExtractValue) &&
127 "Expected extractelement or extractvalue instruction.");
128 if (Opcode == Instruction::ExtractElement) {
129 auto *CI = dyn_cast<ConstantInt>(E->getOperand(1));
130 if (!CI)
131 return std::nullopt;
132 // Check if the index is out of bound. We can get the source vector from
133 // operand 0.
134 unsigned Idx = CI->getZExtValue();
135 auto *EE = cast<ExtractElementInst>(E);
136 const unsigned VF = getNumElements(EE->getVectorOperandType());
137 if (Idx >= VF)
138 return std::nullopt;
139 return Idx;
140 }
141 auto *EI = cast<ExtractValueInst>(E);
142 if (EI->getNumIndices() != 1)
143 return std::nullopt;
144 return *EI->idx_begin();
145}
146
148 Type *Ty = VL.consume_front()->getType();
149 return all_of(VL, [&](Value *V) { return V->getType() == Ty; });
150}
151
152template <typename T>
153std::optional<unsigned> getInsertExtractIndex(const Value *Inst,
154 unsigned Offset) {
155 static_assert(std::is_same_v<T, InsertElementInst> ||
156 std::is_same_v<T, ExtractElementInst>,
157 "unsupported T");
158 const auto *IE = dyn_cast<T>(Inst);
159 if (!IE)
160 return std::nullopt;
161 // InsertElement: result is the vector, index is op 2.
162 // ExtractElement: result is scalar, vector is op 0, index is op 1.
163 constexpr bool IsInsert = std::is_same_v<T, InsertElementInst>;
164 Type *VecTy = IsInsert ? IE->getType() : IE->getOperand(0)->getType();
165 const auto *VT = dyn_cast<FixedVectorType>(VecTy);
166 if (!VT)
167 return std::nullopt;
168 const auto *CI = dyn_cast<ConstantInt>(IE->getOperand(IsInsert ? 2 : 1));
169 if (!CI)
170 return std::nullopt;
171 if (CI->getValue().uge(VT->getNumElements()))
172 return std::nullopt;
173 unsigned Index = Offset;
174 Index *= VT->getNumElements();
175 Index += CI->getZExtValue();
176 return Index;
177}
178
179// Only these two specializations are used; instantiate them here so the
180// definition can stay out of the header.
181template std::optional<unsigned>
183template std::optional<unsigned>
185
186} // namespace llvm::slpvectorizer
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
This file contains some templates that are useful if you are working with the STL at all.
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
const T & consume_front()
consume_front() - Returns the first element and drops it from ArrayRef.
Definition ArrayRef.h:156
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
const ParentTy * getParent() const
Definition ilist_node.h:34
A private "module" namespace for types and utilities used by this pass.
std::optional< unsigned > getExtractIndex(const Instruction *E)
Definition SLPUtils.cpp:123
std::optional< unsigned > getInsertExtractIndex(const Value *Inst, unsigned Offset)
Definition SLPUtils.cpp:153
bool allSameType(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:147
bool allSameOpcode(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:105
bool isSplat(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:90
unsigned getNumElements(Type *Ty)
Definition SLPUtils.cpp:46
unsigned getPartNumElems(unsigned Size, unsigned NumParts)
Returns power-of-2 number of elements in a single register (part), given the total number of elements...
Definition SLPUtils.cpp:54
bool allConstant(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:84
template std::optional< unsigned > getInsertExtractIndex< InsertElementInst >(const Value *, unsigned)
bool allSameBlock(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:62
bool isVectorLikeInstWithConstOps(Value *V)
Checks if V is one of vector-like instructions, i.e.
Definition SLPUtils.cpp:29
unsigned getNumElems(unsigned Size, unsigned PartNumElems, unsigned Part)
Returns correct remaining number of elements, considering total amount Size, (power-of-2 number) of e...
Definition SLPUtils.cpp:58
bool isConstant(Value *V)
Definition SLPUtils.cpp:25
template std::optional< unsigned > getInsertExtractIndex< ExtractElementInst >(const Value *, unsigned)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:573
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
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...
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Definition bit.h:362
ElementCount getVectorizedTypeVF(Type *Ty)
Returns the number of vector elements for a vectorized type.
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
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:394
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