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 @@ -2368,14 +2368,22 @@ // Helper function that checks whether a function has any cycle. // TODO: Replace with more efficent code -static bool containsCycle(Function &F) { - SmallPtrSet Visited; - - // 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)) +static bool containsCycle(Function &F,Attributor &A) { + for (scc_iterator I = scc_begin(&F), IE = scc_end(&F); I != IE; + ++I) { + const std::vector &SCCBBs = *I; + ScalarEvolution *SE = + A.getInfoCache().getAnalysisResultForFunction( + F); + LoopInfo *LI = + A.getInfoCache().getAnalysisResultForFunction(F); + if (!LI || !SE) continue; + std::vector::const_iterator BBI = SCCBBs.begin(); + Loop *L = LI->getLoopFor(*BBI); + L = L->getParentLoop(); + if (L) { + if (L->getNumBlocks() == SCCBBs.size() && + !SE->getSmallConstantMaxTripCount(L)) return true; } } @@ -2386,8 +2394,8 @@ // endless loop // FIXME: Any cycle is regarded as endless loop for now. // We have to allow some patterns. -static bool containsPossiblyEndlessLoop(Function *F) { - return !F || !F->hasExactDefinition() || containsCycle(*F); +static bool containsPossiblyEndlessLoop(Function *F,Attributor &A) { + return !F || !F->hasExactDefinition() || containsCycle(*F,A); } struct AAWillReturnImpl : public AAWillReturn { @@ -2398,7 +2406,7 @@ AAWillReturn::initialize(A); Function *F = getAssociatedFunction(); - if (containsPossiblyEndlessLoop(F)) + if (containsPossiblyEndlessLoop(F,A)) indicatePessimisticFixpoint(); } @@ -7374,7 +7382,7 @@ for (Instruction *I : OpcodeInstMap[Opcode]) { // Skip dead instructions. if (A && A->isAssumedDead(IRPosition::value(*I), QueryingAA, LivenessAA, - CheckBBLivenessOnly)) + CheckBBLivenessOnly)) continue; if (!Pred(*I))