Skip to content

Commit 4bc7c74

Browse files
[SLP] Extract isIdentityOrder to common routine [probably NFC] (llvm#106582)
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. --------- Co-authored-by: Alexey Bataev <[email protected]>
1 parent 9a58b12 commit 4bc7c74

File tree

1 file changed

+19
-33
lines changed

1 file changed

+19
-33
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,18 @@ class BoUpSLP {
13641364
/// Perform LICM and CSE on the newly generated gather sequences.
13651365
void optimizeGatherSequence();
13661366

1367+
/// Does this non-empty order represent an identity order? Identity
1368+
/// should be represented as an empty order, so this is used to
1369+
/// decide if we can canonicalize a computed order. Undef elements
1370+
/// (represented as size) are ignored.
1371+
bool isIdentityOrder(ArrayRef<unsigned> Order) const {
1372+
assert(!Order.empty() && "expected non-empty order");
1373+
const unsigned Sz = Order.size();
1374+
return all_of(enumerate(Order), [&](const auto &P) {
1375+
return P.value() == P.index() || P.value() == Sz;
1376+
});
1377+
}
1378+
13671379
/// Checks if the specified gather tree entry \p TE can be represented as a
13681380
/// shuffled vector entry + (possibly) permutation with other gathers. It
13691381
/// implements the checks only for possibly ordered scalars (Loads,
@@ -5256,12 +5268,6 @@ BoUpSLP::getReorderingData(const TreeEntry &TE, bool TopToBottom) {
52565268
}
52575269
return I1 < I2;
52585270
};
5259-
auto IsIdentityOrder = [](const OrdersType &Order) {
5260-
for (unsigned Idx : seq<unsigned>(0, Order.size()))
5261-
if (Idx != Order[Idx])
5262-
return false;
5263-
return true;
5264-
};
52655271
DenseMap<unsigned, unsigned> PhiToId;
52665272
SmallVector<unsigned> Phis(TE.Scalars.size());
52675273
std::iota(Phis.begin(), Phis.end(), 0);
@@ -5271,7 +5277,7 @@ BoUpSLP::getReorderingData(const TreeEntry &TE, bool TopToBottom) {
52715277
stable_sort(Phis, PHICompare);
52725278
for (unsigned Id = 0, Sz = Phis.size(); Id < Sz; ++Id)
52735279
ResOrder[Id] = PhiToId[Phis[Id]];
5274-
if (IsIdentityOrder(ResOrder))
5280+
if (isIdentityOrder(ResOrder))
52755281
return std::nullopt; // No need to reorder.
52765282
return std::move(ResOrder);
52775283
}
@@ -5565,19 +5571,12 @@ void BoUpSLP::reorderTopToBottom() {
55655571
}
55665572
if (OrdersUses.empty())
55675573
continue;
5568-
auto IsIdentityOrder = [](ArrayRef<unsigned> Order) {
5569-
const unsigned Sz = Order.size();
5570-
for (unsigned Idx : seq<unsigned>(0, Sz))
5571-
if (Idx != Order[Idx] && Order[Idx] != Sz)
5572-
return false;
5573-
return true;
5574-
};
55755574
// Choose the most used order.
55765575
unsigned IdentityCnt = 0;
55775576
unsigned FilledIdentityCnt = 0;
55785577
OrdersType IdentityOrder(VF, VF);
55795578
for (auto &Pair : OrdersUses) {
5580-
if (Pair.first.empty() || IsIdentityOrder(Pair.first)) {
5579+
if (Pair.first.empty() || isIdentityOrder(Pair.first)) {
55815580
if (!Pair.first.empty())
55825581
FilledIdentityCnt += Pair.second;
55835582
IdentityCnt += Pair.second;
@@ -5593,7 +5592,7 @@ void BoUpSLP::reorderTopToBottom() {
55935592
if (Cnt < Pair.second ||
55945593
(Cnt == IdentityCnt && IdentityCnt == FilledIdentityCnt &&
55955594
Cnt == Pair.second && !BestOrder.empty() &&
5596-
IsIdentityOrder(BestOrder))) {
5595+
isIdentityOrder(BestOrder))) {
55975596
combineOrders(Pair.first, BestOrder);
55985597
BestOrder = Pair.first;
55995598
Cnt = Pair.second;
@@ -5602,7 +5601,7 @@ void BoUpSLP::reorderTopToBottom() {
56025601
}
56035602
}
56045603
// Set order of the user node.
5605-
if (IsIdentityOrder(BestOrder))
5604+
if (isIdentityOrder(BestOrder))
56065605
continue;
56075606
fixupOrderingIndices(BestOrder);
56085607
SmallVector<int> Mask;
@@ -5891,19 +5890,12 @@ void BoUpSLP::reorderBottomToTop(bool IgnoreReorder) {
58915890
OrderedEntries.remove(Op.second);
58925891
continue;
58935892
}
5894-
auto IsIdentityOrder = [](ArrayRef<unsigned> Order) {
5895-
const unsigned Sz = Order.size();
5896-
for (unsigned Idx : seq<unsigned>(0, Sz))
5897-
if (Idx != Order[Idx] && Order[Idx] != Sz)
5898-
return false;
5899-
return true;
5900-
};
59015893
// Choose the most used order.
59025894
unsigned IdentityCnt = 0;
59035895
unsigned VF = Data.second.front().second->getVectorFactor();
59045896
OrdersType IdentityOrder(VF, VF);
59055897
for (auto &Pair : OrdersUses) {
5906-
if (Pair.first.empty() || IsIdentityOrder(Pair.first)) {
5898+
if (Pair.first.empty() || isIdentityOrder(Pair.first)) {
59075899
IdentityCnt += Pair.second;
59085900
combineOrders(IdentityOrder, Pair.first);
59095901
}
@@ -5923,7 +5915,7 @@ void BoUpSLP::reorderBottomToTop(bool IgnoreReorder) {
59235915
}
59245916
}
59255917
// Set order of the user node.
5926-
if (IsIdentityOrder(BestOrder)) {
5918+
if (isIdentityOrder(BestOrder)) {
59275919
for (const std::pair<unsigned, TreeEntry *> &Op : Data.second)
59285920
OrderedEntries.remove(Op.second);
59295921
continue;
@@ -6186,13 +6178,7 @@ bool BoUpSLP::canFormVector(ArrayRef<StoreInst *> StoresVec,
61866178
// Identity order (e.g., {0,1,2,3}) is modeled as an empty OrdersType in
61876179
// reorderTopToBottom() and reorderBottomToTop(), so we are following the
61886180
// same convention here.
6189-
auto IsIdentityOrder = [](const OrdersType &Order) {
6190-
for (unsigned Idx : seq<unsigned>(0, Order.size()))
6191-
if (Idx != Order[Idx])
6192-
return false;
6193-
return true;
6194-
};
6195-
if (IsIdentityOrder(ReorderIndices))
6181+
if (isIdentityOrder(ReorderIndices))
61966182
ReorderIndices.clear();
61976183

61986184
return true;

0 commit comments

Comments
 (0)