diff options
author | Jeffrey Byrnes <Jeffrey.Byrnes@amd.com> | 2024-01-12 09:00:08 -0800 |
---|---|---|
committer | Jeffrey Byrnes <Jeffrey.Byrnes@amd.com> | 2024-01-23 15:40:20 -0800 |
commit | 2a61be4e4ca481016516403f634b475197221991 (patch) | |
tree | 1f2f9196fb6bc42cba8d7c94a899fac62168e029 | |
parent | 6a3ace20c80191159009668fff82fc3feeeca0a6 (diff) |
[SROA] NFC: Extract code to checkVectorTypesForPromotion
Change-Id: Ib6f237cc791a097f8f2411bc1d6502f11d4a748e
-rw-r--r-- | llvm/lib/Transforms/Scalar/SROA.cpp | 181 |
1 files changed, 99 insertions, 82 deletions
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index 551a37b13244..10c25e2a0322 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -2138,8 +2138,9 @@ static bool isVectorPromotionViableForSlice(Partition &P, const Slice &S, /// Test whether a vector type is viable for promotion. /// -/// This implements the necessary checking for \c isVectorPromotionViable over -/// all slices of the alloca for the given VectorType. +/// This implements the necessary checking for \c checkVectorTypesForPromotion +/// (and thus isVectorPromotionViable) over all slices of the alloca for the +/// given VectorType. static bool checkVectorTypeForPromotion(Partition &P, VectorType *VTy, const DataLayout &DL) { uint64_t ElementSize = @@ -2164,6 +2165,98 @@ static bool checkVectorTypeForPromotion(Partition &P, VectorType *VTy, return true; } +/// Test whether any vector type in \p CandidateTys is viable for promotion. +/// +/// This implements the necessary checking for \c isVectorPromotionViable over +/// all slices of the alloca for the given VectorType. +static VectorType * +checkVectorTypesForPromotion(Partition &P, const DataLayout &DL, + SmallVectorImpl<VectorType *> &CandidateTys, + bool HaveCommonEltTy, Type *CommonEltTy, + bool HaveVecPtrTy, bool HaveCommonVecPtrTy, + VectorType *CommonVecPtrTy) { + // If we didn't find a vector type, nothing to do here. + if (CandidateTys.empty()) + return nullptr; + + // Pointer-ness is sticky, if we had a vector-of-pointers candidate type, + // then we should choose it, not some other alternative. + // But, we can't perform a no-op pointer address space change via bitcast, + // so if we didn't have a common pointer element type, bail. + if (HaveVecPtrTy && !HaveCommonVecPtrTy) + return nullptr; + + // Try to pick the "best" element type out of the choices. + if (!HaveCommonEltTy && HaveVecPtrTy) { + // If there was a pointer element type, there's really only one choice. + CandidateTys.clear(); + CandidateTys.push_back(CommonVecPtrTy); + } else if (!HaveCommonEltTy && !HaveVecPtrTy) { + // Integer-ify vector types. + for (VectorType *&VTy : CandidateTys) { + if (!VTy->getElementType()->isIntegerTy()) + VTy = cast<VectorType>(VTy->getWithNewType(IntegerType::getIntNTy( + VTy->getContext(), VTy->getScalarSizeInBits()))); + } + + // Rank the remaining candidate vector types. This is easy because we know + // they're all integer vectors. We sort by ascending number of elements. + auto RankVectorTypesComp = [&DL](VectorType *RHSTy, VectorType *LHSTy) { + (void)DL; + assert(DL.getTypeSizeInBits(RHSTy).getFixedValue() == + DL.getTypeSizeInBits(LHSTy).getFixedValue() && + "Cannot have vector types of different sizes!"); + assert(RHSTy->getElementType()->isIntegerTy() && + "All non-integer types eliminated!"); + assert(LHSTy->getElementType()->isIntegerTy() && + "All non-integer types eliminated!"); + return cast<FixedVectorType>(RHSTy)->getNumElements() < + cast<FixedVectorType>(LHSTy)->getNumElements(); + }; + auto RankVectorTypesEq = [&DL](VectorType *RHSTy, VectorType *LHSTy) { + (void)DL; + assert(DL.getTypeSizeInBits(RHSTy).getFixedValue() == + DL.getTypeSizeInBits(LHSTy).getFixedValue() && + "Cannot have vector types of different sizes!"); + assert(RHSTy->getElementType()->isIntegerTy() && + "All non-integer types eliminated!"); + assert(LHSTy->getElementType()->isIntegerTy() && + "All non-integer types eliminated!"); + return cast<FixedVectorType>(RHSTy)->getNumElements() == + cast<FixedVectorType>(LHSTy)->getNumElements(); + }; + llvm::sort(CandidateTys, RankVectorTypesComp); + CandidateTys.erase(std::unique(CandidateTys.begin(), CandidateTys.end(), + RankVectorTypesEq), + CandidateTys.end()); + } else { +// The only way to have the same element type in every vector type is to +// have the same vector type. Check that and remove all but one. +#ifndef NDEBUG + for (VectorType *VTy : CandidateTys) { + assert(VTy->getElementType() == CommonEltTy && + "Unaccounted for element type!"); + assert(VTy == CandidateTys[0] && + "Different vector types with the same element type!"); + } +#endif + CandidateTys.resize(1); + } + + // FIXME: hack. Do we have a named constant for this? + // SDAG SDNode can't have more than 65535 operands. + llvm::erase_if(CandidateTys, [](VectorType *VTy) { + return cast<FixedVectorType>(VTy)->getNumElements() > + std::numeric_limits<unsigned short>::max(); + }); + + for (VectorType *VTy : CandidateTys) + if (checkVectorTypeForPromotion(P, VTy, DL)) + return VTy; + + return nullptr; +} + /// Test whether the given alloca partitioning and range of slices can be /// promoted to a vector. /// @@ -2211,6 +2304,7 @@ static VectorType *isVectorPromotionViable(Partition &P, const DataLayout &DL) { } } }; + // Put load and store types into a set for de-duplication. for (const Slice &S : P) { Type *Ty; @@ -2246,86 +2340,9 @@ static VectorType *isVectorPromotionViable(Partition &P, const DataLayout &DL) { } } - // If we didn't find a vector type, nothing to do here. - if (CandidateTys.empty()) - return nullptr; - - // Pointer-ness is sticky, if we had a vector-of-pointers candidate type, - // then we should choose it, not some other alternative. - // But, we can't perform a no-op pointer address space change via bitcast, - // so if we didn't have a common pointer element type, bail. - if (HaveVecPtrTy && !HaveCommonVecPtrTy) - return nullptr; - - // Try to pick the "best" element type out of the choices. - if (!HaveCommonEltTy && HaveVecPtrTy) { - // If there was a pointer element type, there's really only one choice. - CandidateTys.clear(); - CandidateTys.push_back(CommonVecPtrTy); - } else if (!HaveCommonEltTy && !HaveVecPtrTy) { - // Integer-ify vector types. - for (VectorType *&VTy : CandidateTys) { - if (!VTy->getElementType()->isIntegerTy()) - VTy = cast<VectorType>(VTy->getWithNewType(IntegerType::getIntNTy( - VTy->getContext(), VTy->getScalarSizeInBits()))); - } - - // Rank the remaining candidate vector types. This is easy because we know - // they're all integer vectors. We sort by ascending number of elements. - auto RankVectorTypesComp = [&DL](VectorType *RHSTy, VectorType *LHSTy) { - (void)DL; - assert(DL.getTypeSizeInBits(RHSTy).getFixedValue() == - DL.getTypeSizeInBits(LHSTy).getFixedValue() && - "Cannot have vector types of different sizes!"); - assert(RHSTy->getElementType()->isIntegerTy() && - "All non-integer types eliminated!"); - assert(LHSTy->getElementType()->isIntegerTy() && - "All non-integer types eliminated!"); - return cast<FixedVectorType>(RHSTy)->getNumElements() < - cast<FixedVectorType>(LHSTy)->getNumElements(); - }; - auto RankVectorTypesEq = [&DL](VectorType *RHSTy, VectorType *LHSTy) { - (void)DL; - assert(DL.getTypeSizeInBits(RHSTy).getFixedValue() == - DL.getTypeSizeInBits(LHSTy).getFixedValue() && - "Cannot have vector types of different sizes!"); - assert(RHSTy->getElementType()->isIntegerTy() && - "All non-integer types eliminated!"); - assert(LHSTy->getElementType()->isIntegerTy() && - "All non-integer types eliminated!"); - return cast<FixedVectorType>(RHSTy)->getNumElements() == - cast<FixedVectorType>(LHSTy)->getNumElements(); - }; - llvm::sort(CandidateTys, RankVectorTypesComp); - CandidateTys.erase(std::unique(CandidateTys.begin(), CandidateTys.end(), - RankVectorTypesEq), - CandidateTys.end()); - } else { -// The only way to have the same element type in every vector type is to -// have the same vector type. Check that and remove all but one. -#ifndef NDEBUG - for (VectorType *VTy : CandidateTys) { - assert(VTy->getElementType() == CommonEltTy && - "Unaccounted for element type!"); - assert(VTy == CandidateTys[0] && - "Different vector types with the same element type!"); - } -#endif - CandidateTys.resize(1); - } - - // FIXME: hack. Do we have a named constant for this? - // SDAG SDNode can't have more than 65535 operands. - llvm::erase_if(CandidateTys, [](VectorType *VTy) { - return cast<FixedVectorType>(VTy)->getNumElements() > - std::numeric_limits<unsigned short>::max(); - }); - - for (VectorType *VTy : CandidateTys) - if (checkVectorTypeForPromotion(P, VTy, DL)) - return VTy; - - return nullptr; + return checkVectorTypesForPromotion(P, DL, CandidateTys, HaveCommonEltTy, + CommonEltTy, HaveVecPtrTy, + HaveCommonVecPtrTy, CommonVecPtrTy); } /// Test whether a slice of an alloca is valid for integer widening. |