diff --git a/llvm/include/llvm/Transforms/IPO/Inliner.h b/llvm/include/llvm/Transforms/IPO/Inliner.h --- a/llvm/include/llvm/Transforms/IPO/Inliner.h +++ b/llvm/include/llvm/Transforms/IPO/Inliner.h @@ -157,6 +157,7 @@ CGSCCPassManager PM; ModulePassManager MPM; ModulePassManager AfterCGMPM; + bool MPMFinalized; }; } // end namespace llvm diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -1118,7 +1118,7 @@ InliningAdvisorMode Mode, unsigned MaxDevirtIterations) : Params(Params), IC(IC), Mode(Mode), - MaxDevirtIterations(MaxDevirtIterations) { + MaxDevirtIterations(MaxDevirtIterations), MPMFinalized(false) { // Run the inliner first. The theory is that we are walking bottom-up and so // the callees have already been fully optimized, and we want to inline them // into the callers so that our optimizations can reflect that. @@ -1149,20 +1149,23 @@ return PreservedAnalyses::all(); } - // We wrap the CGSCC pipeline in a devirtualization repeater. This will try - // to detect when we devirtualize indirect calls and iterate the SCC passes - // in that case to try and catch knock-on inlining or function attrs - // opportunities. Then we add it to the module pipeline by walking the SCCs - // in postorder (or bottom-up). - // If MaxDevirtIterations is 0, we just don't use the devirtualization - // wrapper. - if (MaxDevirtIterations == 0) - MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(PM))); - else - MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor( - createDevirtSCCRepeatedPass(std::move(PM), MaxDevirtIterations))); - - MPM.addPass(std::move(AfterCGMPM)); + if (!MPMFinalized) { + // We wrap the CGSCC pipeline in a devirtualization repeater. This will try + // to detect when we devirtualize indirect calls and iterate the SCC passes + // in that case to try and catch knock-on inlining or function attrs + // opportunities. Then we add it to the module pipeline by walking the SCCs + // in postorder (or bottom-up). + // If MaxDevirtIterations is 0, we just don't use the devirtualization + // wrapper. + if (MaxDevirtIterations == 0) + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(PM))); + else + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor( + createDevirtSCCRepeatedPass(std::move(PM), MaxDevirtIterations))); + + MPM.addPass(std::move(AfterCGMPM)); + MPMFinalized = true; + } MPM.run(M, MAM); // Discard the InlineAdvisor, a subsequent inlining session should construct