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 @@ -75,10 +75,13 @@ }; class OptBisectInstrumentation { + bool IsEnabled = false; bool HasWrittenIR = false; + LLVMContext *CachedContext = nullptr; public: OptBisectInstrumentation() = default; + bool shouldRun(StringRef PassID, Any IR); void registerCallbacks(PassInstrumentationCallbacks &PIC); }; 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 @@ -766,28 +766,37 @@ return ShouldRun; } +bool OptBisectInstrumentation::shouldRun(StringRef PassID, Any IR) { + if (!CachedContext) { + CachedContext = &unwrapModule(IR, /*Force*/ true)->getContext(); + IsEnabled = CachedContext->getOptPassGate().isEnabled(); + } + if (!IsEnabled) + return true; + + assert(&unwrapModule(IR, /*Force*/ true)->getContext() == CachedContext); + + if (isIgnored(PassID)) + return true; + bool ShouldRun = CachedContext->getOptPassGate().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; +} void OptBisectInstrumentation::registerCallbacks( PassInstrumentationCallbacks &PIC) { - if (!getOptBisector().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 PassID, Any IR) { return this->shouldRun(PassID, IR); }); } raw_ostream &PrintPassInstrumentation::print() {