LLVM 24.0.0git
SLPTypeUtils.cpp
Go to the documentation of this file.
1//===- SLPTypeUtils.cpp - SLP Vectorizer type/width 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 "SLPTypeUtils.h"
10#include "SLPUtils.h"
11
12#include "llvm/ADT/STLExtras.h"
14#include "llvm/ADT/bit.h"
17#include "llvm/IR/Instruction.h"
19#include "llvm/IR/Type.h"
20#include "llvm/IR/Value.h"
24
25#include <cassert>
26
27using namespace llvm;
28
29namespace llvm::slpvectorizer {
30
31bool isValidElementType(Type *Ty, bool ReVec) {
32 // TODO: Support ScalableVectorType.
33 if (ReVec && isVectorizedTy(Ty) && !getVectorizedTypeVF(Ty).isScalable())
34 Ty = toScalarizedTy(Ty);
35 return canVectorizeTy(Ty) && !Ty->isX86_FP80Ty() && !Ty->isPPC_FP128Ty() &&
36 !Ty->isVoidTy();
37}
38
39Type *getValueType(Value *V, bool ReVec, bool LookThroughCmp) {
40 if (auto *SI = dyn_cast<StoreInst>(V))
41 return SI->getValueOperand()->getType();
42 if (LookThroughCmp)
43 if (auto *CI = dyn_cast<CmpInst>(V))
44 return CI->getOperand(0)->getType();
45 if (!ReVec)
46 if (auto *IE = dyn_cast<InsertElementInst>(V))
47 return IE->getOperand(1)->getType();
48 if (auto *IV = dyn_cast<InsertValueInst>(V))
49 return IV->getOperand(1)->getType();
50 return V->getType();
51}
52
53Type *getWidenedType(Type *ScalarTy, unsigned VF) {
54 if (VF == 1 && !isVectorizedTy(ScalarTy)) {
55 // Workaround for 1 x vector types: toVectorizedTy returns the type
56 // unchanged when EC is scalar, but BoUpSLP relies on widening to
57 // <1 x ScalarTy> (or struct of <1 x ElTy>) to keep the rest of the
58 // pipeline operating on vector types.
59 if (auto *StructTy = dyn_cast<StructType>(ScalarTy)) {
61 "expected unpacked struct literal");
62 assert(all_of(StructTy->elements(), VectorType::isValidElementType) &&
63 "expected all element types to be valid vector element types");
64 return StructType::get(
65 StructTy->getContext(),
66 map_to_vector(StructTy->elements(), [&](Type *ElTy) -> Type * {
67 return FixedVectorType::get(ElTy, 1);
68 }));
69 }
70 return FixedVectorType::get(ScalarTy, 1);
71 }
72 return toVectorizedTy(toScalarizedTy(ScalarTy),
74}
75
77 unsigned Sz, bool ReVec) {
78 if (!isValidElementType(Ty, ReVec) || isa<StructType>(Ty))
79 return bit_ceil(Sz);
80 // Find the number of elements, which forms full vectors.
81 const unsigned NumParts = TTI.getNumberOfParts(getWidenedType(Ty, Sz));
82 if (NumParts == 0 || NumParts >= Sz)
83 return bit_ceil(Sz);
84 return bit_ceil(divideCeil(Sz, NumParts)) * NumParts;
85}
86
88 Type *Ty, unsigned Sz, bool ReVec) {
89 if (!isValidElementType(Ty, ReVec) || isa<StructType>(Ty))
90 return bit_floor(Sz);
91 // Find the number of elements, which forms full vectors.
92 unsigned NumParts = TTI.getNumberOfParts(getWidenedType(Ty, Sz));
93 if (NumParts == 0 || NumParts >= Sz)
94 return bit_floor(Sz);
95 unsigned RegVF = bit_ceil(divideCeil(Sz, NumParts));
96 if (RegVF > Sz)
97 return bit_floor(Sz);
98 return (Sz / RegVF) * RegVF;
99}
100
102 unsigned Opcode, Type *ScalarTy,
103 unsigned NumElts, bool ReVec) {
104 if (!Instruction::isIntDivRem(Opcode) || has_single_bit(NumElts))
105 return nullptr;
106 unsigned PaddedNumElts =
107 getFullVectorNumberOfElements(TTI, ScalarTy, NumElts, ReVec);
108 if (PaddedNumElts == NumElts)
109 return nullptr;
110 return cast<FixedVectorType>(getWidenedType(ScalarTy, PaddedNumElts));
111}
112
114 unsigned Sz, bool ReVec) {
115 if (Sz <= 1)
116 return false;
117 if (!isValidElementType(Ty, ReVec) && !isa<FixedVectorType>(Ty))
118 return false;
119 if (has_single_bit(Sz))
120 return true;
121 if (isa<StructType>(Ty))
122 return false;
123 const unsigned NumParts = TTI.getNumberOfParts(getWidenedType(Ty, Sz));
124 return NumParts > 0 && NumParts < Sz && has_single_bit(Sz / NumParts) &&
125 Sz % NumParts == 0;
126}
127
128} // namespace llvm::slpvectorizer
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains some templates that are useful if you are working with the STL at all.
This file defines less commonly used SmallVector utilities.
This pass exposes codegen information to IR-level passes.
This file implements the C++20 <bit> header.
static const uint32_t IV[8]
Definition blake3_impl.h:83
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:309
Class to represent fixed width SIMD vectors.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:867
bool isIntDivRem() const
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:477
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
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
static LLVM_ABI bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
A private "module" namespace for types and utilities used by this pass.
unsigned getFloorFullVectorNumberOfElements(const TargetTransformInfo &TTI, Type *Ty, unsigned Sz, bool ReVec)
Returns the number of elements of the given type Ty, not greater than Sz, which forms type,...
unsigned getNumElements(Type *Ty)
Definition SLPUtils.cpp:83
Type * getWidenedType(Type *ScalarTy, unsigned VF)
bool hasFullVectorsOrPowerOf2(const TargetTransformInfo &TTI, Type *Ty, unsigned Sz, bool ReVec)
Returns true if widened type of Ty elements with size Sz represents full vector type,...
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...
bool isValidElementType(Type *Ty, bool ReVec)
Predicate for the element types that the SLP vectorizer supports.
Type * getValueType(Value *V, bool ReVec, bool LookThroughCmp)
Returns the "element type" of the given value/instruction V.
unsigned getFullVectorNumberOfElements(const TargetTransformInfo &TTI, Type *Ty, unsigned Sz, bool ReVec)
Returns the number of elements of the given type Ty, not less than Sz, which forms type,...
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
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 isUnpackedStructLiteral(StructType *StructTy)
auto map_to_vector(ContainerTy &&C, FuncTy &&F)
Map a range to a SmallVector with element types deduced from the mapping.
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
constexpr bool has_single_bit(T Value) noexcept
Definition bit.h:149
ElementCount getVectorizedTypeVF(Type *Ty)
Returns the number of vector elements for a vectorized type.
Type * toVectorizedTy(Type *Ty, ElementCount EC)
A helper for converting to vectorized types.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:389
bool canVectorizeTy(Type *Ty)
Returns true if Ty is a valid vector element type, void, or an unpacked literal struct where all elem...
TargetTransformInfo TTI
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347