diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -2369,14 +2369,42 @@ // Helper function that checks whether a function has any cycle. // TODO: Replace with more efficent code static bool containsCycle(Function &F) { - SmallPtrSet Visited; + bool noAnalysis = false; - // Traverse BB by dfs and check whether successor is already visited. - for (BasicBlock *BB : depth_first(&F)) { - Visited.insert(BB); - for (auto *SuccBB : successors(BB)) { - if (Visited.count(SuccBB)) - return true; + ScalarEvolution *SE = + A.getInfoCache().getAnalysisResultForFunction(F); + LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction(F); + + if (!LI || !SE) { + noAnalysis = true; + } + + for (scc_iterator I = scc_begin(&F), IE = scc_end(&F); I != IE; + ++I) { + const std::vector &SCCBBs = *I; + // when noAnalysis available then check only if the SCC has loop or not + if (noAnalysis) { + if (I.hasLoop()) return true; + continue; + } + // when current SCC has a single block with no loop continue to the next SCC + if (!I.hasLoop()) continue; + + std::vector::const_iterator BBI = SCCBBs.begin(); + Loop *L = LI->getLoopFor(*BBI); + if (!L) { + return true; + } + if (L->getNumBlocks() > SCCBBs.size()) return true; + if (L->getNumBlocks() == SCCBBs.size()) { + if (!SE->getSmallConstantMaxTripCount(L)) return true; + continue; + } + L = L->getParentLoop(); + if (L->getNumBlocks() > SCCBBs.size()) return true; + if (L->getNumBlocks() == SCCBBs.size()) { + if (!SE->getSmallConstantMaxTripCount(L)) return true; + continue; } } return false;