Skip to content

Commit 612924a

Browse files
committed
buildTree_rec(): Single point of definition for legality characteristics
1 parent 2de50c6 commit 612924a

File tree

1 file changed

+54
-37
lines changed

1 file changed

+54
-37
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4248,13 +4248,34 @@ class BoUpSLP {
42484248
bool areAltOperandsProfitable(const InstructionsState &S,
42494249
ArrayRef<Value *> VL) const;
42504250

4251+
/// Contains all the outputs of legality analysis for a list of values to
4252+
/// vectorize.
4253+
class ScalarsVectorizationLegality {
4254+
InstructionsState S;
4255+
bool IsLegal;
4256+
bool TryToFindDuplicates;
4257+
bool TrySplitVectorize;
4258+
4259+
public:
4260+
ScalarsVectorizationLegality(InstructionsState S, bool IsLegal,
4261+
bool TryToFindDuplicates = true,
4262+
bool TrySplitVectorize = false)
4263+
: S(S), IsLegal(IsLegal), TryToFindDuplicates(TryToFindDuplicates),
4264+
TrySplitVectorize(TrySplitVectorize) {
4265+
assert((!IsLegal || (S.valid() && TryToFindDuplicates)) &&
4266+
"Inconsistent state");
4267+
}
4268+
const InstructionsState &getInstructionsState() const { return S; };
4269+
bool isLegal() const { return IsLegal; }
4270+
bool tryToFindDuplicates() const { return TryToFindDuplicates; }
4271+
bool trySplitVectorize() const { return TrySplitVectorize; }
4272+
};
4273+
42514274
/// Checks if the specified list of the instructions/values can be vectorized
42524275
/// in general.
4253-
bool isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
4254-
const EdgeInfo &UserTreeIdx,
4255-
InstructionsState &S,
4256-
bool &TryToFindDuplicates,
4257-
bool &TrySplitVectorize) const;
4276+
ScalarsVectorizationLegality
4277+
getScalarsVectorizationLegality(ArrayRef<Value *> VL, unsigned Depth,
4278+
const EdgeInfo &UserTreeIdx) const;
42584279

42594280
/// Checks if the specified list of the instructions/values can be vectorized
42604281
/// and fills required data before actual scheduling of the instructions.
@@ -9693,25 +9714,21 @@ bool BoUpSLP::canBuildSplitNode(ArrayRef<Value *> VL,
96939714
return true;
96949715
}
96959716

9696-
bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
9697-
const EdgeInfo &UserTreeIdx,
9698-
InstructionsState &S,
9699-
bool &TryToFindDuplicates,
9700-
bool &TrySplitVectorize) const {
9717+
BoUpSLP::ScalarsVectorizationLegality
9718+
BoUpSLP::getScalarsVectorizationLegality(ArrayRef<Value *> VL, unsigned Depth,
9719+
const EdgeInfo &UserTreeIdx) const {
97019720
assert((allConstant(VL) || allSameType(VL)) && "Invalid types!");
97029721

9703-
S = getSameOpcode(VL, *TLI);
9704-
TryToFindDuplicates = true;
9705-
TrySplitVectorize = false;
9722+
InstructionsState S = getSameOpcode(VL, *TLI);
97069723

97079724
// Don't go into catchswitch blocks, which can happen with PHIs.
97089725
// Such blocks can only have PHIs and the catchswitch. There is no
97099726
// place to insert a shuffle if we need to, so just avoid that issue.
97109727
if (S && isa<CatchSwitchInst>(S.getMainOp()->getParent()->getTerminator())) {
97119728
LLVM_DEBUG(dbgs() << "SLP: bundle in catchswitch block.\n");
97129729
// Do not try to pack to avoid extra instructions here.
9713-
TryToFindDuplicates = false;
9714-
return false;
9730+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false,
9731+
/*TryToFindDuplicates=*/false);
97159732
}
97169733

97179734
// Check if this is a duplicate of another entry.
@@ -9721,14 +9738,14 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
97219738
if (E->isSame(VL)) {
97229739
LLVM_DEBUG(dbgs() << "SLP: Perfect diamond merge at " << *S.getMainOp()
97239740
<< ".\n");
9724-
return false;
9741+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
97259742
}
97269743
SmallPtrSet<Value *, 8> Values(llvm::from_range, E->Scalars);
97279744
if (all_of(VL, [&](Value *V) {
97289745
return isa<PoisonValue>(V) || Values.contains(V);
97299746
})) {
97309747
LLVM_DEBUG(dbgs() << "SLP: Gathering due to full overlap.\n");
9731-
return false;
9748+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
97329749
}
97339750
}
97349751
}
@@ -9745,23 +9762,23 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
97459762
cast<Instruction>(I)->getOpcode() == S.getOpcode();
97469763
})))) {
97479764
LLVM_DEBUG(dbgs() << "SLP: Gathering due to max recursion depth.\n");
9748-
return false;
9765+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
97499766
}
97509767

