xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/VectorTypeUtils.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===------- VectorTypeUtils.h - Vector type utility functions -*- C++ -*-====//
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 #ifndef LLVM_IR_VECTORTYPEUTILS_H
10 #define LLVM_IR_VECTORTYPEUTILS_H
11 
12 #include "llvm/IR/DerivedTypes.h"
13 #include "llvm/Support/Compiler.h"
14 
15 namespace llvm {
16 
17 /// A helper function for converting Scalar types to vector types. If
18 /// the incoming type is void, we return void. If the EC represents a
19 /// scalar, we return the scalar type.
toVectorTy(Type * Scalar,ElementCount EC)20 inline Type *toVectorTy(Type *Scalar, ElementCount EC) {
21   if (Scalar->isVoidTy() || Scalar->isMetadataTy() || EC.isScalar())
22     return Scalar;
23   return VectorType::get(Scalar, EC);
24 }
25 
toVectorTy(Type * Scalar,unsigned VF)26 inline Type *toVectorTy(Type *Scalar, unsigned VF) {
27   return toVectorTy(Scalar, ElementCount::getFixed(VF));
28 }
29 
30 /// A helper for converting structs of scalar types to structs of vector types.
31 /// Note:
32 ///   - If \p EC is scalar, \p StructTy is returned unchanged
33 ///   - Only unpacked literal struct types are supported
34 LLVM_ABI Type *toVectorizedStructTy(StructType *StructTy, ElementCount EC);
35 
36 /// A helper for converting structs of vector types to structs of scalar types.
37 /// Note: Only unpacked literal struct types are supported.
38 LLVM_ABI Type *toScalarizedStructTy(StructType *StructTy);
39 
40 /// Returns true if `StructTy` is an unpacked literal struct where all elements
41 /// are vectors of matching element count. This does not include empty structs.
42 LLVM_ABI bool isVectorizedStructTy(StructType *StructTy);
43 
44 /// Returns true if `StructTy` is an unpacked literal struct where all elements
45 /// are scalars that can be used as vector element types.
46 LLVM_ABI bool canVectorizeStructTy(StructType *StructTy);
47 
48 /// A helper for converting to vectorized types. For scalar types, this is
49 /// equivalent to calling `toVectorTy`. For struct types, this returns a new
50 /// struct where each element type has been widened to a vector type.
51 /// Note:
52 ///   - If the incoming type is void, we return void
53 ///   - If \p EC is scalar, \p Ty is returned unchanged
54 ///   - Only unpacked literal struct types are supported
toVectorizedTy(Type * Ty,ElementCount EC)55 inline Type *toVectorizedTy(Type *Ty, ElementCount EC) {
56   if (StructType *StructTy = dyn_cast<StructType>(Ty))
57     return toVectorizedStructTy(StructTy, EC);
58   return toVectorTy(Ty, EC);
59 }
60 
61 /// A helper for converting vectorized types to scalarized (non-vector) types.
62 /// For vector types, this is equivalent to calling .getScalarType(). For struct
63 /// types, this returns a new struct where each element type has been converted
64 /// to a scalar type. Note: Only unpacked literal struct types are supported.
toScalarizedTy(Type * Ty)65 inline Type *toScalarizedTy(Type *Ty) {
66   if (StructType *StructTy = dyn_cast<StructType>(Ty))
67     return toScalarizedStructTy(StructTy);
68   return Ty->getScalarType();
69 }
70 
71 /// Returns true if `Ty` is a vector type or a struct of vector types where all
72 /// vector types share the same VF.
isVectorizedTy(Type * Ty)73 inline bool isVectorizedTy(Type *Ty) {
74   if (StructType *StructTy = dyn_cast<StructType>(Ty))
75     return isVectorizedStructTy(StructTy);
76   return Ty->isVectorTy();
77 }
78 
79 /// Returns true if `Ty` is a valid vector element type, void, or an unpacked
80 /// literal struct where all elements are valid vector element types.
81 /// Note: Even if a type can be vectorized that does not mean it is valid to do
82 /// so in all cases. For example, a vectorized struct (as returned by
83 /// toVectorizedTy) does not perform (de)interleaving, so it can't be used for
84 /// vectorizing loads/stores.
canVectorizeTy(Type * Ty)85 inline bool canVectorizeTy(Type *Ty) {
86   if (StructType *StructTy = dyn_cast<StructType>(Ty))
87     return canVectorizeStructTy(StructTy);
88   return Ty->isVoidTy() || VectorType::isValidElementType(Ty);
89 }
90 
91 /// Returns the types contained in `Ty`. For struct types, it returns the
92 /// elements, all other types are returned directly.
getContainedTypes(Type * const & Ty)93 inline ArrayRef<Type *> getContainedTypes(Type *const &Ty) {
94   if (auto *StructTy = dyn_cast<StructType>(Ty))
95     return StructTy->elements();
96   return ArrayRef<Type *>(&Ty, 1);
97 }
98 
99 /// Returns the number of vector elements for a vectorized type.
getVectorizedTypeVF(Type * Ty)100 inline ElementCount getVectorizedTypeVF(Type *Ty) {
101   assert(isVectorizedTy(Ty) && "expected vectorized type");
102   return cast<VectorType>(getContainedTypes(Ty).front())->getElementCount();
103 }
104 
isUnpackedStructLiteral(StructType * StructTy)105 inline bool isUnpackedStructLiteral(StructType *StructTy) {
106   return StructTy->isLiteral() && !StructTy->isPacked();
107 }
108 
109 } // namespace llvm
110 
111 #endif
112