diff --git a/llvm/lib/Transforms/Utils/CodeLayout.cpp b/llvm/lib/Transforms/Utils/CodeLayout.cpp --- a/llvm/lib/Transforms/Utils/CodeLayout.cpp +++ b/llvm/lib/Transforms/Utils/CodeLayout.cpp @@ -67,6 +67,12 @@ "ext-tsp-backward-distance", cl::Hidden, cl::init(640), cl::desc("The maximum distance (in bytes) of a backward jump for ExtTSP")); +// The maximum size of a chain created by the algorithm. The size is bounded +// so that the algorithm can efficiently process extremely large instance. +static cl::opt + MaxChainSize("ext-tsp-max-chain-size", cl::Hidden, cl::init(4096), + cl::desc("The maximum size of a chain to create.")); + // The maximum size of a chain for splitting. Larger values of the threshold // may yield better quality at the cost of worsen run-time. static cl::opt ChainSplitThreshold( @@ -226,6 +232,8 @@ const std::vector &blocks() const { return Blocks; } + size_t numBlocks() const { return Blocks.size(); } + const std::vector> &edges() const { return Edges; } @@ -502,7 +510,7 @@ AllEdges.reserve(AllJumps.size()); for (auto &Block : AllBlocks) { for (auto &Jump : Block.OutJumps) { - const auto SuccBlock = Jump->Target; + auto SuccBlock = Jump->Target; auto CurEdge = Block.CurChain->getEdge(SuccBlock->CurChain); // this edge is already present in the graph if (CurEdge != nullptr) { @@ -592,6 +600,10 @@ if (ChainPred == ChainSucc) continue; + // Stop early if the combined chain violates the maximum allowed size + if (ChainPred->numBlocks() + ChainSucc->numBlocks() >= MaxChainSize) + continue; + // Compute the gain of merging the two chains auto CurGain = getBestMergeGain(ChainPred, ChainSucc, ChainEdge); if (CurGain.score() <= EPS)