97519768
// Don't handle scalable vectors
97529769
if (S && S.getOpcode() == Instruction::ExtractElement &&
97539770
isa<ScalableVectorType>(
97549771
cast<ExtractElementInst>(S.getMainOp())->getVectorOperandType())) {
97559772
LLVM_DEBUG(dbgs() << "SLP: Gathering due to scalable vector type.\n");
9756-
return false;
9773+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
97579774
}
97589775

97599776
// Don't handle vectors.
97609777
if (!SLPReVec && getValueType(VL.front())->isVectorTy()) {
97619778
LLVM_DEBUG(dbgs() << "SLP: Gathering due to vector type.\n");
97629779
// Do not try to pack to avoid extra instructions here.
9763-
TryToFindDuplicates = false;
9764-
return false;
9780+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false,
9781+
/*TryToFindDuplicates=*/false);
97659782
}
97669783

97679784
// If all of the operands are identical or constant we have a simple solution.
@@ -9851,11 +9868,12 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
98519868
if (!S) {
98529869
LLVM_DEBUG(dbgs() << "SLP: Try split and if failed, gathering due to "
98539870
"C,S,B,O, small shuffle. \n");
9854-
TrySplitVectorize = true;
9855-
return false;
9871+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false,
9872+
/*TryToFindDuplicates=*/true,
9873+
/*TrySplitVectorize=*/true);
98569874
}
98579875
LLVM_DEBUG(dbgs() << "SLP: Gathering due to C,S,B,O, small shuffle. \n");
9858-
return false;
9876+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
98599877
}
98609878

98619879
// Don't vectorize ephemeral values.
@@ -9865,8 +9883,8 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
98659883
LLVM_DEBUG(dbgs() << "SLP: The instruction (" << *V
98669884
<< ") is ephemeral.\n");
98679885
// Do not try to pack to avoid extra instructions here.
9868-
TryToFindDuplicates = false;
9869-
return false;
9886+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false,
9887+
/*TryToFindDuplicates=*/false);
98709888
}
98719889
}
98729890
}
@@ -9915,7 +9933,7 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
99159933
if (PreferScalarize) {
99169934
LLVM_DEBUG(dbgs() << "SLP: The instructions are in tree and alternate "
99179935
"node is not profitable.\n");
9918-
return false;
9936+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
99199937
}
99209938
}
99219939

@@ -9924,7 +9942,7 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
99249942
for (Value *V : VL) {
99259943
if (UserIgnoreList->contains(V)) {
99269944
LLVM_DEBUG(dbgs() << "SLP: Gathering due to gathered scalar.\n");
9927-
return false;
9945+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
99289946
}
99299947
}
99309948
}
@@ -9954,9 +9972,9 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
99549972
// Do not vectorize EH and non-returning blocks, not profitable in most
99559973
// cases.
99569974
LLVM_DEBUG(dbgs() << "SLP: bundle in unreachable block.\n");
9957-
return false;
9975+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
99589976
}
9959-
return true;
9977+
return ScalarsVectorizationLegality(S, /*IsLegal=*/true);
99609978
}
99619979

99629980
void BoUpSLP::buildTree_rec(ArrayRef<Value *> VLRef, unsigned Depth,
@@ -9973,7 +9991,6 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VLRef, unsigned Depth,
99739991
ReuseShuffleIndices);
99749992
};
99759993

9976-
InstructionsState S = InstructionsState::invalid();
99779994
// Tries to build split node.
99789995
auto TrySplitNode = [&](const InstructionsState &LocalState) {
99799996
SmallVector<Value *> Op1, Op2;
@@ -10007,17 +10024,17 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VLRef, unsigned Depth,
1000710024
return true;
1000810025
};
1000910026

10010-
bool TryToPackDuplicates;
10011-
bool TrySplitVectorize;
10012-
if (!isLegalToVectorizeScalars(VL, Depth, UserTreeIdx, S, TryToPackDuplicates,
10013-
TrySplitVectorize)) {
10014-
if (TrySplitVectorize) {
10027+
ScalarsVectorizationLegality SVL =
10028+
getScalarsVectorizationLegality(VL, Depth, UserTreeIdx);
10029+
const InstructionsState &S = SVL.getInstructionsState();
10030+
if (!SVL.isLegal()) {
10031+
if (SVL.trySplitVectorize()) {
1001510032
auto [MainOp, AltOp] = getMainAltOpsNoStateVL(VL);
1001610033
// Last chance to try to vectorize alternate node.
1001710034
if (MainOp && AltOp && TrySplitNode(InstructionsState(MainOp, AltOp)))
1001810035
return;
1001910036
}
10020-
if (TryToPackDuplicates)
10037+
if (SVL.tryToFindDuplicates())
1002110038
tryToFindDuplicates(VL, ReuseShuffleIndices, *TTI, *TLI, S, UserTreeIdx);
1002210039

1002310040
CreateGatherTreeEntry(S);

0 commit comments

Comments
 (0)