@@ -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
99629980void 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