@@ -1364,6 +1364,18 @@ class BoUpSLP {
1364
1364
/// Perform LICM and CSE on the newly generated gather sequences.
1365
1365
void optimizeGatherSequence();
1366
1366
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
+
1367
1379
/// Checks if the specified gather tree entry \p TE can be represented as a
1368
1380
/// shuffled vector entry + (possibly) permutation with other gathers. It
1369
1381
/// implements the checks only for possibly ordered scalars (Loads,
@@ -5256,12 +5268,6 @@ BoUpSLP::getReorderingData(const TreeEntry &TE, bool TopToBottom) {
5256
5268
}
5257
5269
return I1 < I2;
5258
5270
};
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
- };
5265
5271
DenseMap<unsigned, unsigned> PhiToId;
5266
5272
SmallVector<unsigned> Phis(TE.Scalars.size());
5267
5273
std::iota(Phis.begin(), Phis.end(), 0);
@@ -5271,7 +5277,7 @@ BoUpSLP::getReorderingData(const TreeEntry &TE, bool TopToBottom) {
5271
5277
stable_sort(Phis, PHICompare);
5272
5278
for (unsigned Id = 0, Sz = Phis.size(); Id < Sz; ++Id)
5273
5279
ResOrder[Id] = PhiToId[Phis[Id]];
5274
- if (IsIdentityOrder (ResOrder))
5280
+ if (isIdentityOrder (ResOrder))
5275
5281
return std::nullopt; // No need to reorder.
5276
5282
return std::move(ResOrder);
5277
5283
}
@@ -5565,19 +5571,12 @@ void BoUpSLP::reorderTopToBottom() {
5565
5571
}
5566
5572
if (OrdersUses.empty())
5567
5573
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
- };
5575
5574
// Choose the most used order.
5576
5575
unsigned IdentityCnt = 0;
5577
5576
unsigned FilledIdentityCnt = 0;
5578
5577
OrdersType IdentityOrder(VF, VF);
5579
5578
for (auto &Pair : OrdersUses) {
5580
- if (Pair.first.empty() || IsIdentityOrder (Pair.first)) {
5579
+ if (Pair.first.empty() || isIdentityOrder (Pair.first)) {
5581
5580
if (!Pair.first.empty())
5582
5581
FilledIdentityCnt += Pair.second;
5583
5582
IdentityCnt += Pair.second;
@@ -5593,7 +5592,7 @@ void BoUpSLP::reorderTopToBottom() {
5593
5592
if (Cnt < Pair.second ||
5594
5593
(Cnt == IdentityCnt && IdentityCnt == FilledIdentityCnt &&
5595
5594
Cnt == Pair.second && !BestOrder.empty() &&
5596
- IsIdentityOrder (BestOrder))) {
5595
+ isIdentityOrder (BestOrder))) {
5597
5596
combineOrders(Pair.first, BestOrder);
5598
5597
BestOrder = Pair.first;
5599
5598
Cnt = Pair.second;
@@ -5602,7 +5601,7 @@ void BoUpSLP::reorderTopToBottom() {
5602
5601
}
5603
5602
}
5604
5603
// Set order of the user node.
5605
- if (IsIdentityOrder (BestOrder))
5604
+ if (isIdentityOrder (BestOrder))
5606
5605
continue;
5607
5606
fixupOrderingIndices(BestOrder);
5608
5607
SmallVector<int> Mask;
@@ -5891,19 +5890,12 @@ void BoUpSLP::reorderBottomToTop(bool IgnoreReorder) {
5891
5890
OrderedEntries.remove(Op.second);
5892
5891
continue;
5893
5892
}
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
- };
5901
5893
// Choose the most used order.
5902
5894
unsigned IdentityCnt = 0;
5903
5895
unsigned VF = Data.second.front().second->getVectorFactor();
5904
5896
OrdersType IdentityOrder(VF, VF);
5905
5897
for (auto &Pair : OrdersUses) {
5906
- if (Pair.first.empty() || IsIdentityOrder (Pair.first)) {
5898
+ if (Pair.first.empty() || isIdentityOrder (Pair.first)) {
5907
5899
IdentityCnt += Pair.second;
5908
5900
combineOrders(IdentityOrder, Pair.first);
5909
5901
}
@@ -5923,7 +5915,7 @@ void BoUpSLP::reorderBottomToTop(bool IgnoreReorder) {
5923
5915
}
5924
5916
}
5925
5917
// Set order of the user node.
5926
- if (IsIdentityOrder (BestOrder)) {
5918
+ if (isIdentityOrder (BestOrder)) {
5927
5919
for (const std::pair<unsigned, TreeEntry *> &Op : Data.second)
5928
5920
OrderedEntries.remove(Op.second);
5929
5921
continue;
@@ -6186,13 +6178,7 @@ bool BoUpSLP::canFormVector(ArrayRef<StoreInst *> StoresVec,
6186
6178
// Identity order (e.g., {0,1,2,3}) is modeled as an empty OrdersType in
6187
6179
// reorderTopToBottom() and reorderBottomToTop(), so we are following the
6188
6180
// 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))
6196
6182
ReorderIndices.clear();
6197
6183
6198
6184
return true;
0 commit comments