Index: llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -85,11 +85,13 @@ ScheduleRegionSizeBudget("slp-schedule-budget", cl::init(100000), cl::Hidden, cl::desc("Limit the size of the SLP scheduling region per block")); +static cl::opt MinVectorRegSizeOption( + "slp-min-reg-size", cl::init(128), cl::Hidden, + cl::desc("Attempt to vectorize for this register size in bits")); + namespace { // FIXME: Set this via cl::opt to allow overriding. -static const unsigned MinVecRegSize = 128; - static const unsigned RecursionMaxDepth = 12; // Limit the number of alias checks. The limit is chosen so that @@ -3418,6 +3420,8 @@ else MaxVecRegSize = TTI->getRegisterBitWidth(true); + MinVecRegSize = MinVectorRegSizeOption; + // Don't vectorize when the attribute NoImplicitFloat is used. if (F.hasFnAttribute(Attribute::NoImplicitFloat)) return false; @@ -3531,6 +3535,7 @@ unsigned NumGEPs; unsigned MaxVecRegSize; // This is set by TTI or overridden by cl::opt. + unsigned MinVecRegSize; // Set by cl::opt (default: 128). }; /// \brief Check that the Values in the slice in VL array are still existent in @@ -3924,9 +3929,14 @@ /// The width of one full horizontal reduction operation. unsigned ReduxWidth; - HorizontalReduction() - : ReductionRoot(nullptr), ReductionPHI(nullptr), ReductionOpcode(0), - ReducedValueOpcode(0), IsPairwiseReduction(false), ReduxWidth(0) {} + /// Minimal width of available vector registers. It's used to determine + /// ReduxWidth. + unsigned MinVecRegSize; + + HorizontalReduction(unsigned MinVecRegSize) + : ReductionRoot(nullptr), ReductionPHI(nullptr), ReductionOpcode(0), + ReducedValueOpcode(0), IsPairwiseReduction(false), ReduxWidth(0), + MinVecRegSize(MinVecRegSize) {} /// \brief Try to find a reduction tree. bool matchAssociativeReduction(PHINode *Phi, BinaryOperator *B) { @@ -4254,11 +4264,12 @@ /// \returns true if a horizontal reduction was matched and reduced. /// \returns false if a horizontal reduction was not matched. static bool canMatchHorizontalReduction(PHINode *P, BinaryOperator *BI, - BoUpSLP &R, TargetTransformInfo *TTI) { + BoUpSLP &R, TargetTransformInfo *TTI, + unsigned MinRegSize) { if (!ShouldVectorizeHor) return false; - HorizontalReduction HorRdx; + HorizontalReduction HorRdx(MinRegSize); if (!HorRdx.matchAssociativeReduction(P, BI)) return false; @@ -4346,7 +4357,7 @@ continue; // Try to match and vectorize a horizontal reduction. - if (canMatchHorizontalReduction(P, BI, R, TTI)) { + if (canMatchHorizontalReduction(P, BI, R, TTI, MinVecRegSize)) { Changed = true; it = BB->begin(); e = BB->end(); @@ -4373,7 +4384,8 @@ if (StoreInst *SI = dyn_cast(it)) if (BinaryOperator *BinOp = dyn_cast(SI->getValueOperand())) { - if (canMatchHorizontalReduction(nullptr, BinOp, R, TTI) || + if (canMatchHorizontalReduction(nullptr, BinOp, R, TTI, + MinVecRegSize) || tryToVectorize(BinOp, R)) { Changed = true; it = BB->begin();