Index: include/llvm/Analysis/CallGraphSCCPass.h =================================================================== --- include/llvm/Analysis/CallGraphSCCPass.h +++ include/llvm/Analysis/CallGraphSCCPass.h @@ -57,7 +57,9 @@ /// SCC passes that add or delete functions to the SCC are required to update /// the SCC list, otherwise stale pointers may be dereferenced. /// - virtual bool runOnSCC(CallGraphSCC &SCC) = 0; + /// If the SCC pass requires the entire CGSCC pipeline to rerun on + /// the current SCC. Set Devirt to true. + virtual bool runOnSCC(CallGraphSCC &SCC, bool& Devirt) = 0; /// doFinalization - This method is called after the SCC's of the program has /// been processed, allowing the pass to do final cleanup as necessary. Index: include/llvm/Transforms/IPO/InlinerPass.h =================================================================== --- include/llvm/Transforms/IPO/InlinerPass.h +++ include/llvm/Transforms/IPO/InlinerPass.h @@ -40,7 +40,7 @@ // Main run interface method, this implements the interface required by the // Pass class. - bool runOnSCC(CallGraphSCC &SCC) override; + bool runOnSCC(CallGraphSCC &SCC, bool& Devirt) override; using llvm::Pass::doFinalization; // doFinalization - Remove now-dead linkonce functions at the end of Index: lib/Analysis/CallGraphSCCPass.cpp =================================================================== --- lib/Analysis/CallGraphSCCPass.cpp +++ lib/Analysis/CallGraphSCCPass.cpp @@ -123,7 +123,7 @@ { TimeRegion PassTimer(getPassTimer(CGSP)); - Changed = CGSP->runOnSCC(CurSCC); + Changed = CGSP->runOnSCC(CurSCC, DevirtualizedCall); } // After the CGSCCPass is done, when assertions are enabled, use @@ -609,7 +609,7 @@ AU.setPreservesAll(); } - bool runOnSCC(CallGraphSCC &SCC) override { + bool runOnSCC(CallGraphSCC &SCC, bool& Devirt) override { Out << Banner; for (CallGraphNode *CGN : SCC) { if (CGN->getFunction()) { Index: lib/Transforms/Coroutines/CoroInline.cpp =================================================================== --- lib/Transforms/Coroutines/CoroInline.cpp +++ lib/Transforms/Coroutines/CoroInline.cpp @@ -45,7 +45,7 @@ static char ID; // Pass identification, replacement for typeid - bool runOnSCC(CallGraphSCC &SCC) override { + bool runOnSCC(CallGraphSCC &SCC, bool& Devirt) override { bool changed = false; for (CallGraphNode *CGN : SCC) Index: lib/Transforms/Coroutines/CoroSplit.cpp =================================================================== --- lib/Transforms/Coroutines/CoroSplit.cpp +++ lib/Transforms/Coroutines/CoroSplit.cpp @@ -259,7 +259,7 @@ } #endif - bool runOnSCC(CallGraphSCC &SCC) override { + bool runOnSCC(CallGraphSCC &SCC, bool& Devirt) override { // find coroutines for processing SmallVector CIs; for (CallGraphNode *CGN : SCC) @@ -274,8 +274,10 @@ CoroutineShape Shape; for (CoroInitInst* CoroInit : CIs) - if (CoroInit->meta().getPhase() == Phase::NotReadyForSplit) + if (CoroInit->meta().getPhase() == Phase::NotReadyForSplit) { preSplitPass(CoroInit, SCC); + Devirt = true; + } else splitCoroutine(CoroInit, Shape); Index: lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- lib/Transforms/IPO/ArgumentPromotion.cpp +++ lib/Transforms/IPO/ArgumentPromotion.cpp @@ -73,7 +73,7 @@ CallGraphSCCPass::getAnalysisUsage(AU); } - bool runOnSCC(CallGraphSCC &SCC) override; + bool runOnSCC(CallGraphSCC &SCC, bool& Devirt) override; static char ID; // Pass identification, replacement for typeid explicit ArgPromotion(unsigned maxElements = 3) : CallGraphSCCPass(ID), maxElements(maxElements) { @@ -113,7 +113,7 @@ return new ArgPromotion(maxElements); } -bool ArgPromotion::runOnSCC(CallGraphSCC &SCC) { +bool ArgPromotion::runOnSCC(CallGraphSCC &SCC, bool& Devirt) { bool Changed = false, LocalChange; do { // Iterate until we stop promoting from this SCC. Index: lib/Transforms/IPO/FunctionAttrs.cpp =================================================================== --- lib/Transforms/IPO/FunctionAttrs.cpp +++ lib/Transforms/IPO/FunctionAttrs.cpp @@ -1051,7 +1051,7 @@ initializePostOrderFunctionAttrsLegacyPassPass(*PassRegistry::getPassRegistry()); } - bool runOnSCC(CallGraphSCC &SCC) override; + bool runOnSCC(CallGraphSCC &SCC, bool& Devirt) override; void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); @@ -1077,7 +1077,8 @@ Pass *llvm::createPostOrderFunctionAttrsLegacyPass() { return new PostOrderFunctionAttrsLegacyPass(); } -bool PostOrderFunctionAttrsLegacyPass::runOnSCC(CallGraphSCC &SCC) { +bool PostOrderFunctionAttrsLegacyPass::runOnSCC(CallGraphSCC &SCC, + bool &Devirt) { TLI = &getAnalysis().getTLI(); bool Changed = false; Index: lib/Transforms/IPO/InlineSimple.cpp =================================================================== --- lib/Transforms/IPO/InlineSimple.cpp +++ lib/Transforms/IPO/InlineSimple.cpp @@ -62,7 +62,7 @@ return llvm::getInlineCost(CS, DefaultThreshold, TTI, ACT); } - bool runOnSCC(CallGraphSCC &SCC) override; + bool runOnSCC(CallGraphSCC &SCC, bool& Devirt) override; void getAnalysisUsage(AnalysisUsage &AU) const override; private: @@ -93,9 +93,9 @@ llvm::computeThresholdFromOptLevels(OptLevel, SizeOptLevel)); } -bool SimpleInliner::runOnSCC(CallGraphSCC &SCC) { +bool SimpleInliner::runOnSCC(CallGraphSCC &SCC, bool& Devirt) { TTIWP = &getAnalysis(); - return Inliner::runOnSCC(SCC); + return Inliner::runOnSCC(SCC, Devirt); } void SimpleInliner::getAnalysisUsage(AnalysisUsage &AU) const { Index: lib/Transforms/IPO/Inliner.cpp =================================================================== --- lib/Transforms/IPO/Inliner.cpp +++ lib/Transforms/IPO/Inliner.cpp @@ -356,7 +356,7 @@ return false; } -bool Inliner::runOnSCC(CallGraphSCC &SCC) { +bool Inliner::runOnSCC(CallGraphSCC &SCC, bool& Devirt) { CallGraph &CG = getAnalysis().getCallGraph(); ACT = &getAnalysis(); auto &TLI = getAnalysis().getTLI(); Index: lib/Transforms/IPO/PruneEH.cpp =================================================================== --- lib/Transforms/IPO/PruneEH.cpp +++ lib/Transforms/IPO/PruneEH.cpp @@ -46,7 +46,7 @@ } // runOnSCC - Analyze the SCC, performing the transformation if possible. - bool runOnSCC(CallGraphSCC &SCC) override; + bool runOnSCC(CallGraphSCC &SCC, bool& Devirt) override; bool SimplifyFunction(Function *F); void DeleteBasicBlock(BasicBlock *BB); @@ -63,7 +63,7 @@ Pass *llvm::createPruneEHPass() { return new PruneEH(); } -bool PruneEH::runOnSCC(CallGraphSCC &SCC) { +bool PruneEH::runOnSCC(CallGraphSCC &SCC, bool& Devirt) { SmallPtrSet SCCNodes; CallGraph &CG = getAnalysis().getCallGraph(); bool MadeChange = false; Index: tools/opt/PassPrinters.cpp =================================================================== --- tools/opt/PassPrinters.cpp +++ tools/opt/PassPrinters.cpp @@ -69,7 +69,7 @@ PassName = "CallGraphSCCPass Printer: " + PassToPrintName; } - bool runOnSCC(CallGraphSCC &SCC) override { + bool runOnSCC(CallGraphSCC &SCC, bool& Devirt) override { if (!QuietPass) Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";