[PATCH] D125111: [SLP] Make reordering aware of external vectorizable scalar stores.
Valeriy Dmitriev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri May 6 15:02:00 PDT 2022
vdmitrie added inline comments.
================
Comment at: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:4084
+ // it into `ExternalReorderIndices`
+ for (const auto &Pair : PtrToStoresMap) {
+ auto &StoresVec = Pair.second;
----------------
Hi Vasileios.
May I offer you to make some stylistic changes to this method to improve code readability?
I was bit lazy to place all comments inline - sorry for that :). It was much easier for me to just apply your patch and use editor locally. So I'm only putting summary here:
- reduce abuse of "auto"
- do not create thin lambdas just for minor reducing amount of code.
- improve Cmp to not call getPointerDiff if we already failed once
- added type check to Cmp before querying for diff (although I'm not sure whether we can have different store types here)
- inline Cmp into the call for stable_sort
- inline stable_sort into CanFormVector
- outline CanFromVector outside the loop
- I'm not sure we need to look at each store to find out whether they are all sequential.
We probably can take diff between the first and the last ones.
- use range loop for sequential index traversing
After applying all these suggestions here is how the method could possibly look:
SmallVector<BoUpSLP::OrdersType, 1>
BoUpSLP::findExternalStoreUsersReorderIndices(TreeEntry *TE) const {
unsigned NumLanes = TE->Scalars.size();
DenseMap<Value *, SmallVector<StoreInst *, 4>> PtrToStoresMap =
collectUserStores(TE);
// Holds the reorder indices for each candidate store vector that is a user of
// the current TreeEntry.
SmallVector<OrdersType, 1> ExternalReorderIndices;
// \Returns true if the stores in `SortedStoresVec` are consecutive and can
// form a vector.
auto &&CanFormVector = [this](SmallVector<StoreInst *, 4> &StoresVecSorted) {
Type *Ty = StoresVecSorted.front()->getValueOperand()->getType();
bool FailedToSort = false;
stable_sort(StoresVecSorted, [this, &FailedToSort, Ty](StoreInst *S1,
StoreInst *S2) {
if (FailedToSort)
return false;
if (S1->getValueOperand()->getType() != Ty ||
S2->getValueOperand()->getType() != Ty) {
FailedToSort = true;
return false;
}
Optional<int> Diff = getPointersDiff(Ty, S2->getPointerOperand(), Ty,
S1->getPointerOperand(), *DL, *SE,
/*StrictCheck=*/true);
if (!Diff) {
FailedToSort = true;
return false;
}
return Diff < 0;
});
// If we failed to compare stores, then just abandon this stores vector.
if (FailedToSort)
return false;
Optional<int> Range =
getPointersDiff(Ty, StoresVecSorted.front()->getPointerOperand(), Ty,
StoresVecSorted.back()->getPointerOperand(), *DL, *SE,
/*StrictCheck=*/true);
return *Range == (int)StoresVecSorted.size() - 1;
};
// Now inspect the stores collected per pointer and look for vectorization
// candidates. For each candidate calculate the reorder index vector and push
// it into `ExternalReorderIndices`
for (const auto &Pair : PtrToStoresMap) {
const SmallVector<StoreInst *, 4> &StoresVec = Pair.second;
// If we have fewer than NumLanes stores, then we can't form a vector.
if (StoresVec.size() != NumLanes)
continue;
// Sort the vector based on the pointers. We create a copy because we may
// need the original later for calculating the reorder (shuffle) indices.
auto StoresVecSorted = StoresVec;
// If the stores are not consecutive then abandon this sotres vector.
if (!CanFormVector(StoresVecSorted))
continue;
// The scalars in StoresVec can form a vector instruction, so calculate the
// shuffle indices.
ExternalReorderIndices.resize(ExternalReorderIndices.size() + 1);
OrdersType &ReorderIndices = ExternalReorderIndices.back();
for (StoreInst *SI : StoresVec) {
unsigned Idx = llvm::find(StoresVecSorted, SI) - StoresVecSorted.begin();
ReorderIndices.push_back(Idx);
}
// Identity order (e.g., {0,1,2,3}) is modeled as an empty OrdersType in
// reorderTopToBottom() and reorderBottomToTop(), so we are following the
// same convention here.
auto IsIdentityOrder = [](const OrdersType &Order) {
for (unsigned Idx : seq<unsigned>(0, Order.size()))
if (Idx != Order[Idx])
return false;
return true;
};
if (IsIdentityOrder(ReorderIndices))
ReorderIndices.clear();
}
return ExternalReorderIndices;
}
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D125111/new/
https://reviews.llvm.org/D125111
More information about the llvm-commits
mailing list