Skip to content

Commit dcd12cf

Browse files
committed
buildTree_rec(): Single point of definition for legality characteristics
1 parent 7179326 commit dcd12cf

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
@@ -4260,13 +4260,34 @@ class BoUpSLP {
42604260
bool areAltOperandsProfitable(const InstructionsState &S,
42614261
ArrayRef<Value *> VL) const;
42624262

4263+
/// Contains all the outputs of legality analysis for a list of values to
4264+
/// vectorize.
4265+
class ScalarsVectorizationLegality {
4266+
InstructionsState S;
4267+
bool IsLegal;
4268+
bool TryToFindDuplicates;
4269+
bool TrySplitVectorize;
4270+
4271+
public:
4272+
ScalarsVectorizationLegality(InstructionsState S, bool IsLegal,
4273+
bool TryToFindDuplicates = true,
4274+
bool TrySplitVectorize = false)
4275+
: S(S), IsLegal(IsLegal), TryToFindDuplicates(TryToFindDuplicates),
4276+
TrySplitVectorize(TrySplitVectorize) {
4277+
assert((!IsLegal || (S.valid() && TryToFindDuplicates)) &&
4278+
"Inconsistent state");
4279+
}
4280+
const InstructionsState &getInstructionsState() const { return S; };
4281+
bool isLegal() const { return IsLegal; }
4282+
bool tryToFindDuplicates() const { return TryToFindDuplicates; }
4283+
bool trySplitVectorize() const { return TrySplitVectorize; }
4284+
};
4285+
42634286
/// Checks if the specified list of the instructions/values can be vectorized
42644287
/// in general.
4265-
bool isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
4266-
const EdgeInfo &UserTreeIdx,
4267-
InstructionsState &S,
4268-
bool &TryToFindDuplicates,
4269-
bool &TrySplitVectorize) const;
4288+
ScalarsVectorizationLegality
4289+
getScalarsVectorizationLegality(ArrayRef<Value *> VL, unsigned Depth,
4290+
const EdgeInfo &UserTreeIdx) const;
42704291

42714292
/// Checks if the specified list of the instructions/values can be vectorized
42724293
/// and fills required data before actual scheduling of the instructions.
@@ -9764,25 +9785,21 @@ bool BoUpSLP::canBuildSplitNode(ArrayRef<Value *> VL,
97649785
return true;
97659786
}
97669787

9767-
bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
9768-
const EdgeInfo &UserTreeIdx,
9769-
InstructionsState &S,
9770-
bool &TryToFindDuplicates,
9771-
bool &TrySplitVectorize) const {
9788+
BoUpSLP::ScalarsVectorizationLegality
9789+
BoUpSLP::getScalarsVectorizationLegality(ArrayRef<Value *> VL, unsigned Depth,
9790+
const EdgeInfo &UserTreeIdx) const {
97729791
assert((allConstant(VL) || allSameType(VL)) && "Invalid types!");
97739792

9774-
S = getSameOpcode(VL, *TLI);
9775-
TryToFindDuplicates = true;
9776-
TrySplitVectorize = false;
9793+
InstructionsState S = getSameOpcode(VL, *TLI);
97779794

97789795
// Don't go into catchswitch blocks, which can happen with PHIs.
97799796
// Such blocks can only have PHIs and the catchswitch. There is no
97809797
// place to insert a shuffle if we need to, so just avoid that issue.
97819798
if (S && isa<CatchSwitchInst>(S.getMainOp()->getParent()->getTerminator())) {
97829799
LLVM_DEBUG(dbgs() << "SLP: bundle in catchswitch block.\n");
97839800
// Do not try to pack to avoid extra instructions here.
9784-
TryToFindDuplicates = false;
9785-
return false;
9801+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false,
9802+
/*TryToFindDuplicates=*/false);
97869803
}
97879804

97889805
// Check if this is a duplicate of another entry.
@@ -9792,14 +9809,14 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
97929809
if (E->isSame(VL)) {
97939810
LLVM_DEBUG(dbgs() << "SLP: Perfect diamond merge at " << *S.getMainOp()
97949811
<< ".\n");
9795-
return false;
9812+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
97969813
}
97979814
SmallPtrSet<Value *, 8> Values(llvm::from_range, E->Scalars);
97989815
if (all_of(VL, [&](Value *V) {
97999816
return isa<PoisonValue>(V) || Values.contains(V);
98009817
})) {
98019818
LLVM_DEBUG(dbgs() << "SLP: Gathering due to full overlap.\n");
9802-
return false;
9819+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
98039820
}
98049821
}
98059822
}
@@ -9816,23 +9833,23 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
98169833
cast<Instruction>(I)->getOpcode() == S.getOpcode();
98179834
})))) {
98189835
LLVM_DEBUG(dbgs() << "SLP: Gathering due to max recursion depth.\n");
9819-
return false;
9836+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
98209837
}
98219838

98229839
// Don't handle scalable vectors
98239840
if (S && S.getOpcode() == Instruction::ExtractElement &&
98249841
isa<ScalableVectorType>(
98259842
cast<ExtractElementInst>(S.getMainOp())->getVectorOperandType())) {
98269843
LLVM_DEBUG(dbgs() << "SLP: Gathering due to scalable vector type.\n");
9827-
return false;
9844+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
98289845
}
98299846

