Index: include/llvm/Analysis/CallGraphSCCPass.h =================================================================== --- include/llvm/Analysis/CallGraphSCCPass.h +++ include/llvm/Analysis/CallGraphSCCPass.h @@ -59,6 +59,11 @@ /// virtual bool runOnSCC(CallGraphSCC &SCC) = 0; + /// This methods is invoked by CGManager::RunPassOnSCC after each call + /// to RunOnSCC to query the pass if there were any change made that + /// require rerunning pipeline again. + virtual bool restartRequested() const { return false; } + /// doFinalization - This method is called after the SCC's of the program has /// been processed, allowing the pass to do final cleanup as necessary. virtual bool doFinalization(CallGraph &CG) { Index: lib/Analysis/CallGraphSCCPass.cpp =================================================================== --- lib/Analysis/CallGraphSCCPass.cpp +++ lib/Analysis/CallGraphSCCPass.cpp @@ -123,7 +123,15 @@ { TimeRegion PassTimer(getPassTimer(CGSP)); - Changed = CGSP->runOnSCC(CurSCC); + if (CGSP->runOnSCC(CurSCC)) { + Changed = true; + + if (CGSP->restartRequested()) { + DEBUG(dbgs() << " CGSCCPASSMGR: Pipeline restart requested by '" + << CGSP->getPassName() << "'\n"); + DevirtualizedCall = true; + } + } } // After the CGSCCPass is done, when assertions are enabled, use Index: lib/Transforms/Coroutines/CoroSplit.cpp =================================================================== --- lib/Transforms/Coroutines/CoroSplit.cpp +++ lib/Transforms/Coroutines/CoroSplit.cpp @@ -237,8 +237,12 @@ static char ID; // Pass identification, replacement for typeid CoroSplit() : CallGraphSCCPass(ID) {} - bool runOnSCC(CallGraphSCC &SCC) override { + bool needToRestart; + + bool restartRequested() const override { return needToRestart; } + bool runOnSCC(CallGraphSCC &SCC) override { + needToRestart = false; // find coroutines for processing SmallVector CIs; for (CallGraphNode *CGN : SCC) @@ -253,8 +257,10 @@ CoroutineShape Shape; for (CoroInitInst* CoroInit : CIs) - if (CoroInit->meta().getPhase() == Phase::NotReadyForSplit) + if (CoroInit->meta().getPhase() == Phase::NotReadyForSplit) { preSplitPass(CoroInit, SCC); + needToRestart = true; + } else splitCoroutine(CoroInit, Shape);