[VectorUtils] Add InterleaveGroup::members() (NFCI) (#195122)

We need to iterate over all non-null members of a group in multiple
places. Add members helper, as suggested in
https://github.com/llvm/llvm-project/pull/190191.

PR: https://github.com/llvm/llvm-project/pull/195122
This commit is contained in:
Florian Hahn
2026-04-30 21:39:43 +01:00
committed by GitHub
parent 33e9c7fd96
commit 76b5e40297
4 changed files with 34 additions and 39 deletions

View File

@@ -14,6 +14,8 @@
#define LLVM_ANALYSIS_VECTORUTILS_H
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/IR/Module.h"
@@ -595,6 +597,15 @@ public:
return Members.lookup(Key);
}
/// Return an iterator range over the non-null members of this group, in
/// index order.
auto members() const {
return make_filter_range(
map_range(seq<uint32_t>(0, Factor),
[this](uint32_t I) { return getMember(I); }),
[](InstTy *I) { return I != nullptr; });
}
/// Get the index for the given member. Unlike the key in the member
/// map, the index starts from 0.
uint32_t getIndex(const InstTy *Instr) const {

View File

@@ -956,13 +956,11 @@ public:
if (W != CM_Interleave)
OtherMemberCost = InsertPosCost = Cost / Grp->getNumMembers();
;
for (unsigned Idx = 0; Idx < Grp->getFactor(); ++Idx) {
if (auto *I = Grp->getMember(Idx)) {
if (Grp->getInsertPos() == I)
WideningDecisions[{I, VF}] = {W, InsertPosCost};
else
WideningDecisions[{I, VF}] = {W, OtherMemberCost};
}
for (auto *I : Grp->members()) {
if (Grp->getInsertPos() == I)
WideningDecisions[{I, VF}] = {W, InsertPosCost};
else
WideningDecisions[{I, VF}] = {W, OtherMemberCost};
}
}
@@ -2560,10 +2558,7 @@ bool LoopVectorizationCostModel::interleavedAccessCanBeWidened(
// If the group involves a non-integral pointer, we may not be able to
// losslessly cast all values to a common type.
bool ScalarNI = DL.isNonIntegralPointerType(ScalarTy);
for (unsigned Idx = 0; Idx < InterleaveFactor; Idx++) {
Instruction *Member = Group->getMember(Idx);
if (!Member)
continue;
for (Instruction *Member : Group->members()) {
auto *MemberTy = getLoadStoreType(Member);
bool MemberNI = DL.isNonIntegralPointerType(MemberTy);
// Don't coerce non-integral pointers to integers or vice versa.
@@ -4833,12 +4828,9 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
// the cost will actually be assigned to one instruction.
if (const auto *Group = getInterleavedAccessGroup(&I)) {
if (Decision == CM_Scalarize) {
for (unsigned Idx = 0; Idx < Group->getFactor(); ++Idx) {
if (auto *I = Group->getMember(Idx)) {
setWideningDecision(I, VF, Decision,
getMemInstScalarizationCost(I, VF));
}
}
for (Instruction *I : Group->members())
setWideningDecision(I, VF, Decision,
getMemInstScalarizationCost(I, VF));
} else {
setWideningDecision(Group, VF, Decision, Cost);
}
@@ -4913,17 +4905,14 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
// Scalarize all members of this interleaved group when any member
// is used as an address. The address-used load skips scalarization
// overhead, other members include it.
for (unsigned Idx = 0; Idx < Group->getFactor(); ++Idx) {
if (Instruction *Member = Group->getMember(Idx)) {
InstructionCost Cost =
AddrDefs.contains(Member)
? (VF.getKnownMinValue() *
getMemoryInstructionCost(Member,
ElementCount::getFixed(1)))
: getMemInstScalarizationCost(Member, VF);
setWideningDecision(Member, VF, CM_Scalarize, Cost);
UpdateMemOpUserCost(cast<LoadInst>(Member));
}
for (Instruction *Member : Group->members()) {
InstructionCost Cost = AddrDefs.contains(Member)
? (VF.getKnownMinValue() *
getMemoryInstructionCost(
Member, ElementCount::getFixed(1)))
: getMemInstScalarizationCost(Member, VF);
setWideningDecision(Member, VF, CM_Scalarize, Cost);
UpdateMemOpUserCost(cast<LoadInst>(Member));
}
}
} else {

View File

@@ -2867,11 +2867,10 @@ protected:
assert((!Mask || !IG->isReverse()) &&
"Reversed masked interleave-group not supported.");
if (StoredValues.empty()) {
for (unsigned I = 0; I < IG->getFactor(); ++I)
if (Instruction *Inst = IG->getMember(I)) {
assert(!Inst->getType()->isVoidTy() && "must have result");
new VPRecipeValue(this, Inst);
}
for (Instruction *Inst : IG->members()) {
assert(!Inst->getType()->isVoidTy() && "must have result");
new VPRecipeValue(this, Inst);
}
} else {
for (auto *SV : StoredValues)
addOperand(SV);

View File

@@ -3489,12 +3489,8 @@ void VPlanTransforms::dropPoisonGeneratingRecipes(
const InterleaveGroup<Instruction> *InterGroup =
InterleaveRec->getInterleaveGroup();
bool NeedPredication = false;
for (int I = 0, NumMembers = InterGroup->getNumMembers();
I < NumMembers; ++I) {
Instruction *Member = InterGroup->getMember(I);
if (Member)
NeedPredication |= BlockNeedsPredication(Member->getParent());
}
for (Instruction *Member : InterGroup->members())
NeedPredication |= BlockNeedsPredication(Member->getParent());
if (NeedPredication)
CollectPoisonGeneratingInstrsInBackwardSlice(AddrDef);