-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SLP] Extract isIdentityOrder to common routine [probably NFC] #106582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This isn't quite just code motion as the four different versions we had of this routine differed in whether they ignored the "size" marker used to represent undef. I doubt this matters in practice, but it is a functional change.
@llvm/pr-subscribers-llvm-transforms Author: Philip Reames (preames) ChangesThis isn't quite just code motion as the four different versions we had of this routine differed in whether they ignored the "size" marker used to represent undef. I doubt this matters in practice, but it is a functional change. Full diff: https://github.com/llvm/llvm-project/pull/106582.diff 1 Files Affected:
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 81811e0a4d9295..e2882b3d595351 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -1364,6 +1364,19 @@ class BoUpSLP {
/// Perform LICM and CSE on the newly generated gather sequences.
void optimizeGatherSequence();
+ /// Does this non-empty order represent an identity order? Identity
+ /// should be represented as an empty order, so this is used to
+ /// decide if we can canonicalize a computed order. Undef elements
+ /// (represented as size) are ignored.
+ bool IsIdentityOrder(ArrayRef<unsigned> Order) const {
+ assert(!Order.empty());
+ const unsigned Sz = Order.size();
+ for (unsigned Idx : seq<unsigned>(0, Sz))
+ if (Idx != Order[Idx] && Order[Idx] != Sz)
+ return false;
+ return true;
+ }
+
/// Checks if the specified gather tree entry \p TE can be represented as a
/// shuffled vector entry + (possibly) permutation with other gathers. It
/// implements the checks only for possibly ordered scalars (Loads,
@@ -5256,12 +5269,6 @@ BoUpSLP::getReorderingData(const TreeEntry &TE, bool TopToBottom) {
}
return I1 < I2;
};
- auto IsIdentityOrder = [](const OrdersType &Order) {
- for (unsigned Idx : seq<unsigned>(0, Order.size()))
- if (Idx != Order[Idx])
- return false;
- return true;
- };
DenseMap<unsigned, unsigned> PhiToId;
SmallVector<unsigned> Phis(TE.Scalars.size());
std::iota(Phis.begin(), Phis.end(), 0);
@@ -5565,13 +5572,6 @@ void BoUpSLP::reorderTopToBottom() {
}
if (OrdersUses.empty())
continue;
- auto IsIdentityOrder = [](ArrayRef<unsigned> Order) {
- const unsigned Sz = Order.size();
- for (unsigned Idx : seq<unsigned>(0, Sz))
- if (Idx != Order[Idx] && Order[Idx] != Sz)
- return false;
- return true;
- };
// Choose the most used order.
unsigned IdentityCnt = 0;
unsigned FilledIdentityCnt = 0;
@@ -5891,13 +5891,6 @@ void BoUpSLP::reorderBottomToTop(bool IgnoreReorder) {
OrderedEntries.remove(Op.second);
continue;
}
- auto IsIdentityOrder = [](ArrayRef<unsigned> Order) {
- const unsigned Sz = Order.size();
- for (unsigned Idx : seq<unsigned>(0, Sz))
- if (Idx != Order[Idx] && Order[Idx] != Sz)
- return false;
- return true;
- };
// Choose the most used order.
unsigned IdentityCnt = 0;
unsigned VF = Data.second.front().second->getVectorFactor();
@@ -6186,12 +6179,6 @@ bool BoUpSLP::canFormVector(ArrayRef<StoreInst *> StoresVec,
// 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();
|
/// Does this non-empty order represent an identity order? Identity | ||
/// should be represented as an empty order, so this is used to | ||
/// decide if we can canonicalize a computed order. Undef elements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand the description. Why it is empty order?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just describing the behavior of the existing code. We use an empty order to represent no reordering - i.e. the identity order. We use this routine to check if a computed order is identity, and can thus be replaced with an empty one. If you have a preferred wording here, please suggest it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see
Co-authored-by: Alexey Bataev <[email protected]>
This isn't quite just code motion as the four different versions we had of this routine differed in whether they ignored the "size" marker used to represent undef. I doubt this matters in practice, but it is a functional change.