@@ -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