[llvm] [SLP][NFC]Make TreeEntry a class and store "need-to-schedule" state (PR #140734)
via llvm-commits
llvm-commits at lists.llvm.org
Tue May 20 07:19:00 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-vectorizers
Author: Alexey Bataev (alexey-bataev)
<details>
<summary>Changes</summary>
TreeEntry should be a class, not a struct, since it has private members.
Also, do no repeat Does-Not-Need-To-Schedule analysis during codegen,
codegen may affect the result of the analysis in future patches.
---
Full diff: https://github.com/llvm/llvm-project/pull/140734.diff
1 Files Affected:
- (modified) llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp (+23-7)
``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index fcb9da637dd37..a8b28dd08a416 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -1744,7 +1744,7 @@ namespace slpvectorizer {
/// Bottom Up SLP Vectorizer.
class BoUpSLP {
- struct TreeEntry;
+ class TreeEntry;
class ScheduleEntity;
class ScheduleData;
class ScheduleBundle;
@@ -3607,7 +3607,8 @@ class BoUpSLP {
/// opportunities.
void reorderGatherNode(TreeEntry &TE);
- struct TreeEntry {
+ class TreeEntry {
+ public:
using VecTreeTy = SmallVector<std::unique_ptr<TreeEntry>, 8>;
TreeEntry(VecTreeTy &Container) : Container(Container) {}
@@ -3774,6 +3775,9 @@ class BoUpSLP {
/// Interleaving factor for interleaved loads Vectorize nodes.
unsigned InterleaveFactor = 0;
+ /// True if the node does not require scheduling.
+ bool DoesNotNeedToSchedule = false;
+
/// Set this bundle's \p OpIdx'th operand to \p OpVL.
void setOperand(unsigned OpIdx, ArrayRef<Value *> OpVL) {
if (Operands.size() < OpIdx + 1)
@@ -3791,6 +3795,16 @@ class BoUpSLP {
/// Sets interleaving factor for the interleaving nodes.
void setInterleave(unsigned Factor) { InterleaveFactor = Factor; }
+ /// Marks the node as one that does not require scheduling.
+ void setDoesNotNeedToSchedule() {
+ assert(::doesNotNeedToSchedule(Scalars) &&
+ "Expected to not need scheduling");
+ DoesNotNeedToSchedule = true;
+ }
+ /// Returns true if the node is marked as one that does not require
+ /// scheduling.
+ bool doesNotNeedToSchedule() const { return DoesNotNeedToSchedule; }
+
/// Set this bundle's operands from \p Operands.
void setOperands(ArrayRef<ValueList> Operands) {
for (unsigned I : seq<unsigned>(Operands.size()))
@@ -4107,6 +4121,8 @@ class BoUpSLP {
}
}
} else if (!Last->isGather()) {
+ if (doesNotNeedToSchedule(VL))
+ Last->setDoesNotNeedToSchedule();
SmallPtrSet<Value *, 4> Processed;
for (Value *V : VL) {
if (isa<PoisonValue>(V))
@@ -4124,7 +4140,7 @@ class BoUpSLP {
// Update the scheduler bundle to point to this TreeEntry.
assert((!Bundle.getBundle().empty() || isa<PHINode>(S.getMainOp()) ||
isVectorLikeInstWithConstOps(S.getMainOp()) ||
- doesNotNeedToSchedule(VL)) &&
+ Last->doesNotNeedToSchedule()) &&
"Bundle and VL out of sync");
if (!Bundle.getBundle().empty()) {
#if !defined(NDEBUG) || defined(EXPENSIVE_CHECKS)
@@ -15331,8 +15347,8 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
}
if (!TEUseEI.UserTE->isGather() && !UserPHI &&
- doesNotNeedToSchedule(TEUseEI.UserTE->Scalars) !=
- doesNotNeedToSchedule(UseEI.UserTE->Scalars) &&
+ TEUseEI.UserTE->doesNotNeedToSchedule() !=
+ UseEI.UserTE->doesNotNeedToSchedule() &&
is_contained(UseEI.UserTE->Scalars, TEInsertPt))
continue;
// Check if the user node of the TE comes after user node of TEPtr,
@@ -16127,7 +16143,7 @@ void BoUpSLP::setInsertPointAfterBundle(const TreeEntry *E) {
}
if (IsPHI ||
(!E->isGather() && E->State != TreeEntry::SplitVectorize &&
- doesNotNeedToSchedule(E->Scalars)) ||
+ E->doesNotNeedToSchedule()) ||
(GatheredLoadsEntriesFirst.has_value() &&
E->Idx >= *GatheredLoadsEntriesFirst && !E->isGather() &&
E->getOpcode() == Instruction::Load)) {
@@ -19803,7 +19819,7 @@ void BoUpSLP::scheduleBlock(BlockScheduling *BS) {
if (ScheduleData *SD = BS->getScheduleData(I)) {
[[maybe_unused]] ArrayRef<TreeEntry *> SDTEs = getTreeEntries(I);
assert((isVectorLikeInstWithConstOps(SD->getInst()) || SDTEs.empty() ||
- doesNotNeedToSchedule(SDTEs.front()->Scalars)) &&
+ SDTEs.front()->doesNotNeedToSchedule()) &&
"scheduler and vectorizer bundle mismatch");
SD->setSchedulingPriority(Idx++);
continue;
``````````
</details>
https://github.com/llvm/llvm-project/pull/140734
More information about the llvm-commits
mailing list