//===------- VectorTypeUtils.h - Vector type utility functions -*- C++ -*-====// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_IR_VECTORTYPEUTILS_H #define LLVM_IR_VECTORTYPEUTILS_H #include "llvm/IR/DerivedTypes.h" #include "llvm/Support/Compiler.h" namespace llvm { /// A helper function for converting Scalar types to vector types. If /// the incoming type is void, we return void. If the EC represents a /// scalar, we return the scalar type. inline Type *toVectorTy(Type *Scalar, ElementCount EC) { if (Scalar->isVoidTy() || Scalar->isMetadataTy() || EC.isScalar()) return Scalar; return VectorType::get(Scalar, EC); } inline Type *toVectorTy(Type *Scalar, unsigned VF) { return toVectorTy(Scalar, ElementCount::getFixed(VF)); } /// A helper for converting structs of scalar types to structs of vector types. /// Note: /// - If \p EC is scalar, \p StructTy is returned unchanged /// - Only unpacked literal struct types are supported LLVM_ABI Type *toVectorizedStructTy(StructType *StructTy, ElementCount EC); /// A helper for converting structs of vector types to structs of scalar types. /// Note: Only unpacked literal struct types are supported. LLVM_ABI Type *toScalarizedStructTy(StructType *StructTy); /// Returns true if `StructTy` is an unpacked literal struct where all elements /// are vectors of matching element count. This does not include empty structs. LLVM_ABI bool isVectorizedStructTy(StructType *StructTy); /// Returns true if `StructTy` is an unpacked literal struct where all elements /// are scalars that can be used as vector element types. LLVM_ABI bool canVectorizeStructTy(StructType *StructTy); /// A helper for converting to vectorized types. For scalar types, this is /// equivalent to calling `toVectorTy`. For struct types, this returns a new /// struct where each element type has been widened to a vector type. /// Note: /// - If the incoming type is void, we return void /// - If \p EC is scalar, \p Ty is returned unchanged /// - Only unpacked literal struct types are supported inline Type *toVectorizedTy(Type *Ty, ElementCount EC) { if (StructType *StructTy = dyn_cast(Ty)) return toVectorizedStructTy(StructTy, EC); return toVectorTy(Ty, EC); } /// A helper for converting vectorized types to scalarized (non-vector) types. /// For vector types, this is equivalent to calling .getScalarType(). For struct /// types, this returns a new struct where each element type has been converted /// to a scalar type. Note: Only unpacked literal struct types are supported. inline Type *toScalarizedTy(Type *Ty) { if (StructType *StructTy = dyn_cast(Ty)) return toScalarizedStructTy(StructTy); return Ty->getScalarType(); } /// Returns true if `Ty` is a vector type or a struct of vector types where all /// vector types share the same VF. inline bool isVectorizedTy(Type *Ty) { if (StructType *StructTy = dyn_cast(Ty)) return isVectorizedStructTy(StructTy); return Ty->isVectorTy(); } /// Returns true if `Ty` is a valid vector element type, void, or an unpacked /// literal struct where all elements are valid vector element types. /// Note: Even if a type can be vectorized that does not mean it is valid to do /// so in all cases. For example, a vectorized struct (as returned by /// toVectorizedTy) does not perform (de)interleaving, so it can't be used for /// vectorizing loads/stores. inline bool canVectorizeTy(Type *Ty) { if (StructType *StructTy = dyn_cast(Ty)) return canVectorizeStructTy(StructTy); return Ty->isVoidTy() || VectorType::isValidElementType(Ty); } /// Returns the types contained in `Ty`. For struct types, it returns the /// elements, all other types are returned directly. inline ArrayRef getContainedTypes(Type *const &Ty) { if (auto *StructTy = dyn_cast(Ty)) return StructTy->elements(); return ArrayRef(&Ty, 1); } /// Returns the number of vector elements for a vectorized type. inline ElementCount getVectorizedTypeVF(Type *Ty) { assert(isVectorizedTy(Ty) && "expected vectorized type"); return cast(getContainedTypes(Ty).front())->getElementCount(); } inline bool isUnpackedStructLiteral(StructType *StructTy) { return StructTy->isLiteral() && !StructTy->isPacked(); } } // namespace llvm #endif