[llvm] [SLP] Create groups before sorting Phis (PR #111174)
Alexey Bataev via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 4 09:27:18 PDT 2024
================
@@ -5448,40 +5448,136 @@ BoUpSLP::getReorderingData(const TreeEntry &TE, bool TopToBottom) {
if (!TE.ReorderIndices.empty())
return TE.ReorderIndices;
- auto PHICompare = [&](unsigned I1, unsigned I2) {
- Value *V1 = TE.Scalars[I1];
- Value *V2 = TE.Scalars[I2];
- if (V1 == V2 || (V1->getNumUses() == 0 && V2->getNumUses() == 0))
- return false;
- if (V1->getNumUses() < V2->getNumUses())
- return true;
- if (V1->getNumUses() > V2->getNumUses())
- return false;
- auto *FirstUserOfPhi1 = cast<Instruction>(*V1->user_begin());
- auto *FirstUserOfPhi2 = cast<Instruction>(*V2->user_begin());
- if (auto *IE1 = dyn_cast<InsertElementInst>(FirstUserOfPhi1))
- if (auto *IE2 = dyn_cast<InsertElementInst>(FirstUserOfPhi2)) {
- if (!areTwoInsertFromSameBuildVector(
- IE1, IE2,
- [](InsertElementInst *II) { return II->getOperand(0); }))
- return I1 < I2;
- return getElementIndex(IE1) < getElementIndex(IE2);
- }
- if (auto *EE1 = dyn_cast<ExtractElementInst>(FirstUserOfPhi1))
- if (auto *EE2 = dyn_cast<ExtractElementInst>(FirstUserOfPhi2)) {
- if (EE1->getOperand(0) != EE2->getOperand(0))
- return I1 < I2;
- return getElementIndex(EE1) < getElementIndex(EE2);
- }
- return I1 < I2;
- };
- SmallDenseMap<unsigned, unsigned, 16> PhiToId;
+ DenseMap<unsigned, unsigned> PhiToId;
SmallVector<unsigned> Phis(TE.Scalars.size());
std::iota(Phis.begin(), Phis.end(), 0);
+
+ BitVector Seen(Phis.size());
+ SmallVector<SmallVector<unsigned>> Groups;
+ Groups.resize(Phis.size(), {});
+
+ for (auto const Phidx : Phis) {
+ // We've already found a group for this Phidx
+ if (Seen.test(Phidx))
+ continue;
+
+ Groups[Phidx].push_back(Phidx);
+
+ auto UserIterPhi1 = TE.Scalars[Phidx]->user_begin();
+ if (UserIterPhi1.atEnd())
+ continue;
+
+ auto *FirstUserOfPhi1 = cast<Instruction>(*UserIterPhi1);
+
+ unsigned Count = 0;
+ if (auto *IE1 = dyn_cast<InsertElementInst>(FirstUserOfPhi1)) {
+ auto Width = IE1->getType()->getElementCount();
+ assert(!Width.isScalable());
+ Count = Width.getFixedValue() - 1;
+ } else if (auto *EE1 = dyn_cast<ExtractElementInst>(FirstUserOfPhi1)) {
+ // Count is unused in the case of extract element instructions.
+ Count = -1;
+ }
+
+ for (auto const PhidxB : ArrayRef(Phis).drop_front(Phidx + 1)) {
+
----------------
alexey-bataev wrote:
Again, O(N^2). I don't like it, it increases compile time. Alternative approach is here
https://github.com/llvm/llvm-project/pull/110529
https://github.com/llvm/llvm-project/pull/111174
More information about the llvm-commits
mailing list