Skip to content

Commit 3cf23f7

Browse files
vangthao95zhang2amd
authored andcommitted
[SROA] Try harder to find a vector promotion viable type when rewriting
We are seeing significant performance loss when an alloca fails to get promoted to register. I have observed that this is due to the common type found when attempting to rewrite partition users being unviable for promotion. While if we would have continue looking for a type, we would have found a subtype in the original allocated type that would have enabled promotion. Thus first check if the initial common type found is promotion viable and if not then continue looking instead of stopping with the initial common type found. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D128073 Change-Id: I71cb958abec6c64b1689c813037f8aed4709d2b5
1 parent 52890b5 commit 3cf23f7

File tree

2 files changed

+462
-27
lines changed

2 files changed

+462
-27
lines changed

llvm/lib/Transforms/Scalar/SROA.cpp

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,34 @@ static bool isVectorPromotionViableForSlice(Partition &P, const Slice &S,
18471847
return true;
18481848
}
18491849

1850+
/// Test whether a vector type is viable for promotion.
1851+
///
1852+
/// This implements the necessary checking for \c isVectorPromotionViable over
1853+
/// all slices of the alloca for the given VectorType.
1854+
static bool checkVectorTypeForPromotion(Partition &P, VectorType *VTy,
1855+
const DataLayout &DL) {
1856+
uint64_t ElementSize =
1857+
DL.getTypeSizeInBits(VTy->getElementType()).getFixedSize();
1858+
1859+
// While the definition of LLVM vectors is bitpacked, we don't support sizes
1860+
// that aren't byte sized.
1861+
if (ElementSize % 8)
1862+
return false;
1863+
assert((DL.getTypeSizeInBits(VTy).getFixedSize() % 8) == 0 &&
1864+
"vector size not a multiple of element size?");
1865+
ElementSize /= 8;
1866+
1867+
for (const Slice &S : P)
1868+
if (!isVectorPromotionViableForSlice(P, S, VTy, ElementSize, DL))
1869+
return false;
1870+
1871+
for (const Slice *S : P.splitSliceTails())
1872+
if (!isVectorPromotionViableForSlice(P, *S, VTy, ElementSize, DL))
1873+
return false;
1874+
1875+
return true;
1876+
}
1877+
18501878
/// Test whether the given alloca partitioning and range of slices can be
18511879
/// promoted to a vector.
18521880
///
@@ -1939,31 +1967,8 @@ static VectorType *isVectorPromotionViable(Partition &P, const DataLayout &DL) {
19391967
CandidateTys.resize(1);
19401968
}
19411969

1942-
// Try each vector type, and return the one which works.
1943-
auto CheckVectorTypeForPromotion = [&](VectorType *VTy) {
1944-
uint64_t ElementSize =
1945-
DL.getTypeSizeInBits(VTy->getElementType()).getFixedSize();
1946-
1947-
// While the definition of LLVM vectors is bitpacked, we don't support sizes
1948-
// that aren't byte sized.
1949-
if (ElementSize % 8)
1950-
return false;
1951-
assert((DL.getTypeSizeInBits(VTy).getFixedSize() % 8) == 0 &&
1952-
"vector size not a multiple of element size?");
1953-
ElementSize /= 8;
1954-
1955-
for (const Slice &S : P)
1956-
if (!isVectorPromotionViableForSlice(P, S, VTy, ElementSize, DL))
1957-
return false;
1958-
1959-
for (const Slice *S : P.splitSliceTails())
1960-
if (!isVectorPromotionViableForSlice(P, *S, VTy, ElementSize, DL))
1961-
return false;
1962-
1963-
return true;
1964-
};
19651970
for (VectorType *VTy : CandidateTys)
1966-
if (CheckVectorTypeForPromotion(VTy))
1971+
if (checkVectorTypeForPromotion(P, VTy, DL))
19671972
return VTy;
19681973

19691974
return nullptr;
@@ -4246,26 +4251,45 @@ AllocaInst *SROAPass::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
42464251
// won't always succeed, in which case we fall back to a legal integer type
42474252
// or an i8 array of an appropriate size.
42484253
Type *SliceTy = nullptr;
4254+
VectorType *SliceVecTy = nullptr;
42494255
const DataLayout &DL = AI.getModule()->getDataLayout();
42504256
std::pair<Type *, IntegerType *> CommonUseTy =
42514257
findCommonType(P.begin(), P.end(), P.endOffset());
42524258
// Do all uses operate on the same type?
42534259
if (CommonUseTy.first)
4254-
if (DL.getTypeAllocSize(CommonUseTy.first).getFixedSize() >= P.size())
4260+
if (DL.getTypeAllocSize(CommonUseTy.first).getFixedSize() >= P.size()) {
42554261
SliceTy = CommonUseTy.first;
4262+
SliceVecTy = dyn_cast<VectorType>(SliceTy);
4263+
}
42564264
// If not, can we find an appropriate subtype in the original allocated type?
42574265
if (!SliceTy)
42584266
if (Type *TypePartitionTy = getTypePartition(DL, AI.getAllocatedType(),
42594267
P.beginOffset(), P.size()))
42604268
SliceTy = TypePartitionTy;
4269+
42614270
// If still not, can we use the largest bitwidth integer type used?
42624271
if (!SliceTy && CommonUseTy.second)
4263-
if (DL.getTypeAllocSize(CommonUseTy.second).getFixedSize() >= P.size())
4272+
if (DL.getTypeAllocSize(CommonUseTy.second).getFixedSize() >= P.size()) {
42644273
SliceTy = CommonUseTy.second;
4274+
SliceVecTy = dyn_cast<VectorType>(SliceTy);
4275+
}
42654276
if ((!SliceTy || (SliceTy->isArrayTy() &&
42664277
SliceTy->getArrayElementType()->isIntegerTy())) &&
4267-
DL.isLegalInteger(P.size() * 8))
4278+
DL.isLegalInteger(P.size() * 8)) {
42684279
SliceTy = Type::getIntNTy(*C, P.size() * 8);
4280+
}
4281+
4282+
// If the common use types are not viable for promotion then attempt to find
4283+
// another type that is viable.
4284+
if (SliceVecTy && !checkVectorTypeForPromotion(P, SliceVecTy, DL))
4285+
if (Type *TypePartitionTy = getTypePartition(DL, AI.getAllocatedType(),
4286+
P.beginOffset(), P.size())) {
4287+
VectorType *TypePartitionVecTy = dyn_cast<VectorType>(TypePartitionTy);
4288+
if (TypePartitionVecTy &&
4289+
checkVectorTypeForPromotion(P, TypePartitionVecTy, DL))
4290+
SliceTy = TypePartitionTy;
4291+
}
4292+
42694293
if (!SliceTy)
42704294
SliceTy = ArrayType::get(Type::getInt8Ty(*C), P.size());
42714295
assert(DL.getTypeAllocSize(SliceTy).getFixedSize() >= P.size());

0 commit comments

Comments
 (0)