Skip to content

Commit df0add1

Browse files
committed
[SLP] Use named structs in vectorizeStores() (NFC)
This is a mostly straightforward replacement of the previous std::pair<int, std::set<std::pair<...>>> data structure with slightly more readable alternatives.
1 parent 29ca03f commit df0add1

File tree

1 file changed

+74
-48
lines changed

1 file changed

+74
-48
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 74 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -19945,6 +19945,46 @@ static bool checkTreeSizes(ArrayRef<std::pair<unsigned, unsigned>> Sizes,
1994519945
return Dev * 96 / (Mean * Mean) == 0;
1994619946
}
1994719947

19948+
namespace {
19949+
19950+
/// A reference to a store instruction and the distance of its address to a base
19951+
/// pointer.
19952+
struct InstAndPtrDist {
19953+
InstAndPtrDist(unsigned InstrIdx, int DistToBasePtr)
19954+
: InstrIdx(InstrIdx), DistToBasePtr(DistToBasePtr) {}
19955+
unsigned InstrIdx;
19956+
int DistToBasePtr;
19957+
};
19958+
struct PtrDistCompare {
19959+
bool operator()(const InstAndPtrDist &Op1, const InstAndPtrDist &Op2) const {
19960+
return Op1.DistToBasePtr < Op2.DistToBasePtr;
19961+
}
19962+
};
19963+
19964+
/// A group of instructions that we'll try to bundle together using vector ops.
19965+
/// They are ordered using the signed distance of their address operand to the
19966+
/// address of this group's BaseInstr.
19967+
struct RelatedStoreInsts {
19968+
RelatedStoreInsts(unsigned BaseInstrIdx) { reset(BaseInstrIdx); }
19969+
void reset(unsigned NewBaseInstr) {
19970+
BaseInstrIdx = NewBaseInstr;
19971+
Instrs.clear();
19972+
Instrs.emplace(NewBaseInstr, 0);
19973+
}
19974+
19975+
// Note: PtrDistCompare ensures that there a 1:1 mapping between distance and
19976+
// instruction. This could be turned into a map to be more obvious.
19977+
using InstSet = std::set<InstAndPtrDist, PtrDistCompare>;
19978+
19979+
/// The index of the Base instruction, i.e. the one with a 0 pointer distance.
19980+
unsigned BaseInstrIdx;
19981+
19982+
/// Maps an instruction index to a pointer distance from \p BaseInstrIdx.
19983+
InstSet Instrs;
19984+
};
19985+
19986+
} // end anonymous namespace
19987+
1994819988
bool SLPVectorizerPass::vectorizeStores(
1994919989
ArrayRef<StoreInst *> Stores, BoUpSLP &R,
1995019990
DenseSet<std::tuple<Value *, Value *, Value *, Value *, unsigned>>
@@ -19954,31 +19994,21 @@ bool SLPVectorizerPass::vectorizeStores(
1995419994
BoUpSLP::ValueSet VectorizedStores;
1995519995
bool Changed = false;
1995619996

19957-
struct StoreDistCompare {
19958-
bool operator()(const std::pair<unsigned, int> &Op1,
19959-
const std::pair<unsigned, int> &Op2) const {
19960-
return Op1.second < Op2.second;
19961-
}
19962-
};
19963-
// A set of pairs (index of store in Stores array ref, Distance of the store
19964-
// address relative to base store address in units).
19965-
using StoreIndexToDistSet =
19966-
std::set<std::pair<unsigned, int>, StoreDistCompare>;
19967-
auto TryToVectorize = [&](const StoreIndexToDistSet &Set) {
19997+
auto TryToVectorize = [&](const RelatedStoreInsts::InstSet &StoreSeq) {
1996819998
int PrevDist = -1;
1996919999
BoUpSLP::ValueList Operands;
1997020000
// Collect the chain into a list.
19971-
for (auto [Idx, Data] : enumerate(Set)) {
19972-
if (Operands.empty() || Data.second - PrevDist == 1) {
19973-
Operands.push_back(Stores[Data.first]);
19974-
PrevDist = Data.second;
19975-
if (Idx != Set.size() - 1)
20001+
for (auto [Idx, Data] : enumerate(StoreSeq)) {
20002+
if (Operands.empty() || Data.DistToBasePtr - PrevDist == 1) {
20003+
Operands.push_back(Stores[Data.InstrIdx]);
20004+
PrevDist = Data.DistToBasePtr;
20005+
if (Idx != StoreSeq.size() - 1)
1997620006
continue;
1997720007
}
1997820008
auto E = make_scope_exit([&, &DataVar = Data]() {
1997920009
Operands.clear();
19980-
Operands.push_back(Stores[DataVar.first]);
19981-
PrevDist = DataVar.second;
20010+
Operands.push_back(Stores[DataVar.InstrIdx]);
20011+
PrevDist = DataVar.DistToBasePtr;
1998220012
});
1998320013

1998420014
if (Operands.size() <= 1 ||
@@ -20245,7 +20275,8 @@ bool SLPVectorizerPass::vectorizeStores(
2024520275
// Need to store the index of the very first store separately, since the set
2024620276
// may be reordered after the insertion and the first store may be moved. This
2024720277
// container allows to reduce number of calls of getPointersDiff() function.
20248-
SmallVector<std::pair<unsigned, StoreIndexToDistSet>> SortedStores;
20278+
SmallVector<RelatedStoreInsts> SortedStores;
20279+
2024920280
// Inserts the specified store SI with the given index Idx to the set of the
2025020281
// stores. If the store with the same distance is found already - stop
2025120282
// insertion, try to vectorize already found stores. If some stores from this
@@ -20279,56 +20310,51 @@ bool SLPVectorizerPass::vectorizeStores(
2027920310
// dependencies and no need to waste compile time to try to vectorize them.
2028020311
// - Try to vectorize the sequence {1, {1, 0}, {3, 2}}.
2028120312
auto FillStoresSet = [&](unsigned Idx, StoreInst *SI) {
20282-
for (std::pair<unsigned, StoreIndexToDistSet> &Set : SortedStores) {
20313+
for (RelatedStoreInsts &StoreSeq : SortedStores) {
2028320314
std::optional<int> Diff = getPointersDiff(
20284-
Stores[Set.first]->getValueOperand()->getType(),
20285-
Stores[Set.first]->getPointerOperand(),
20315+
Stores[StoreSeq.BaseInstrIdx]->getValueOperand()->getType(),
20316+
Stores[StoreSeq.BaseInstrIdx]->getPointerOperand(),
2028620317
SI->getValueOperand()->getType(), SI->getPointerOperand(), *DL, *SE,
2028720318
/*StrictCheck=*/true);
2028820319
if (!Diff)
2028920320
continue;
20290-
auto It = Set.second.find(std::make_pair(Idx, *Diff));
20291-
if (It == Set.second.end()) {
20292-
Set.second.emplace(Idx, *Diff);
20321+
auto It = StoreSeq.Instrs.find({Idx, *Diff});
20322+
if (It == StoreSeq.Instrs.end()) {
20323+
StoreSeq.Instrs.emplace(Idx, *Diff);
2029320324
return;
2029420325
}
2029520326
// Try to vectorize the first found set to avoid duplicate analysis.
20296-
TryToVectorize(Set.second);
20297-
unsigned ItIdx = It->first;
20298-
int ItDist = It->second;
20299-
StoreIndexToDistSet PrevSet;
20300-
copy_if(Set.second, std::inserter(PrevSet, PrevSet.end()),
20301-
[&](const std::pair<unsigned, int> &Pair) {
20302-
return Pair.first > ItIdx;
20303-
});
20304-
Set.second.clear();
20305-
Set.first = Idx;
20306-
Set.second.emplace(Idx, 0);
20327+
TryToVectorize(StoreSeq.Instrs);
20328+
unsigned ItIdx = It->InstrIdx;
20329+
int ItDist = It->DistToBasePtr;
20330+
RelatedStoreInsts::InstSet PrevSet;
20331+
copy_if(StoreSeq.Instrs, std::inserter(PrevSet, PrevSet.end()),
20332+
[&](const InstAndPtrDist &I) { return I.InstrIdx > ItIdx; });
20333+
StoreSeq.reset(Idx);
2030720334
// Insert stores that followed previous match to try to vectorize them
2030820335
// with this store.
2030920336
unsigned StartIdx = ItIdx + 1;
2031020337
SmallBitVector UsedStores(Idx - StartIdx);
2031120338
// Distances to previously found dup store (or this store, since they
2031220339
// store to the same addresses).
2031320340
SmallVector<int> Dists(Idx - StartIdx, 0);
20314-
for (const std::pair<unsigned, int> &Pair : reverse(PrevSet)) {
20341+
for (const InstAndPtrDist &Store : reverse(PrevSet)) {
2031520342
// Do not try to vectorize sequences, we already tried.
20316-
if (VectorizedStores.contains(Stores[Pair.first]))
20343+
if (VectorizedStores.contains(Stores[Store.InstrIdx]))
2031720344
break;
20318-
unsigned BI = Pair.first - StartIdx;
20345+
unsigned BI = Store.InstrIdx - StartIdx;
2031920346
UsedStores.set(BI);
20320-
Dists[BI] = Pair.second - ItDist;
20347+
Dists[BI] = Store.DistToBasePtr - ItDist;
2032120348
}
2032220349
for (unsigned I = StartIdx; I < Idx; ++I) {
2032320350
unsigned BI = I - StartIdx;
2032420351
if (UsedStores.test(BI))
20325-
Set.second.emplace(I, Dists[BI]);
20352+
StoreSeq.Instrs.emplace(I, Dists[BI]);
2032620353
}
2032720354
return;
2032820355
}
20329-
auto &Res = SortedStores.emplace_back();
20330-
Res.first = Idx;
20331-
Res.second.emplace(Idx, 0);
20356+
// We did not find a comparable store, start a new sequence.
20357+
SortedStores.emplace_back(Idx);
2033220358
};
2033320359
Type *PrevValTy = nullptr;
2033420360
for (auto [I, SI] : enumerate(Stores)) {
@@ -20338,17 +20364,17 @@ bool SLPVectorizerPass::vectorizeStores(
2033820364
PrevValTy = SI->getValueOperand()->getType();
2033920365
// Check that we do not try to vectorize stores of different types.
2034020366
if (PrevValTy != SI->getValueOperand()->getType()) {
20341-
for (auto &Set : SortedStores)
20342-
TryToVectorize(Set.second);
20367+
for (RelatedStoreInsts &StoreSeq : SortedStores)
20368+
TryToVectorize(StoreSeq.Instrs);
2034320369
SortedStores.clear();
2034420370
PrevValTy = SI->getValueOperand()->getType();
2034520371
}
2034620372
FillStoresSet(I, SI);
2034720373
}
2034820374

2034920375
// Final vectorization attempt.
20350-
for (auto &Set : SortedStores)
20351-
TryToVectorize(Set.second);
20376+
for (RelatedStoreInsts &StoreSeq : SortedStores)
20377+
TryToVectorize(StoreSeq.Instrs);
2035220378

2035320379
return Changed;
2035420380
}

0 commit comments

Comments
 (0)