98309847
// Don't handle vectors.
98319848
if (!SLPReVec && getValueType(VL.front())->isVectorTy()) {
98329849
LLVM_DEBUG(dbgs() << "SLP: Gathering due to vector type.\n");
98339850
// Do not try to pack to avoid extra instructions here.
9834-
TryToFindDuplicates = false;
9835-
return false;
9851+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false,
9852+
/*TryToFindDuplicates=*/false);
98369853
}
98379854

98389855
// If all of the operands are identical or constant we have a simple solution.
@@ -9922,11 +9939,12 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
99229939
if (!S) {
99239940
LLVM_DEBUG(dbgs() << "SLP: Try split and if failed, gathering due to "
99249941
"C,S,B,O, small shuffle. \n");
9925-
TrySplitVectorize = true;
9926-
return false;
9942+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false,
9943+
/*TryToFindDuplicates=*/true,
9944+
/*TrySplitVectorize=*/true);
99279945
}
99289946
LLVM_DEBUG(dbgs() << "SLP: Gathering due to C,S,B,O, small shuffle. \n");
9929-
return false;
9947+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
99309948
}
99319949

99329950
// Don't vectorize ephemeral values.
@@ -9936,8 +9954,8 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
99369954
LLVM_DEBUG(dbgs() << "SLP: The instruction (" << *V
99379955
<< ") is ephemeral.\n");
99389956
// Do not try to pack to avoid extra instructions here.
9939-
TryToFindDuplicates = false;
9940-
return false;
9957+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false,
9958+
/*TryToFindDuplicates=*/false);
99419959
}
99429960
}
99439961
}
@@ -9986,7 +10004,7 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
998610004
if (PreferScalarize) {
998710005
LLVM_DEBUG(dbgs() << "SLP: The instructions are in tree and alternate "
998810006
"node is not profitable.\n");
9989-
return false;
10007+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
999010008
}
999110009
}
999210010

@@ -9995,7 +10013,7 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
999510013
for (Value *V : VL) {
999610014
if (UserIgnoreList->contains(V)) {
999710015
LLVM_DEBUG(dbgs() << "SLP: Gathering due to gathered scalar.\n");
9998-
return false;
10016+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
999910017
}
1000010018
}
1000110019
}
@@ -10025,9 +10043,9 @@ bool BoUpSLP::isLegalToVectorizeScalars(ArrayRef<Value *> VL, unsigned Depth,
1002510043
// Do not vectorize EH and non-returning blocks, not profitable in most
1002610044
// cases.
1002710045
LLVM_DEBUG(dbgs() << "SLP: bundle in unreachable block.\n");
10028-
return false;
10046+
return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
1002910047
}
10030-
return true;
10048+
return ScalarsVectorizationLegality(S, /*IsLegal=*/true);
1003110049
}
1003210050

1003310051
void BoUpSLP::buildTreeRec(ArrayRef<Value *> VLRef, unsigned Depth,
@@ -10038,7 +10056,6 @@ void BoUpSLP::buildTreeRec(ArrayRef<Value *> VLRef, unsigned Depth,
1003810056
SmallVector<int> ReuseShuffleIndices;
1003910057
SmallVector<Value *> VL(VLRef.begin(), VLRef.end());
1004010058

10041-
InstructionsState S = InstructionsState::invalid();
1004210059
// Tries to build split node.
1004310060
auto TrySplitNode = [&](const InstructionsState &LocalState) {
1004410061
SmallVector<Value *> Op1, Op2;
@@ -10072,17 +10089,17 @@ void BoUpSLP::buildTreeRec(ArrayRef<Value *> VLRef, unsigned Depth,
1007210089
return true;
1007310090
};
1007410091

10075-
bool TryToPackDuplicates;
10076-
bool TrySplitVectorize;
10077-
if (!isLegalToVectorizeScalars(VL, Depth, UserTreeIdx, S, TryToPackDuplicates,
10078-
TrySplitVectorize)) {
10079-
if (TrySplitVectorize) {
10092+
ScalarsVectorizationLegality SVL =
10093+
getScalarsVectorizationLegality(VL, Depth, UserTreeIdx);
10094+
const InstructionsState &S = SVL.getInstructionsState();
10095+
if (!SVL.isLegal()) {
10096+
if (SVL.trySplitVectorize()) {
1008010097
auto [MainOp, AltOp] = getMainAltOpsNoStateVL(VL);
1008110098
// Last chance to try to vectorize alternate node.
1008210099
if (MainOp && AltOp && TrySplitNode(InstructionsState(MainOp, AltOp)))
1008310100
return;
1008410101
}
10085-
if (TryToPackDuplicates)
10102+
if (SVL.tryToFindDuplicates())
1008610103
tryToFindDuplicates(VL, ReuseShuffleIndices, *TTI, *TLI, S, UserTreeIdx);
1008710104

1008810105
newGatherTreeEntry(VL, S, UserTreeIdx, ReuseShuffleIndices);

0 commit comments

Comments
 (0)