diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -153,6 +153,21 @@ "slp-max-look-ahead-depth", cl::init(2), cl::Hidden, cl::desc("The maximum look-ahead depth for operand reordering scores")); +// Look-ahead explores the operands of the bundle. To avoid compilation time +// increase we limit the number of operands visited to this value. +static cl::opt LookAheadOperandsBudget( + "slp-look-ahead-operands-budget", cl::init(2), cl::Hidden, + cl::desc("The maximum number of operands to consider while visiting the " + "predecessors. This prevents compilation time increase")); + +// Look-ahead goes through the users ot the bundle to calculate the users cost +// in getExternalUsesCost(). To avoid compilation time increase we limit the +// number of users visited to this value. +static cl::opt LookAheadUsersBudget( + "slp-look-ahead-users-budget", cl::init(2), cl::Hidden, + cl::desc("The maximum number of users to visit while visiting the " + "predecessors. This prevents compilation time increase.")); + static cl::opt ViewSLPTree("view-slp-tree", cl::Hidden, cl::desc("Display the SLP trees with Graphviz")); @@ -817,6 +832,7 @@ // and RHS as base and Idx as the offset. int Ln = std::min(LHS.second, RHS.second) + Idx; assert(Ln >= 0 && "Bad lane calculation"); + unsigned UsersBudget = LookAheadUsersBudget; for (User *U : V->users()) { if (const TreeEntry *UserTE = R.getTreeEntry(U)) { // The user is in the VectorizableTree. Check if we need to insert. @@ -838,6 +854,9 @@ Cost += ExternalUseCost; } } + // Limit the number of visited uses to cap compilation time. + if (--UsersBudget == 0) + break; } } return Cost; @@ -898,7 +917,9 @@ // Recursion towards the operands of I1 and I2. We are trying all possbile // operand pairs, and keeping track of the best score. - for (unsigned OpIdx1 = 0, NumOperands1 = I1->getNumOperands(); + for (unsigned OpIdx1 = 0, + NumOperands1 = std::min(I1->getNumOperands(), + LookAheadOperandsBudget.getValue()); OpIdx1 != NumOperands1; ++OpIdx1) { // Try to pair op1I with the best operand of I2. int MaxTmpScore = 0; @@ -906,8 +927,10 @@ bool FoundBest = false; // If I2 is commutative try all combinations. unsigned FromIdx = isCommutative(I2) ? 0 : OpIdx1; + // Limit the number of operands to visit to reduce compilation time. unsigned ToIdx = isCommutative(I2) - ? I2->getNumOperands() + ? std::min(I2->getNumOperands(), + LookAheadOperandsBudget.getValue()) : std::min(I2->getNumOperands(), OpIdx1 + 1); assert(FromIdx <= ToIdx && "Bad index"); for (unsigned OpIdx2 = FromIdx; OpIdx2 != ToIdx; ++OpIdx2) {