diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -851,9 +851,10 @@ PrintPassOptions PrintPassOpts; PrintPassOpts.Indent = DebugPassStructure; PrintPassOpts.SkipAnalyses = DebugPassStructure; - StandardInstrumentations SI(CodeGenOpts.DebugPassManager || - DebugPassStructure, - /*VerifyEach*/ false, PrintPassOpts); + StandardInstrumentations SI( + TheModule->getContext(), + (CodeGenOpts.DebugPassManager || DebugPassStructure), + /*VerifyEach*/ false, PrintPassOpts); SI.registerCallbacks(PIC, &FAM); PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC); diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -694,7 +694,8 @@ llvm::PassInstrumentationCallbacks pic; llvm::PipelineTuningOptions pto; llvm::Optional pgoOpt; - llvm::StandardInstrumentations si(opts.DebugPassManager); + llvm::StandardInstrumentations si( + llvmModule->getContext(), opts.DebugPassManager); si.registerCallbacks(pic, &fam); llvm::PassBuilder pb(tm.get(), pto, pgoOpt, &pic); diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h --- a/llvm/include/llvm/IR/OptBisect.h +++ b/llvm/include/llvm/IR/OptBisect.h @@ -29,7 +29,8 @@ /// IRDescription is a textual description of the IR unit the pass is running /// over. - virtual bool shouldRunPass(const Pass *P, StringRef IRDescription) { + virtual bool shouldRunPass(const StringRef PassName, + StringRef IRDescription) { return true; } @@ -55,7 +56,8 @@ /// Checks the bisect limit to determine if the specified pass should run. /// /// This forwards to checkPass(). - bool shouldRunPass(const Pass *P, StringRef IRDescription) override; + bool shouldRunPass(const StringRef PassName, + StringRef IRDescription) override; /// isEnabled() should return true before calling shouldRunPass(). bool isEnabled() const override { return BisectLimit != Disabled; } @@ -89,7 +91,7 @@ /// Singleton instance of the OptBisect class, so multiple pass managers don't /// need to coordinate their uses of OptBisect. -OptBisect &getOptBisector(); +OptPassGate &getGlobalPassGate(); } // end namespace llvm diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h --- a/llvm/include/llvm/Passes/StandardInstrumentations.h +++ b/llvm/include/llvm/Passes/StandardInstrumentations.h @@ -74,11 +74,12 @@ bool shouldRun(StringRef PassID, Any IR); }; -class OptBisectInstrumentation { +class OptPassGateInstrumentation { + LLVMContext &Context; bool HasWrittenIR = false; - public: - OptBisectInstrumentation() = default; + OptPassGateInstrumentation(LLVMContext &Context) : Context(Context) {} + bool shouldRun(StringRef PassName, Any IR); void registerCallbacks(PassInstrumentationCallbacks &PIC); }; @@ -528,7 +529,7 @@ TimePassesHandler TimePasses; TimeProfilingPassesHandler TimeProfilingPasses; OptNoneInstrumentation OptNone; - OptBisectInstrumentation OptBisect; + OptPassGateInstrumentation OptPassGate; PreservedCFGCheckerInstrumentation PreservedCFGChecker; IRChangedPrinter PrintChangedIR; PseudoProbeVerifier PseudoProbeVerification; @@ -540,7 +541,8 @@ bool VerifyEach; public: - StandardInstrumentations(bool DebugLogging, bool VerifyEach = false, + StandardInstrumentations(LLVMContext &Context, bool DebugLogging, + bool VerifyEach = false, PrintPassOptions PrintPassOpts = PrintPassOptions()); // Register all the standard instrumentation callbacks. If \p FAM is nullptr diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp --- a/llvm/lib/Analysis/CallGraphSCCPass.cpp +++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp @@ -751,7 +751,8 @@ bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC) const { OptPassGate &Gate = SCC.getCallGraph().getModule().getContext().getOptPassGate(); - return Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(SCC)); + return Gate.isEnabled() && + !Gate.shouldRunPass(this->getPassName(), getDescription(SCC)); } char DummyCGSCCPass::ID = 0; diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp --- a/llvm/lib/Analysis/LoopPass.cpp +++ b/llvm/lib/Analysis/LoopPass.cpp @@ -373,7 +373,8 @@ return false; // Check the opt bisect limit. OptPassGate &Gate = F->getContext().getOptPassGate(); - if (Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(*L))) + if (Gate.isEnabled() && + !Gate.shouldRunPass(this->getPassName(), getDescription(*L))) return true; // Check for the OptimizeNone attribute. if (F->hasOptNone()) { diff --git a/llvm/lib/Analysis/RegionPass.cpp b/llvm/lib/Analysis/RegionPass.cpp --- a/llvm/lib/Analysis/RegionPass.cpp +++ b/llvm/lib/Analysis/RegionPass.cpp @@ -283,7 +283,8 @@ bool RegionPass::skipRegion(Region &R) const { Function &F = *R.getEntry()->getParent(); OptPassGate &Gate = F.getContext().getOptPassGate(); - if (Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(R))) + if (Gate.isEnabled() && + !Gate.shouldRunPass(this->getPassName(), getDescription(R))) return true; if (F.hasOptNone()) { diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -240,7 +240,7 @@ /// singleton OptBisect if not explicitly set. OptPassGate &LLVMContextImpl::getOptPassGate() const { if (!OPG) - OPG = &getOptBisector(); + OPG = &getGlobalPassGate(); return *OPG; } diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp --- a/llvm/lib/IR/OptBisect.cpp +++ b/llvm/lib/IR/OptBisect.cpp @@ -20,10 +20,15 @@ using namespace llvm; +static OptBisect &getOptBisector() { + static OptBisect OptBisector; + return OptBisector; +} + static cl::opt OptBisectLimit("opt-bisect-limit", cl::Hidden, cl::init(OptBisect::Disabled), cl::Optional, cl::cb([](int Limit) { - llvm::getOptBisector().setLimit(Limit); + getOptBisector().setLimit(Limit); }), cl::desc("Maximum optimization to perform")); @@ -34,25 +39,16 @@ << "(" << PassNum << ") " << Name << " on " << TargetDesc << "\n"; } -bool OptBisect::shouldRunPass(const Pass *P, StringRef IRDescription) { - assert(isEnabled()); - - return checkPass(P->getPassName(), IRDescription); -} - -bool OptBisect::checkPass(const StringRef PassName, - const StringRef TargetDesc) { +bool OptBisect::shouldRunPass(const StringRef PassName, + StringRef IRDescription) { assert(isEnabled()); int CurBisectNum = ++LastBisectNum; bool ShouldRun = (BisectLimit == -1 || CurBisectNum <= BisectLimit); - printPassMessage(PassName, CurBisectNum, TargetDesc, ShouldRun); + printPassMessage(PassName, CurBisectNum, IRDescription, ShouldRun); return ShouldRun; } const int OptBisect::Disabled; -OptBisect &llvm::getOptBisector() { - static OptBisect OptBisector; - return OptBisector; -} +OptPassGate &llvm::getGlobalPassGate() { return getOptBisector(); } diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp --- a/llvm/lib/IR/Pass.cpp +++ b/llvm/lib/IR/Pass.cpp @@ -62,7 +62,8 @@ bool ModulePass::skipModule(Module &M) const { OptPassGate &Gate = M.getContext().getOptPassGate(); - return Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(M)); + return Gate.isEnabled() && + !Gate.shouldRunPass(this->getPassName(), getDescription(M)); } bool Pass::mustPreserveAnalysisID(char &AID) const { @@ -172,7 +173,8 @@ bool FunctionPass::skipFunction(const Function &F) const { OptPassGate &Gate = F.getContext().getOptPassGate(); - if (Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(F))) + if (Gate.isEnabled() && + !Gate.shouldRunPass(this->getPassName(), getDescription(F))) return true; if (F.hasOptNone()) { diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -256,7 +256,7 @@ ModuleAnalysisManager MAM; PassInstrumentationCallbacks PIC; - StandardInstrumentations SI(Conf.DebugPassManager); + StandardInstrumentations SI(Mod.getContext(), Conf.DebugPassManager); SI.registerCallbacks(PIC, &FAM); PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC); diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -244,7 +244,7 @@ ModuleAnalysisManager MAM; PassInstrumentationCallbacks PIC; - StandardInstrumentations SI(DebugPassManager); + StandardInstrumentations SI(TheModule.getContext(), DebugPassManager); SI.registerCallbacks(PIC, &FAM); PipelineTuningOptions PTO; PTO.LoopVectorization = true; diff --git a/llvm/lib/Passes/PassBuilderBindings.cpp b/llvm/lib/Passes/PassBuilderBindings.cpp --- a/llvm/lib/Passes/PassBuilderBindings.cpp +++ b/llvm/lib/Passes/PassBuilderBindings.cpp @@ -65,7 +65,7 @@ PB.registerModuleAnalyses(MAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); - StandardInstrumentations SI(Debug, VerifyEach); + StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach); SI.registerCallbacks(PIC, &FAM); ModulePassManager MPM; if (VerifyEach) { diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp --- a/llvm/lib/Passes/StandardInstrumentations.cpp +++ b/llvm/lib/Passes/StandardInstrumentations.cpp @@ -767,27 +767,35 @@ return ShouldRun; } -void OptBisectInstrumentation::registerCallbacks( +bool OptPassGateInstrumentation::shouldRun(StringRef PassName, Any IR) { + if (isIgnored(PassName)) + return true; + + bool ShouldRun = + Context.getOptPassGate().shouldRunPass(PassName, getIRName(IR)); + if (!ShouldRun && !this->HasWrittenIR && !OptBisectPrintIRPath.empty()) { + // FIXME: print IR if limit is higher than number of opt-bisect + // invocations + this->HasWrittenIR = true; + const Module *M = unwrapModule(IR, /*Force=*/true); + assert((M && &M->getContext() == &Context) && "Missing/Mismatching Module"); + std::error_code EC; + raw_fd_ostream OS(OptBisectPrintIRPath, EC); + if (EC) + report_fatal_error(errorCodeToError(EC)); + M->print(OS, nullptr); + } + return ShouldRun; +} + +void OptPassGateInstrumentation::registerCallbacks( PassInstrumentationCallbacks &PIC) { - if (!getOptBisector().isEnabled()) + OptPassGate &PassGate = Context.getOptPassGate(); + if (!PassGate.isEnabled()) return; - PIC.registerShouldRunOptionalPassCallback([this](StringRef PassID, Any IR) { - if (isIgnored(PassID)) - return true; - bool ShouldRun = getOptBisector().checkPass(PassID, getIRName(IR)); - if (!ShouldRun && !this->HasWrittenIR && !OptBisectPrintIRPath.empty()) { - // FIXME: print IR if limit is higher than number of opt-bisect - // invocations - this->HasWrittenIR = true; - const Module *M = unwrapModule(IR, /*Force=*/true); - assert(M && "expected Module"); - std::error_code EC; - raw_fd_ostream OS(OptBisectPrintIRPath, EC); - if (EC) - report_fatal_error(errorCodeToError(EC)); - M->print(OS, nullptr); - } - return ShouldRun; + + PIC.registerShouldRunOptionalPassCallback([this](StringRef PassName, Any IR) { + return this->shouldRun(PassName, IR); }); } @@ -2037,8 +2045,11 @@ } StandardInstrumentations::StandardInstrumentations( - bool DebugLogging, bool VerifyEach, PrintPassOptions PrintPassOpts) - : PrintPass(DebugLogging, PrintPassOpts), OptNone(DebugLogging), + LLVMContext &Context, bool DebugLogging, bool VerifyEach, + PrintPassOptions PrintPassOpts) + : PrintPass(DebugLogging, PrintPassOpts), + OptNone(DebugLogging), + OptPassGate(Context), PrintChangedIR(PrintChanged == ChangePrinter::Verbose), PrintChangedDiff(PrintChanged == ChangePrinter::DiffVerbose || PrintChanged == ChangePrinter::ColourDiffVerbose, @@ -2099,7 +2110,7 @@ PrintPass.registerCallbacks(PIC); TimePasses.registerCallbacks(PIC); OptNone.registerCallbacks(PIC); - OptBisect.registerCallbacks(PIC); + OptPassGate.registerCallbacks(PIC); if (FAM) PreservedCFGChecker.registerCallbacks(PIC, *FAM); PrintChangedIR.registerCallbacks(PIC); diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -354,8 +354,8 @@ PrintPassOptions PrintPassOpts; PrintPassOpts.Verbose = DebugPM == DebugLogging::Verbose; PrintPassOpts.SkipAnalyses = DebugPM == DebugLogging::Quiet; - StandardInstrumentations SI(DebugPM != DebugLogging::None, VerifyEachPass, - PrintPassOpts); + StandardInstrumentations SI(M.getContext(), DebugPM != DebugLogging::None, + VerifyEachPass, PrintPassOpts); SI.registerCallbacks(PIC, &FAM); DebugifyEachInstrumentation Debugify; DebugifyStatsMap DIStatsMap; diff --git a/llvm/unittests/IR/LegacyPassManagerTest.cpp b/llvm/unittests/IR/LegacyPassManagerTest.cpp --- a/llvm/unittests/IR/LegacyPassManagerTest.cpp +++ b/llvm/unittests/IR/LegacyPassManagerTest.cpp @@ -359,10 +359,8 @@ struct CustomOptPassGate : public OptPassGate { bool Skip; CustomOptPassGate(bool Skip) : Skip(Skip) { } - bool shouldRunPass(const Pass *P, StringRef IRDescription) override { - if (P->getPassKind() == PT_Module) - return !Skip; - return OptPassGate::shouldRunPass(P, IRDescription); + bool shouldRunPass(const StringRef PassName, StringRef IRDescription) override { + return !Skip; } bool isEnabled() const override { return true; } }; diff --git a/llvm/unittests/IR/PassManagerTest.cpp b/llvm/unittests/IR/PassManagerTest.cpp --- a/llvm/unittests/IR/PassManagerTest.cpp +++ b/llvm/unittests/IR/PassManagerTest.cpp @@ -826,7 +826,7 @@ FunctionAnalysisManager FAM; FunctionPassManager FPM; PassInstrumentationCallbacks PIC; - StandardInstrumentations SI(/*DebugLogging*/ true); + StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ true); SI.registerCallbacks(PIC, &FAM); FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); FAM.registerPass([&] { return DominatorTreeAnalysis(); }); @@ -872,7 +872,7 @@ FunctionAnalysisManager FAM; FunctionPassManager FPM; PassInstrumentationCallbacks PIC; - StandardInstrumentations SI(/*DebugLogging*/ true); + StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ true); SI.registerCallbacks(PIC, &FAM); FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); FAM.registerPass([&] { return DominatorTreeAnalysis(); }); @@ -937,7 +937,7 @@ FunctionAnalysisManager FAM; FunctionPassManager FPM; PassInstrumentationCallbacks PIC; - StandardInstrumentations SI(/*DebugLogging*/ true); + StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ true); SI.registerCallbacks(PIC, &FAM); FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); FAM.registerPass([&] { return DominatorTreeAnalysis(); });