[Mlir-commits] [clang] [flang] [llvm] [mlir] [polly] PassBuilder: Take LLVMContext for LibraryOptionsContext (PR #233150)

Fangrui Song llvmlistbot at llvm.org
Mon Oct 19 19:57:48 PDT 2026


https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/233150

>From 47e7768bb1e1f88a8c2837daaf6aa9ba189c4298 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sat, 17 Oct 2026 13:46:24 -0700
Subject: [PATCH 1/2] PassBuilder: Take LLVMContext for LibraryOptionsContext

PassBuilder uses the PipelineTuningOptions' context, else the
TargetMachine's, else null, for which LibraryOptionsContext::get<T>
returns T::Global. A caller that sets neither, such as llvm-reduce,
silently gets the global values.

Take the LLVMContext whose library options the pipelines read as the
first constructor parameter instead, as StandardInstrumentations does,
and remove PipelineTuningOptions::LibraryOptions.

LLM-aided
---
 clang/lib/CodeGen/BackendUtil.cpp             |  3 +-
 .../clang-fuzzer/handle-llvm/handle_llvm.cpp  |  2 +-
 flang/lib/Frontend/FrontendActions.cpp        |  3 +-
 llvm/docs/NVPTXUsage.md                       |  2 +-
 llvm/docs/NewPassManager.md                   |  4 +-
 .../MyFirstLanguageFrontend/LangImpl04.md     |  2 +-
 llvm/examples/Kaleidoscope/Chapter4/toy.cpp   |  2 +-
 llvm/examples/Kaleidoscope/Chapter5/toy.cpp   |  2 +-
 llvm/examples/Kaleidoscope/Chapter6/toy.cpp   |  2 +-
 llvm/examples/Kaleidoscope/Chapter7/toy.cpp   |  2 +-
 llvm/include/llvm/Passes/PassBuilder.h        | 18 +++----
 .../Instrumentation/PGOCtxProfLowering.h      |  2 +-
 .../Instrumentation/PGOInstrumentation.h      |  5 +-
 .../ExecutionEngine/Orc/SpeculateAnalyses.cpp |  4 +-
 llvm/lib/LTO/LTOBackend.cpp                   |  2 +-
 llvm/lib/LTO/ThinLTOCodeGenerator.cpp         |  2 +-
 llvm/lib/Passes/PassBuilder.cpp               |  8 ++-
 llvm/lib/Passes/PassBuilderBindings.cpp       |  2 +-
 llvm/lib/Passes/PassBuilderPipelines.cpp      | 17 +++---
 llvm/lib/Passes/RunCodeGen.cpp                |  6 +--
 .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp |  2 +-
 .../Instrumentation/PGOCtxProfLowering.cpp    |  4 +-
 .../Instrumentation/PGOInstrumentation.cpp    |  4 +-
 llvm/tools/llc/lib/NewPMDriver.cpp            |  3 +-
 llvm/tools/llvm-extract/llvm-extract.cpp      |  6 +--
 .../tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp | 10 ++--
 llvm/tools/llvm-reduce/ReducerWorkItem.cpp    |  2 +-
 llvm/tools/llvm-reduce/deltas/RunIRPasses.cpp |  3 +-
 llvm/tools/opt/NewPMDriver.cpp                |  6 +--
 llvm/tools/opt/NewPMDriver.h                  |  3 +-
 llvm/tools/opt/optdriver.cpp                  |  2 +-
 .../Analysis/CtxProfAnalysisTest.cpp          |  2 +-
 .../Analysis/LastRunTrackingAnalysisTest.cpp  |  2 +-
 .../PluginInlineAdvisorAnalysisTest.cpp       |  2 +-
 .../PluginInlineOrderAnalysisTest.cpp         |  2 +-
 .../Analysis/ReplaceWithVecLibTest.cpp        |  2 +-
 llvm/unittests/CodeGen/CodeGenTestBase.h      |  2 +-
 llvm/unittests/CodeGen/GCMetadata.cpp         |  2 +-
 llvm/unittests/CodeGen/PassManagerTest.cpp    |  4 +-
 .../Frontend/OpenMPIRBuilderTest.cpp          | 20 +++----
 .../IR/LibraryOptionsContextTest.cpp          |  2 +-
 .../unittests/IR/PassBuilderCallbacksTest.cpp |  4 +-
 llvm/unittests/Passes/Plugins/PluginsTest.cpp |  7 +--
 .../DirectX/ResourceBindingAnalysisTests.cpp  |  4 +-
 .../DirectX/UniqueResourceFromUseTests.cpp    |  2 +-
 llvm/unittests/Target/X86/TernlogTest.cpp     |  2 +-
 .../Transforms/Coroutines/ExtraRematTest.cpp  |  5 +-
 .../PGOInstrumentationTest.cpp                |  4 +-
 llvm/unittests/Transforms/Scalar/LICMTest.cpp |  2 +-
 .../Transforms/Utils/MemTransferLowering.cpp  |  4 +-
 mlir/lib/ExecutionEngine/OptUtils.cpp         |  2 +-
 offload/plugins-nextgen/common/src/JIT.cpp    |  2 +-
 polly/lib/Support/RegisterPasses.cpp          | 52 +++++++++----------
 polly/lib/Transform/ScopInliner.cpp           |  8 ++-
 54 files changed, 133 insertions(+), 140 deletions(-)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 1ffcf7d7f6b0a..c4a1bb0be3f01 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -943,7 +943,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
       (CodeGenOpts.DebugPassManager || DebugPassStructure),
       CodeGenOpts.VerifyEach, PrintPassOpts);
   SI.registerCallbacks(PIC, &MAM);
-  PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC, CI.getVirtualFileSystemPtr());
+  PassBuilder PB(TheModule->getContext(), TM.get(), PTO, PGOOpt, &PIC,
+                 CI.getVirtualFileSystemPtr());
 
   // Handle the assignment tracking feature options.
   switch (CodeGenOpts.getAssignmentTrackingMode()) {
diff --git a/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp b/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
index 1c745bffe00c0..a35f11ab4619e 100644
--- a/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
+++ b/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
@@ -94,7 +94,7 @@ static void RunOptimizationPasses(raw_ostream &OS, Module &M,
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
 
-  PassBuilder PB;
+  PassBuilder PB(M.getContext());
 
   PB.registerModuleAnalyses(MAM);
   PB.registerCGSCCAnalyses(CGAM);
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 62dd3fb054863..a80bcaa873d31 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -1032,7 +1032,8 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
   pto.LoopVectorization = opts.VectorizeLoop;
   pto.SLPVectorization = opts.VectorizeSLP;
 
-  llvm::PassBuilder pb(targetMachine, pto, pgoOpt, &pic);
+  llvm::PassBuilder pb(llvmModule->getContext(), targetMachine, pto, pgoOpt,
+                       &pic);
 
   // Register plugin callbacks with PB.
   for (const std::unique_ptr<llvm::PassPlugin> &plugin : ci.getPassPlugins())
diff --git a/llvm/docs/NVPTXUsage.md b/llvm/docs/NVPTXUsage.md
index a752e4c0894c9..bd307702bc0d9 100644
--- a/llvm/docs/NVPTXUsage.md
+++ b/llvm/docs/NVPTXUsage.md
@@ -4894,7 +4894,7 @@ pass manager:
 
 ```c++
 std::unique_ptr<TargetMachine> TM = ...;
-PassBuilder PB(TM);
+PassBuilder PB(Context, TM.get());
 ModulePassManager MPM;
 PB.parsePassPipeline(MPM, ...);
 ```
diff --git a/llvm/docs/NewPassManager.md b/llvm/docs/NewPassManager.md
index 1c264c3eaad6d..f7d50be46c4bb 100644
--- a/llvm/docs/NewPassManager.md
+++ b/llvm/docs/NewPassManager.md
@@ -22,7 +22,7 @@ ModuleAnalysisManager MAM;
 // Take a look at the PassBuilder constructor parameters for more
 // customization, e.g. specifying a TargetMachine or various debugging
 // options.
-PassBuilder PB;
+PassBuilder PB(MyModule.getContext());
 
 // Register all the basic analyses with the managers.
 PB.registerModuleAnalyses(MAM);
@@ -152,7 +152,7 @@ cases, `PassBuilder` exposes callbacks that allow injecting passes into
 certain parts of the pipeline. For example,
 
 ```cpp
-PassBuilder PB;
+PassBuilder PB(Context);
 PB.registerPipelineStartEPCallback(
     [&](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
       MPM.addPass(FooPass());
diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.md b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.md
index 1a833244f9c1a..018d4f89978bc 100644
--- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.md
+++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.md
@@ -181,7 +181,7 @@ Next, we register the analysis passes used by the transform passes.
 
 ```c++
   // Register analysis passes used in these transform passes.
-  PassBuilder PB;
+  PassBuilder PB(*TheContext);
   PB.registerModuleAnalyses(*TheMAM);
   PB.registerFunctionAnalyses(*TheFAM);
   PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
diff --git a/llvm/examples/Kaleidoscope/Chapter4/toy.cpp b/llvm/examples/Kaleidoscope/Chapter4/toy.cpp
index d21cb82d01796..6027f42ba940c 100644
--- a/llvm/examples/Kaleidoscope/Chapter4/toy.cpp
+++ b/llvm/examples/Kaleidoscope/Chapter4/toy.cpp
@@ -591,7 +591,7 @@ static void InitializeModuleAndManagers() {
   TheFPM->addPass(SimplifyCFGPass());
 
   // Register analysis passes used in these transform passes.
-  PassBuilder PB;
+  PassBuilder PB(*TheContext);
   PB.registerModuleAnalyses(*TheMAM);
   PB.registerFunctionAnalyses(*TheFAM);
   PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
diff --git a/llvm/examples/Kaleidoscope/Chapter5/toy.cpp b/llvm/examples/Kaleidoscope/Chapter5/toy.cpp
index 4c6cd258b5878..0a38291660f93 100644
--- a/llvm/examples/Kaleidoscope/Chapter5/toy.cpp
+++ b/llvm/examples/Kaleidoscope/Chapter5/toy.cpp
@@ -865,7 +865,7 @@ static void InitializeModuleAndManagers() {
   TheFPM->addPass(SimplifyCFGPass());
 
   // Register analysis passes used in these transform passes.
-  PassBuilder PB;
+  PassBuilder PB(*TheContext);
   PB.registerModuleAnalyses(*TheMAM);
   PB.registerFunctionAnalyses(*TheFAM);
   PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
diff --git a/llvm/examples/Kaleidoscope/Chapter6/toy.cpp b/llvm/examples/Kaleidoscope/Chapter6/toy.cpp
index 9fc8864a4df1a..b9565f62b362d 100644
--- a/llvm/examples/Kaleidoscope/Chapter6/toy.cpp
+++ b/llvm/examples/Kaleidoscope/Chapter6/toy.cpp
@@ -984,7 +984,7 @@ static void InitializeModuleAndManagers() {
   TheFPM->addPass(SimplifyCFGPass());
 
   // Register analysis passes used in these transform passes.
-  PassBuilder PB;
+  PassBuilder PB(*TheContext);
   PB.registerModuleAnalyses(*TheMAM);
   PB.registerFunctionAnalyses(*TheFAM);
   PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
diff --git a/llvm/examples/Kaleidoscope/Chapter7/toy.cpp b/llvm/examples/Kaleidoscope/Chapter7/toy.cpp
index 5ebec1799ad4b..8ac39c8496178 100644
--- a/llvm/examples/Kaleidoscope/Chapter7/toy.cpp
+++ b/llvm/examples/Kaleidoscope/Chapter7/toy.cpp
@@ -1154,7 +1154,7 @@ static void InitializeModuleAndManagers() {
   TheFPM->addPass(SimplifyCFGPass());
 
   // Register analysis passes used in these transform passes.
-  PassBuilder PB;
+  PassBuilder PB(*TheContext);
   PB.registerModuleAnalyses(*TheMAM);
   PB.registerFunctionAnalyses(*TheFAM);
   PB.crossRegisterProxies(*TheLAM, *TheFAM, *TheCGAM, *TheMAM);
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 2dd74624b424e..641d33dd24bfc 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -34,6 +34,7 @@
 namespace llvm {
 class StringRef;
 class AAManager;
+class LLVMContext;
 class TargetMachine;
 class ModuleSummaryIndex;
 struct PassesOptions;
@@ -54,8 +55,6 @@ class PipelineTuningOptions {
   LLVM_ABI explicit PipelineTuningOptions(
       const cl::LibraryOptionsContext *LibraryOptions);
 
-  const cl::LibraryOptionsContext *LibraryOptions;
-
   /// Tuning option to set loop interleaving on/off, set based on opt level.
   bool LoopInterleaving;
 
@@ -129,7 +128,7 @@ enum class PrintPipelinePassesFormat {
 /// of the built-in passes, and those may reference these members during
 /// construction.
 class PassBuilder {
-  const cl::LibraryOptionsContext *LibraryOptions;
+  LLVMContext &Context;
   const PassesOptions &Opts;
   TargetMachine *TM;
   PipelineTuningOptions PTO;
@@ -151,8 +150,10 @@ class PassBuilder {
     std::vector<PipelineElement> InnerPipeline;
   };
 
+  /// The pipelines read the library options of \p Context, which must outlive
+  /// the PassBuilder.
   LLVM_ABI explicit PassBuilder(
-      TargetMachine *TM = nullptr,
+      LLVMContext &Context, TargetMachine *TM = nullptr,
       PipelineTuningOptions PTO = PipelineTuningOptions(),
       std::optional<PGOOptions> PGOOpt = std::nullopt,
       PassInstrumentationCallbacks *PIC = nullptr,
@@ -680,19 +681,14 @@ class PassBuilder {
                                        std::string ProfileFile,
                                        std::string ProfileRemappingFile);
 
+  LLVMContext &getContext() const { return Context; }
+
   /// Returns PIC. External libraries can use this to register pass
   /// instrumentation callbacks.
   PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
     return PIC;
   }
 
-  /// Returns the library options the pipelines read: the
-  /// PipelineTuningOptions', else the TargetMachine's, else null for the global
-  /// values.
-  const cl::LibraryOptionsContext *getLibraryOptions() const {
-    return LibraryOptions;
-  }
-
   /// Returns the virtual file system.
   IntrusiveRefCntPtr<vfs::FileSystem> getVirtualFileSystemPtr() const {
     return FS;
diff --git a/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h b/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h
index 1d4c21d91a9b1..67155c2e824b6 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h
@@ -25,7 +25,7 @@ class PGOCtxProfLoweringPass
   explicit PGOCtxProfLoweringPass() = default;
   // True if contextual instrumentation is enabled.
   LLVM_ABI static bool
-  isCtxIRPGOInstrEnabled(const cl::LibraryOptionsContext *LibraryOptions);
+  isCtxIRPGOInstrEnabled(const cl::LibraryOptionsContext &LibraryOptions);
 
   LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
 };
diff --git a/llvm/include/llvm/Transforms/Instrumentation/PGOInstrumentation.h b/llvm/include/llvm/Transforms/Instrumentation/PGOInstrumentation.h
index af2e5373f1d6d..cb3b22ad489af 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/PGOInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/PGOInstrumentation.h
@@ -111,10 +111,9 @@ LLVM_ABI void setProfMetadata(Instruction *TI, ArrayRef<uint64_t> EdgeCounts,
 LLVM_ABI void setIrrLoopHeaderMetadata(Module *M, Instruction *TI,
                                        uint64_t Count);
 
-/// Return the value of -pgo-instrument-cold-function-only in LibraryOptions, or
-/// its global value if null.
+/// Return the value of -pgo-instrument-cold-function-only in LibraryOptions.
 LLVM_ABI bool isPGOInstrumentColdFunctionOnly(
-    const cl::LibraryOptionsContext *LibraryOptions);
+    const cl::LibraryOptionsContext &LibraryOptions);
 
 } // end namespace llvm
 
diff --git a/llvm/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp b/llvm/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp
index d2bff139b3235..75c8b49af5c69 100644
--- a/llvm/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp
@@ -86,7 +86,7 @@ BlockFreqQuery::ResultTy BlockFreqQuery::operator()(Function &F) {
   DenseSet<StringRef> Calles;
   SmallVector<std::pair<const BasicBlock *, uint64_t>, 8> BBFreqs;
 
-  PassBuilder PB;
+  PassBuilder PB(F.getContext());
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
 
@@ -233,7 +233,7 @@ SequenceBBQuery::queryCFG(Function &F, const BlockListTy &CallerBlocks) {
   VisitedBlocksInfoTy VisitedBlocks;
   BackEdgesInfoTy BackEdgesInfo;
 
-  PassBuilder PB;
+  PassBuilder PB(F.getContext());
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
 
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 5223ad3e3f251..ed431be770f59 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -297,7 +297,7 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
   StandardInstrumentations SI(Mod.getContext(), Conf.DebugPassManager,
                               Conf.VerifyEach);
   SI.registerCallbacks(PIC, &MAM);
-  PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC);
+  PassBuilder PB(Mod.getContext(), TM, Conf.PTO, PGOOpt, &PIC);
 
   RegisterPassPlugins(Conf, PB);
 
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 710594d360df3..56a6064a56dec 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -264,7 +264,7 @@ static void optimizeModule(Module &TheModule, TargetMachine &TM,
   PipelineTuningOptions PTO;
   PTO.LoopVectorization = true;
   PTO.SLPVectorization = true;
-  PassBuilder PB(&TM, PTO, PGOOpt, &PIC);
+  PassBuilder PB(TheModule.getContext(), &TM, PTO, PGOOpt, &PIC);
 
   std::unique_ptr<TargetLibraryInfoImpl> TLII(
       new TargetLibraryInfoImpl(TM.getTargetTriple(), TM.Options.VecLib));
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index dd77f96f94379..6004c3ab4073d 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -566,14 +566,12 @@ static Expected<OptimizationLevel> parseOptLevelParam(StringRef S) {
       inconvertibleErrorCode());
 }
 
-PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO,
+PassBuilder::PassBuilder(LLVMContext &Context, TargetMachine *TM,
+                         PipelineTuningOptions PTO,
                          std::optional<PGOOptions> PGOOpt,
                          PassInstrumentationCallbacks *PIC,
                          IntrusiveRefCntPtr<vfs::FileSystem> FS)
-    : LibraryOptions(PTO.LibraryOptions ? PTO.LibraryOptions
-                     : TM               ? TM->Options.MCOptions.LibraryOptions
-                                        : nullptr),
-      Opts(cl::LibraryOptionsContext::get<PassesOptions>(LibraryOptions)),
+    : Context(Context), Opts(Context.getLibraryOptions().get<PassesOptions>()),
       TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
   if (TM)
     TM->registerPassBuilderCallbacks(*this);
diff --git a/llvm/lib/Passes/PassBuilderBindings.cpp b/llvm/lib/Passes/PassBuilderBindings.cpp
index 933fe89e53a94..d9f2f887c6467 100644
--- a/llvm/lib/Passes/PassBuilderBindings.cpp
+++ b/llvm/lib/Passes/PassBuilderBindings.cpp
@@ -55,7 +55,7 @@ static LLVMErrorRef runPasses(Module *Mod, Function *Fun, const char *Passes,
   bool VerifyEach = PassOpts->VerifyEach;
 
   PassInstrumentationCallbacks PIC;
-  PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC);
+  PassBuilder PB(Mod->getContext(), Machine, PassOpts->PTO, std::nullopt, &PIC);
 
   LoopAnalysisManager LAM;
   FunctionAnalysisManager FAM;
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 125c8e442f27b..42184d87718c4 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -168,8 +168,7 @@ extern cl::opt<bool> EnableMemProfContextDisambiguation;
 } // namespace llvm
 
 PipelineTuningOptions::PipelineTuningOptions(
-    const cl::LibraryOptionsContext *LibraryOptions)
-    : LibraryOptions(LibraryOptions) {
+    const cl::LibraryOptionsContext *LibraryOptions) {
   const PassesOptions &Opts =
       cl::LibraryOptionsContext::get<PassesOptions>(LibraryOptions);
   LoopInterleaving = true;
@@ -1131,8 +1130,8 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
   const bool IsPreLink = !isThinLTOPostLink(Phase);
   // Enable contextual profiling instrumentation.
   const bool IsCtxProfGen =
-      IsPreLink &&
-      PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled(LibraryOptions);
+      IsPreLink && PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled(
+                       Context.getLibraryOptions());
   const bool IsPGOPreLink = !IsCtxProfGen && PGOOpt && IsPreLink;
   const bool IsPGOInstrGen =
       IsPGOPreLink && PGOOpt->Action == PGOOptions::IRInstr;
@@ -1141,19 +1140,19 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
   const bool IsMemprofUse = IsPGOPreLink && !PGOOpt->MemoryProfile.empty();
   // We don't want to mix pgo ctx gen and pgo gen; we also don't currently
   // enable ctx profiling from the frontend.
-  assert(!(IsPGOInstrGen &&
-           PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled(LibraryOptions)) &&
+  assert(!(IsPGOInstrGen && PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled(
+                                Context.getLibraryOptions())) &&
          "Enabling both instrumented PGO and contextual instrumentation is not "
          "supported.");
   const bool IsCtxProfUse = !UseCtxProfile.empty() && isThinLTOPreLink(Phase);
 
   assert((Opts.instrument_cold_function_only_path.empty() ||
-          isPGOInstrumentColdFunctionOnly(LibraryOptions)) &&
+          isPGOInstrumentColdFunctionOnly(Context.getLibraryOptions())) &&
          "--instrument-cold-function-only-path is provided but "
          "--pgo-instrument-cold-function-only is not enabled");
   const bool IsColdFuncOnlyInstrGen =
-      isPGOInstrumentColdFunctionOnly(LibraryOptions) && IsPGOPreLink &&
-      !Opts.instrument_cold_function_only_path.empty();
+      isPGOInstrumentColdFunctionOnly(Context.getLibraryOptions()) &&
+      IsPGOPreLink && !Opts.instrument_cold_function_only_path.empty();
 
   if (IsPGOInstrGen || IsPGOInstrUse || IsMemprofUse || IsCtxProfGen ||
       IsCtxProfUse || IsColdFuncOnlyInstrGen)
diff --git a/llvm/lib/Passes/RunCodeGen.cpp b/llvm/lib/Passes/RunCodeGen.cpp
index 7514d6cbb9aca..bbf451efa48b2 100644
--- a/llvm/lib/Passes/RunCodeGen.cpp
+++ b/llvm/lib/Passes/RunCodeGen.cpp
@@ -67,9 +67,9 @@ static Error runCodeGenPipelineNewPM(TargetMachine &TM, Module &M,
   Opt.DisableVerify = DisableVerify;
   MachineModuleInfo MMI(&TM);
   PassInstrumentationCallbacks PIC;
-  PipelineTuningOptions PTOptions(&M.getContext().getLibraryOptions());
-  TargetMachine *TMPointer = &TM;
-  PassBuilder PB(TMPointer, PTOptions, std::nullopt, &PIC, VFS);
+  const auto &LibraryOptions = M.getContext().getLibraryOptions();
+  PipelineTuningOptions PTOptions(&LibraryOptions);
+  PassBuilder PB(M.getContext(), &TM, PTOptions, std::nullopt, &PIC, VFS);
   PB.registerModuleAnalyses(MAM);
   PB.registerCGSCCAnalyses(CGAM);
   PB.registerFunctionAnalyses(FAM);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 6a5b27e5775c6..53130fae3c998 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -1283,7 +1283,7 @@ bool AMDGPUTargetMachine::splitModule(
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
 
-  PassBuilder PB(this);
+  PassBuilder PB(M.getContext(), this);
   PB.registerModuleAnalyses(MAM);
   PB.registerFunctionAnalyses(FAM);
   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
diff --git a/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp b/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
index 5a35c34bc3b29..74644d67d4260 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
@@ -31,8 +31,8 @@ using namespace llvm;
 #define DEBUG_TYPE "ctx-instr-lower"
 
 bool PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled(
-    const cl::LibraryOptionsContext *LibraryOptions) {
-  return !cl::LibraryOptionsContext::get<InstrumentationOptions>(LibraryOptions)
+    const cl::LibraryOptionsContext &LibraryOptions) {
+  return !LibraryOptions.get<InstrumentationOptions>()
               .profile_context_root.empty();
 }
 
diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index 2ce082c664eae..2e45694a37421 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -185,8 +185,8 @@ extern cl::opt<bool> EnableVTableProfileUse;
 } // namespace llvm
 
 bool llvm::isPGOInstrumentColdFunctionOnly(
-    const cl::LibraryOptionsContext *LibraryOptions) {
-  return cl::LibraryOptionsContext::get<InstrumentationOptions>(LibraryOptions)
+    const cl::LibraryOptionsContext &LibraryOptions) {
+  return LibraryOptions.get<InstrumentationOptions>()
       .pgo_instrument_cold_function_only;
 }
 
diff --git a/llvm/tools/llc/lib/NewPMDriver.cpp b/llvm/tools/llc/lib/NewPMDriver.cpp
index 156a71c49e017..03f5afd45c5e8 100644
--- a/llvm/tools/llc/lib/NewPMDriver.cpp
+++ b/llvm/tools/llc/lib/NewPMDriver.cpp
@@ -143,7 +143,8 @@ int llvm::compileModuleWithNewPM(
 
   MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });
 
-  PassBuilder PB(Target.get(), PipelineTuningOptions(), std::nullopt, &PIC);
+  PassBuilder PB(Context, Target.get(), PipelineTuningOptions(), std::nullopt,
+                 &PIC);
   for (auto &PassPlugin : PassPlugins)
     PassPlugin.registerPassBuilderCallbacks(PB);
   PB.registerModuleAnalyses(MAM);
diff --git a/llvm/tools/llvm-extract/llvm-extract.cpp b/llvm/tools/llvm-extract/llvm-extract.cpp
index 6fa1a95ece735..4c549951603d8 100644
--- a/llvm/tools/llvm-extract/llvm-extract.cpp
+++ b/llvm/tools/llvm-extract/llvm-extract.cpp
@@ -332,7 +332,7 @@ int main(int argc, char **argv) {
     CGSCCAnalysisManager CGAM;
     ModuleAnalysisManager MAM;
 
-    PassBuilder PB(nullptr, PipelineTuningOptions(&Context.getLibraryOptions()));
+    PassBuilder PB(Context);
 
     PB.registerModuleAnalyses(MAM);
     PB.registerCGSCCAnalyses(CGAM);
@@ -379,7 +379,7 @@ int main(int argc, char **argv) {
     CGSCCAnalysisManager CGAM;
     ModuleAnalysisManager MAM;
 
-    PassBuilder PB(nullptr, PipelineTuningOptions(&Context.getLibraryOptions()));
+    PassBuilder PB(Context);
 
     PB.registerModuleAnalyses(MAM);
     PB.registerCGSCCAnalyses(CGAM);
@@ -400,7 +400,7 @@ int main(int argc, char **argv) {
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
 
-  PassBuilder PB(nullptr, PipelineTuningOptions(&Context.getLibraryOptions()));
+  PassBuilder PB(Context);
 
   PB.registerModuleAnalyses(MAM);
   PB.registerCGSCCAnalyses(CGAM);
diff --git a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp
index 004b9dadec943..d9397795efd6f 100644
--- a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp
+++ b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp
@@ -37,6 +37,7 @@ static cl::opt<std::string> PassPipeline(
     cl::desc("A textual description of the pass pipeline for testing"));
 
 static std::unique_ptr<IRMutator> Mutator;
+static cl::LibraryOptionsContext LibraryOptions;
 static std::unique_ptr<TargetMachine> TM;
 
 std::unique_ptr<IRMutator> createOptMutator() {
@@ -116,6 +117,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
   //
 
   LLVMContext Context;
+  Context.getLibraryOptions().assign(LibraryOptions);
   auto M = parseAndVerify(Data, Size, Context);
   if (!M) {
     errs() << "error: input module is broken!\n";
@@ -133,7 +135,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
   // Create pass pipeline
   //
 
-  PassBuilder PB(TM.get());
+  PassBuilder PB(Context, TM.get());
 
   LoopAnalysisManager LAM;
   FunctionAnalysisManager FAM;
@@ -190,8 +192,6 @@ extern "C" LLVM_ATTRIBUTE_USED int LLVMFuzzerInitialize(int *argc,
   // Parse input options
   //
 
-  // Created after the targets register their library options.
-  static cl::LibraryOptionsContext LibraryOptions;
   handleExecNameEncodedOptimizerOpts(LibraryOptions, ExecName);
   parseFuzzerCLOpts(LibraryOptions, *argc, *argv);
 
@@ -214,7 +214,9 @@ extern "C" LLVM_ATTRIBUTE_USED int LLVMFuzzerInitialize(int *argc,
     exit(1);
   }
 
-  PassBuilder PB(TM.get());
+  LLVMContext Context;
+  Context.getLibraryOptions().assign(LibraryOptions);
+  PassBuilder PB(Context, TM.get());
   ModulePassManager MPM;
   if (auto Err = PB.parsePassPipeline(MPM, PassPipeline)) {
     errs() << ExecName << ": " << toString(std::move(Err)) << "\n";
diff --git a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
index c675b2b9e2816..4d8a570d699d6 100644
--- a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
+++ b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
@@ -799,7 +799,7 @@ void ReducerWorkItem::writeBitcode(raw_ostream &OutStream) const {
   const bool ShouldPreserveUseListOrder = true;
 
   if (LTOInfo && LTOInfo->IsThinLTO && LTOInfo->EnableSplitLTOUnit) {
-    PassBuilder PB;
+    PassBuilder PB(M->getContext());
     LoopAnalysisManager LAM;
     FunctionAnalysisManager FAM;
     CGSCCAnalysisManager CGAM;
diff --git a/llvm/tools/llvm-reduce/deltas/RunIRPasses.cpp b/llvm/tools/llvm-reduce/deltas/RunIRPasses.cpp
index 631130bf3b124..daf33c5ee24fc 100644
--- a/llvm/tools/llvm-reduce/deltas/RunIRPasses.cpp
+++ b/llvm/tools/llvm-reduce/deltas/RunIRPasses.cpp
@@ -33,7 +33,8 @@ void llvm::runIRPassesDeltaPass(Oracle &O, ReducerWorkItem &WorkItem) {
   PassInstrumentationCallbacks PIC;
   PIC.registerShouldRunOptionalPassCallback(
       [&](StringRef, IRUnitRef) { return !O.shouldKeep(); });
-  PassBuilder PB(nullptr, PipelineTuningOptions(), std::nullopt, &PIC);
+  PassBuilder PB(Program.getContext(), nullptr, PipelineTuningOptions(),
+                 std::nullopt, &PIC);
 
   PB.registerModuleAnalyses(MAM);
   PB.registerCGSCCAnalyses(CGAM);
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index fb56822589a11..22899f4eb8ccb 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -480,7 +480,7 @@ bool llvm::runPassPipeline(
   PTO.LoopUnrolling = !DisableLoopUnrolling;
   PTO.UnifiedLTO = UnifiedLTO;
   PTO.LoopFusion = EnableLoopFusion;
-  PassBuilder PB(TM, PTO, P, &PIC);
+  PassBuilder PB(M.getContext(), TM, PTO, P, &PIC);
   registerEPCallbacks(PB);
 
   // Let plugins and linked extensions register pass builder callbacks.
@@ -625,7 +625,7 @@ bool llvm::runPassPipeline(
   return true;
 }
 
-void llvm::printPasses(raw_ostream &OS) {
-  PassBuilder PB;
+void llvm::printPasses(LLVMContext &Context, raw_ostream &OS) {
+  PassBuilder PB(Context);
   PB.printPassNames(OS);
 }
diff --git a/llvm/tools/opt/NewPMDriver.h b/llvm/tools/opt/NewPMDriver.h
index d5d0d851013a5..769a31ceab78b 100644
--- a/llvm/tools/opt/NewPMDriver.h
+++ b/llvm/tools/opt/NewPMDriver.h
@@ -23,6 +23,7 @@
 #include "llvm/Support/CommandLine.h"
 
 namespace llvm {
+class LLVMContext;
 class PassBuilder;
 class StringRef;
 struct PassPluginLibraryInfo;
@@ -54,7 +55,7 @@ enum PGOKind {
 enum CSPGOKind { NoCSPGO, CSInstrGen, CSInstrUse };
 } // namespace opt_tool
 
-void printPasses(raw_ostream &OS);
+void printPasses(LLVMContext &Context, raw_ostream &OS);
 
 /// Driver function to run the new pass manager over a module.
 ///
diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index 816a7b0cc16ea..f6a26d2af70d0 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -496,7 +496,7 @@ optMain(int argc, char **argv,
   // construct the PassBuilder before parsing IR so we can reuse the same
   // PassBuilder for print passes.
   if (PrintPasses) {
-    printPasses(outs());
+    printPasses(Context, outs());
     return 0;
   }
 
diff --git a/llvm/unittests/Analysis/CtxProfAnalysisTest.cpp b/llvm/unittests/Analysis/CtxProfAnalysisTest.cpp
index 3fba07ddd0f24..f4dbe61e76dd6 100644
--- a/llvm/unittests/Analysis/CtxProfAnalysisTest.cpp
+++ b/llvm/unittests/Analysis/CtxProfAnalysisTest.cpp
@@ -89,7 +89,7 @@ attributes #0 = { noinline }
   }
 
 public:
-  CtxProfAnalysisTest() {
+  CtxProfAnalysisTest() : PB(C) {
     PB.registerModuleAnalyses(MAM);
     PB.registerCGSCCAnalyses(CGAM);
     PB.registerFunctionAnalyses(FAM);
diff --git a/llvm/unittests/Analysis/LastRunTrackingAnalysisTest.cpp b/llvm/unittests/Analysis/LastRunTrackingAnalysisTest.cpp
index 7ce66b3a7d064..6414a2474fb50 100644
--- a/llvm/unittests/Analysis/LastRunTrackingAnalysisTest.cpp
+++ b/llvm/unittests/Analysis/LastRunTrackingAnalysisTest.cpp
@@ -28,7 +28,7 @@ class LastRunTrackingAnalysisTest : public testing::Test {
   ModulePassManager MPM;
   ModuleAnalysisManager MAM;
 
-  LastRunTrackingAnalysisTest() : M("LastRunTrackingAnalysisTest", C) {
+  LastRunTrackingAnalysisTest() : M("LastRunTrackingAnalysisTest", C), PB(C) {
     PB.registerModuleAnalyses(MAM);
     PB.registerCGSCCAnalyses(CGAM);
     PB.registerFunctionAnalyses(FAM);
diff --git a/llvm/unittests/Analysis/PluginInlineAdvisorAnalysisTest.cpp b/llvm/unittests/Analysis/PluginInlineAdvisorAnalysisTest.cpp
index f891878838b0a..3cd22dba2b084 100644
--- a/llvm/unittests/Analysis/PluginInlineAdvisorAnalysisTest.cpp
+++ b/llvm/unittests/Analysis/PluginInlineAdvisorAnalysisTest.cpp
@@ -75,7 +75,7 @@ struct CompilerInstance {
         [&] { return PluginInlineAdvisorAnalysis(fooOnlyFactory); });
   }
 
-  CompilerInstance() {
+  CompilerInstance() : PB(Ctx) {
     IP = getInlineParamsFromOptLevel(3);
     PB.registerModuleAnalyses(MAM);
     PB.registerCGSCCAnalyses(CGAM);
diff --git a/llvm/unittests/Analysis/PluginInlineOrderAnalysisTest.cpp b/llvm/unittests/Analysis/PluginInlineOrderAnalysisTest.cpp
index f5431cd7fdc85..7e29c80ce5be5 100644
--- a/llvm/unittests/Analysis/PluginInlineOrderAnalysisTest.cpp
+++ b/llvm/unittests/Analysis/PluginInlineOrderAnalysisTest.cpp
@@ -50,7 +50,7 @@ struct CompilerInstance {
     Plugin->registerPassBuilderCallbacks(PB);
   }
 
-  CompilerInstance() {
+  CompilerInstance() : PB(Ctx) {
     IP = getInlineParamsFromOptLevel(3);
     PB.registerModuleAnalyses(MAM);
     PB.registerCGSCCAnalyses(CGAM);
diff --git a/llvm/unittests/Analysis/ReplaceWithVecLibTest.cpp b/llvm/unittests/Analysis/ReplaceWithVecLibTest.cpp
index 31e0263ad64d7..db36347ee8c9f 100644
--- a/llvm/unittests/Analysis/ReplaceWithVecLibTest.cpp
+++ b/llvm/unittests/Analysis/ReplaceWithVecLibTest.cpp
@@ -68,7 +68,7 @@ class ReplaceWithVecLibTest : public ::testing::Test {
     FunctionPassManager FPM;
     FPM.addPass(ReplaceWithVeclib());
     std::unique_ptr<Module> M = parseIR(Ctx, IR);
-    PassBuilder PB;
+    PassBuilder PB(Ctx);
     PB.registerFunctionAnalyses(FAM);
 
     // Enable debugging and capture std error
diff --git a/llvm/unittests/CodeGen/CodeGenTestBase.h b/llvm/unittests/CodeGen/CodeGenTestBase.h
index b6256c6a8c391..b07de37118f6c 100644
--- a/llvm/unittests/CodeGen/CodeGenTestBase.h
+++ b/llvm/unittests/CodeGen/CodeGenTestBase.h
@@ -58,7 +58,7 @@ class CodeGenTestBase : public testing::Test {
       GTEST_SKIP();
     MMI = std::make_unique<MachineModuleInfo>(TM.get());
 
-    PassBuilder PB(TM.get());
+    PassBuilder PB(Context, TM.get());
     PB.registerModuleAnalyses(MAM);
     PB.registerCGSCCAnalyses(CGAM);
     PB.registerFunctionAnalyses(FAM);
diff --git a/llvm/unittests/CodeGen/GCMetadata.cpp b/llvm/unittests/CodeGen/GCMetadata.cpp
index a5d8a63d9b555..74d2b67ae2e46 100644
--- a/llvm/unittests/CodeGen/GCMetadata.cpp
+++ b/llvm/unittests/CodeGen/GCMetadata.cpp
@@ -57,7 +57,7 @@ TEST_F(GCMetadataTest, Basic) {
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
-  PassBuilder PB;
+  PassBuilder PB(Context);
   PB.registerModuleAnalyses(MAM);
   PB.registerCGSCCAnalyses(CGAM);
   PB.registerFunctionAnalyses(FAM);
diff --git a/llvm/unittests/CodeGen/PassManagerTest.cpp b/llvm/unittests/CodeGen/PassManagerTest.cpp
index a9f4afdaf2534..25b673c5287df 100644
--- a/llvm/unittests/CodeGen/PassManagerTest.cpp
+++ b/llvm/unittests/CodeGen/PassManagerTest.cpp
@@ -188,7 +188,7 @@ TEST_F(PassManagerTest, Basic) {
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
-  PassBuilder PB(TM.get());
+  PassBuilder PB(Context, TM.get());
   PB.registerModuleAnalyses(MAM);
   PB.registerCGSCCAnalyses(CGAM);
   PB.registerFunctionAnalyses(FAM);
@@ -237,7 +237,7 @@ TEST_F(PassManagerTest, DiagnosticHandler) {
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
-  PassBuilder PB(TM.get());
+  PassBuilder PB(Context, TM.get());
   PB.registerModuleAnalyses(MAM);
   PB.registerCGSCCAnalyses(CGAM);
   PB.registerFunctionAnalyses(FAM);
diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
index c00757675d156..260fc613e9807 100644
--- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
+++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
@@ -2000,7 +2000,7 @@ TEST_F(OpenMPIRBuilderTest, ApplySimd) {
   OMPBuilder.finalize();
   EXPECT_FALSE(verifyModule(*M, &errs()));
 
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(*F);
@@ -2044,7 +2044,7 @@ TEST_F(OpenMPIRBuilderTest, ApplySimdCustomAligned) {
   OMPBuilder.finalize();
   EXPECT_FALSE(verifyModule(*M, &errs()));
 
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(*F);
@@ -2100,7 +2100,7 @@ TEST_F(OpenMPIRBuilderTest, ApplySimdlen) {
   OMPBuilder.finalize();
   EXPECT_FALSE(verifyModule(*M, &errs()));
 
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(*F);
@@ -2137,7 +2137,7 @@ TEST_F(OpenMPIRBuilderTest, ApplySafelenOrderConcurrent) {
   OMPBuilder.finalize();
   EXPECT_FALSE(verifyModule(*M, &errs()));
 
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(*F);
@@ -2175,7 +2175,7 @@ TEST_F(OpenMPIRBuilderTest, ApplySafelen) {
   OMPBuilder.finalize();
   EXPECT_FALSE(verifyModule(*M, &errs()));
 
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(*F);
@@ -2212,7 +2212,7 @@ TEST_F(OpenMPIRBuilderTest, ApplySimdlenSafelen) {
   OMPBuilder.finalize();
   EXPECT_FALSE(verifyModule(*M, &errs()));
 
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(*F);
@@ -2260,7 +2260,7 @@ TEST_F(OpenMPIRBuilderTest, ApplySimdIf) {
   OMPBuilder.finalize();
   EXPECT_FALSE(verifyModule(*M, &errs()));
 
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(*F);
@@ -2310,7 +2310,7 @@ TEST_F(OpenMPIRBuilderTest, UnrollLoopFull) {
   OMPBuilder.finalize();
   EXPECT_FALSE(verifyModule(*M, &errs()));
 
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(*F);
@@ -2338,7 +2338,7 @@ TEST_F(OpenMPIRBuilderTest, UnrollLoopPartial) {
   EXPECT_FALSE(verifyModule(*M, &errs()));
   UnrolledLoop->assertOK();
 
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(*F);
@@ -2371,7 +2371,7 @@ TEST_F(OpenMPIRBuilderTest, UnrollLoopHeuristic) {
   OMPBuilder.finalize();
   EXPECT_FALSE(verifyModule(*M, &errs()));
 
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   FunctionAnalysisManager FAM;
   PB.registerFunctionAnalyses(FAM);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(*F);
diff --git a/llvm/unittests/IR/LibraryOptionsContextTest.cpp b/llvm/unittests/IR/LibraryOptionsContextTest.cpp
index 87fd1a2378b3b..a8b08d89caf1e 100644
--- a/llvm/unittests/IR/LibraryOptionsContextTest.cpp
+++ b/llvm/unittests/IR/LibraryOptionsContextTest.cpp
@@ -41,7 +41,7 @@ static std::string runInstCombine(LLVMContext &Ctx) {
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   PB.registerModuleAnalyses(MAM);
   PB.registerCGSCCAnalyses(CGAM);
   PB.registerFunctionAnalyses(FAM);
diff --git a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
index 788e5296de520..0567476aa13e8 100644
--- a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
+++ b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
@@ -460,8 +460,8 @@ class PassBuilderCallbacksTest<PassManager<
                   "exit:\n"
                   "  ret void\n"
                   "}\n")),
-        CallbacksHandle(), PB(nullptr, PipelineTuningOptions(), std::nullopt,
-                              &CallbacksHandle.Callbacks),
+        CallbacksHandle(), PB(Context, nullptr, PipelineTuningOptions(),
+                              std::nullopt, &CallbacksHandle.Callbacks),
         PM(), LAM(), FAM(), CGAM(), AM() {
 
     EXPECT_TRUE(&CallbacksHandle.Callbacks ==
diff --git a/llvm/unittests/Passes/Plugins/PluginsTest.cpp b/llvm/unittests/Passes/Plugins/PluginsTest.cpp
index c2ef01c14dc73..668cf2367ebf9 100644
--- a/llvm/unittests/Passes/Plugins/PluginsTest.cpp
+++ b/llvm/unittests/Passes/Plugins/PluginsTest.cpp
@@ -54,7 +54,8 @@ TEST(PluginsTests, LoadPlugin) {
   ASSERT_EQ(TEST_PLUGIN_NAME, Plugin->getPluginName());
   ASSERT_EQ(TEST_PLUGIN_VERSION, Plugin->getPluginVersion());
 
-  PassBuilder PB;
+  LLVMContext C;
+  PassBuilder PB(C);
   ModulePassManager PM;
   ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, "plugin-pass"), Failed());
 
@@ -100,7 +101,8 @@ TEST(PluginsTests, LoadMultiplePlugins) {
   ASSERT_EQ("DoublerPlugin", DoublerPlugin2->getPluginName());
   ASSERT_EQ("2.2-unit", DoublerPlugin2->getPluginVersion());
 
-  PassBuilder PB;
+  LLVMContext C;
+  PassBuilder PB(C);
   ModulePassManager PM;
   const char *PipelineText = "module(doubler-pass,plugin-pass,doubler-pass)";
   ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Failed());
@@ -109,7 +111,6 @@ TEST(PluginsTests, LoadMultiplePlugins) {
   DoublerPlugin2->registerPassBuilderCallbacks(PB);
   ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded());
 
-  LLVMContext C;
   SMDiagnostic Err;
   std::unique_ptr<Module> M =
       parseAssemblyString(R"IR(@doubleme = constant i32 7)IR", Err, C);
diff --git a/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp b/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp
index 65e1beadf3e38..900dfb64f97e2 100644
--- a/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp
+++ b/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp
@@ -25,9 +25,9 @@ class ResourceBindingAnalysisTest : public testing::Test {
   LLVMContext *Context;
 
   virtual void SetUp() {
-    PB = new PassBuilder();
-    MAM = new ModuleAnalysisManager();
     Context = new LLVMContext();
+    PB = new PassBuilder(*Context);
+    MAM = new ModuleAnalysisManager();
     PB->registerModuleAnalyses(*MAM);
     MAM->registerPass([&] { return DXILResourceBindingAnalysis(); });
   }
diff --git a/llvm/unittests/Target/DirectX/UniqueResourceFromUseTests.cpp b/llvm/unittests/Target/DirectX/UniqueResourceFromUseTests.cpp
index 5b54c13cae332..d76ab34ee6b25 100644
--- a/llvm/unittests/Target/DirectX/UniqueResourceFromUseTests.cpp
+++ b/llvm/unittests/Target/DirectX/UniqueResourceFromUseTests.cpp
@@ -33,7 +33,7 @@ class UniqueResourceFromUseTest : public testing::Test {
   virtual void SetUp() {
     Context = new LLVMContext();
     MAM = new ModuleAnalysisManager();
-    PB = new PassBuilder();
+    PB = new PassBuilder(*Context);
     PB->registerModuleAnalyses(*MAM);
     MAM->registerPass([&] { return DXILResourceTypeAnalysis(); });
     MAM->registerPass([&] { return DXILResourceAnalysis(); });
diff --git a/llvm/unittests/Target/X86/TernlogTest.cpp b/llvm/unittests/Target/X86/TernlogTest.cpp
index 86a2797a425c0..cab889400aa6e 100644
--- a/llvm/unittests/Target/X86/TernlogTest.cpp
+++ b/llvm/unittests/Target/X86/TernlogTest.cpp
@@ -170,7 +170,7 @@ TEST(TernlogTest, TestConstantFolding) {
   LLVMContext Ctx;
   FunctionAnalysisManager FAM;
   FunctionPassManager FPM;
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   LoopAnalysisManager LAM;
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
diff --git a/llvm/unittests/Transforms/Coroutines/ExtraRematTest.cpp b/llvm/unittests/Transforms/Coroutines/ExtraRematTest.cpp
index a34b630a34fb7..c1152f45b8d20 100644
--- a/llvm/unittests/Transforms/Coroutines/ExtraRematTest.cpp
+++ b/llvm/unittests/Transforms/Coroutines/ExtraRematTest.cpp
@@ -27,10 +27,9 @@ struct ExtraRematTest : public testing::Test {
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
-  LLVMContext Context;
   std::unique_ptr<Module> M;
 
-  ExtraRematTest() {
+  ExtraRematTest() : PB(Ctx) {
     PB.registerModuleAnalyses(MAM);
     PB.registerCGSCCAnalyses(CGAM);
     PB.registerFunctionAnalyses(FAM);
@@ -57,7 +56,7 @@ struct ExtraRematTest : public testing::Test {
 
   void ParseAssembly(const StringRef IR) {
     SMDiagnostic Error;
-    M = parseAssemblyString(IR, Error, Context);
+    M = parseAssemblyString(IR, Error, Ctx);
     std::string errMsg;
     raw_string_ostream os(errMsg);
     Error.print("", os);
diff --git a/llvm/unittests/Transforms/Instrumentation/PGOInstrumentationTest.cpp b/llvm/unittests/Transforms/Instrumentation/PGOInstrumentationTest.cpp
index 9ccb13934cbd3..ce7f01333f1b5 100644
--- a/llvm/unittests/Transforms/Instrumentation/PGOInstrumentationTest.cpp
+++ b/llvm/unittests/Transforms/Instrumentation/PGOInstrumentationTest.cpp
@@ -106,6 +106,7 @@ class MockModuleAnalysisHandle
 struct PGOInstrumentationGenTest
     : public Test,
       WithParamInterface<std::tuple<StringRef, StringRef>> {
+  LLVMContext Context;
   ModulePassManager MPM;
   PassBuilder PB;
   MockModuleAnalysisHandle MMAHandle;
@@ -113,10 +114,9 @@ struct PGOInstrumentationGenTest
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
-  LLVMContext Context;
   std::unique_ptr<Module> M;
 
-  PGOInstrumentationGenTest() {
+  PGOInstrumentationGenTest() : PB(Context) {
     MAM.registerPass([&] { return MMAHandle.getAnalysis(); });
     PB.registerModuleAnalyses(MAM);
     PB.registerCGSCCAnalyses(CGAM);
diff --git a/llvm/unittests/Transforms/Scalar/LICMTest.cpp b/llvm/unittests/Transforms/Scalar/LICMTest.cpp
index a193993ba04d6..792aa94501a57 100644
--- a/llvm/unittests/Transforms/Scalar/LICMTest.cpp
+++ b/llvm/unittests/Transforms/Scalar/LICMTest.cpp
@@ -20,7 +20,7 @@ namespace llvm {
 TEST(LICMTest, TestSCEVInvalidationOnHoisting) {
   LLVMContext Ctx;
   ModulePassManager MPM;
-  PassBuilder PB;
+  PassBuilder PB(Ctx);
   LoopAnalysisManager LAM;
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
diff --git a/llvm/unittests/Transforms/Utils/MemTransferLowering.cpp b/llvm/unittests/Transforms/Utils/MemTransferLowering.cpp
index 54208a1714bd0..91904670b32bf 100644
--- a/llvm/unittests/Transforms/Utils/MemTransferLowering.cpp
+++ b/llvm/unittests/Transforms/Utils/MemTransferLowering.cpp
@@ -41,16 +41,16 @@ struct ForwardingPass : public OptionalPassInfoMixin<ForwardingPass> {
 };
 
 struct MemTransferLowerTest : public testing::Test {
+  LLVMContext Context;
   PassBuilder PB;
   LoopAnalysisManager LAM;
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
   ModulePassManager MPM;
-  LLVMContext Context;
   std::unique_ptr<Module> M;
 
-  MemTransferLowerTest() {
+  MemTransferLowerTest() : PB(Context) {
     // Register all the basic analyses with the managers.
     PB.registerModuleAnalyses(MAM);
     PB.registerCGSCCAnalyses(CGAM);
diff --git a/mlir/lib/ExecutionEngine/OptUtils.cpp b/mlir/lib/ExecutionEngine/OptUtils.cpp
index c6962bb921b9d..e657366086e23 100644
--- a/mlir/lib/ExecutionEngine/OptUtils.cpp
+++ b/mlir/lib/ExecutionEngine/OptUtils.cpp
@@ -66,7 +66,7 @@ mlir::makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel,
     tuningOptions.LoopVectorization = true;
     tuningOptions.SLPVectorization = true;
 
-    PassBuilder pb(targetMachine, tuningOptions);
+    PassBuilder pb(m->getContext(), targetMachine, tuningOptions);
 
     pb.registerModuleAnalyses(mam);
     pb.registerCGSCCAnalyses(cgam);
diff --git a/offload/plugins-nextgen/common/src/JIT.cpp b/offload/plugins-nextgen/common/src/JIT.cpp
index b78c9b1768139..fa70b702c10f6 100644
--- a/offload/plugins-nextgen/common/src/JIT.cpp
+++ b/offload/plugins-nextgen/common/src/JIT.cpp
@@ -156,7 +156,7 @@ void JITEngine::opt(TargetMachine *TM, TargetLibraryInfoImpl *TLII, Module &M,
   ModuleAnalysisManager MAM;
   ModulePassManager MPM;
 
-  PassBuilder PB(TM, PTO, PGOOpt, nullptr);
+  PassBuilder PB(M.getContext(), TM, PTO, PGOOpt, nullptr);
 
   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
 
diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index 63c73b8523143..fd648d2a20adc 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -458,15 +458,15 @@ parsePollyCustomOptions(StringRef Params) {
 /// @param EnableForOpt Whether to add Polly IR transformations. If False, only
 ///                     the analysis passes are added, skipping Polly itself.
 ///                     The IR may still be modified.
-static void
-buildCommonPollyPipeline(const cl::LibraryOptionsContext *LibraryOptions,
-                         FunctionPassManager &PM, OptimizationLevel Level,
-                         IntrusiveRefCntPtr<vfs::FileSystem> FS,
-                         bool EnableForOpt) {
-  PassBuilder PB(
-      /*TM=*/nullptr, PipelineTuningOptions(LibraryOptions),
-      /*PGOOpt=*/{},
-      /*PIC=*/nullptr, std::move(FS));
+static void buildCommonPollyPipeline(LLVMContext &Context,
+                                     FunctionPassManager &PM,
+                                     OptimizationLevel Level,
+                                     IntrusiveRefCntPtr<vfs::FileSystem> FS,
+                                     bool EnableForOpt) {
+  PassBuilder PB(Context, /*TM=*/nullptr,
+                 PipelineTuningOptions(&Context.getLibraryOptions()),
+                 /*PGOOpt=*/{},
+                 /*PIC=*/nullptr, std::move(FS));
 
   ExitOnError Err("Inconsistent Polly configuration: ");
   PollyPassOptions &&Opts =
@@ -480,11 +480,10 @@ buildCommonPollyPipeline(const cl::LibraryOptionsContext *LibraryOptions,
     PM.addPass(llvm::CFGPrinterPass());
 }
 
-static void
-buildEarlyPollyPipeline(const cl::LibraryOptionsContext *LibraryOptions,
-                        llvm::ModulePassManager &MPM,
-                        llvm::OptimizationLevel Level,
-                        IntrusiveRefCntPtr<vfs::FileSystem> FS) {
+static void buildEarlyPollyPipeline(LLVMContext &Context,
+                                    llvm::ModulePassManager &MPM,
+                                    llvm::OptimizationLevel Level,
+                                    IntrusiveRefCntPtr<vfs::FileSystem> FS) {
   bool EnableForOpt =
       shouldEnablePollyForOptimization() && Level != OptimizationLevel::O0;
   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
@@ -503,8 +502,7 @@ buildEarlyPollyPipeline(const cl::LibraryOptionsContext *LibraryOptions,
     FPM = FunctionPassManager();
   }
 
-  buildCommonPollyPipeline(LibraryOptions, FPM, Level, std::move(FS),
-                           EnableForOpt);
+  buildCommonPollyPipeline(Context, FPM, Level, std::move(FS), EnableForOpt);
   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
 
   if (DumpAfter)
@@ -513,10 +511,10 @@ buildEarlyPollyPipeline(const cl::LibraryOptionsContext *LibraryOptions,
     MPM.addPass(DumpModulePass(Filename, false));
 }
 
-static void
-buildLatePollyPipeline(const cl::LibraryOptionsContext *LibraryOptions,
-                       FunctionPassManager &PM, llvm::OptimizationLevel Level,
-                       IntrusiveRefCntPtr<vfs::FileSystem> FS) {
+static void buildLatePollyPipeline(LLVMContext &Context,
+                                   FunctionPassManager &PM,
+                                   llvm::OptimizationLevel Level,
+                                   IntrusiveRefCntPtr<vfs::FileSystem> FS) {
   bool EnableForOpt =
       shouldEnablePollyForOptimization() && Level != OptimizationLevel::O0;
   if (!shouldEnablePollyForDiagnostic() && !EnableForOpt)
@@ -530,8 +528,7 @@ buildLatePollyPipeline(const cl::LibraryOptionsContext *LibraryOptions,
         "not supported with NPM",
         false);
 
-  buildCommonPollyPipeline(LibraryOptions, PM, Level, std::move(FS),
-                           EnableForOpt);
+  buildCommonPollyPipeline(Context, PM, Level, std::move(FS), EnableForOpt);
 
   if (DumpAfter)
     PM.addPass(DumpFunctionPass("-after"));
@@ -639,7 +636,7 @@ parseModulePipeline(StringRef Name, llvm::ModulePassManager &MPM,
 void registerPollyPasses(PassBuilder &PB) {
   PassInstrumentationCallbacks *PIC = PB.getPassInstrumentationCallbacks();
   IntrusiveRefCntPtr<vfs::FileSystem> FS = PB.getVirtualFileSystemPtr();
-  const cl::LibraryOptionsContext *LibraryOptions = PB.getLibraryOptions();
+  LLVMContext &Context = PB.getContext();
 
 #define MODULE_PASS(NAME, CREATE_PASS, PARSER)                                 \
   {                                                                            \
@@ -683,15 +680,14 @@ void registerPollyPasses(PassBuilder &PB) {
   switch (PassPosition) {
   case POSITION_EARLY:
     PB.registerPipelineStartEPCallback(
-        [FS, LibraryOptions](ModulePassManager &MPM, OptimizationLevel Level) {
-          buildEarlyPollyPipeline(LibraryOptions, MPM, Level, FS);
+        [FS, &Context](ModulePassManager &MPM, OptimizationLevel Level) {
+          buildEarlyPollyPipeline(Context, MPM, Level, FS);
         });
     break;
   case POSITION_BEFORE_VECTORIZER:
     PB.registerVectorizerStartEPCallback(
-        [FS, LibraryOptions](FunctionPassManager &FPM,
-                             OptimizationLevel Level) {
-          buildLatePollyPipeline(LibraryOptions, FPM, Level, FS);
+        [FS, &Context](FunctionPassManager &FPM, OptimizationLevel Level) {
+          buildLatePollyPipeline(Context, FPM, Level, FS);
         });
     break;
   }
diff --git a/polly/lib/Transform/ScopInliner.cpp b/polly/lib/Transform/ScopInliner.cpp
index 222f4914dd456..60ef37438c34c 100644
--- a/polly/lib/Transform/ScopInliner.cpp
+++ b/polly/lib/Transform/ScopInliner.cpp
@@ -52,11 +52,9 @@ bool runScopInlinerImpl(Function *F, SCC_t &SCC,
     return false;
   }
 
-  PassBuilder PB(
-      /*TM=*/nullptr,
-      PipelineTuningOptions(&F->getContext().getLibraryOptions()),
-      /*PGOOpt=*/{},
-      /*PIC=*/nullptr, std::move(FS));
+  PassBuilder PB(F->getContext(), /*TM=*/nullptr, PipelineTuningOptions(),
+                 /*PGOOpt=*/{},
+                 /*PIC=*/nullptr, std::move(FS));
   // Populate analysis managers and register Polly-specific analyses.
   LoopAnalysisManager LAM;
   FunctionAnalysisManager FAM;

>From d8eee0d7139641a2d7b427487b2609b16ec90a52 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Mon, 19 Oct 2026 10:13:23 -0700
Subject: [PATCH 2/2] Rebase after #233146. Read the default
 PipelineTuningOptions from the PassBuilder's context

---
 llvm/include/llvm/Passes/PassBuilder.h         | 5 +++--
 llvm/lib/Passes/PassBuilder.cpp                | 6 ++++--
 llvm/tools/llc/lib/NewPMDriver.cpp             | 3 +--
 llvm/tools/llvm-reduce/deltas/RunIRPasses.cpp  | 4 ++--
 llvm/unittests/IR/PassBuilderCallbacksTest.cpp | 4 ++--
 mlir/lib/ExecutionEngine/OptUtils.cpp          | 2 +-
 offload/plugins-nextgen/common/src/JIT.cpp     | 3 +--
 polly/lib/Support/RegisterPasses.cpp           | 3 +--
 polly/lib/Transform/ScopInliner.cpp            | 2 +-
 9 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 641d33dd24bfc..29bb007e3ccf0 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -151,10 +151,11 @@ class PassBuilder {
   };
 
   /// The pipelines read the library options of \p Context, which must outlive
-  /// the PassBuilder.
+  /// the PassBuilder. If \p PTO is not given, it reads its defaults from
+  /// \p Context.
   LLVM_ABI explicit PassBuilder(
       LLVMContext &Context, TargetMachine *TM = nullptr,
-      PipelineTuningOptions PTO = PipelineTuningOptions(),
+      std::optional<PipelineTuningOptions> PTO = std::nullopt,
       std::optional<PGOOptions> PGOOpt = std::nullopt,
       PassInstrumentationCallbacks *PIC = nullptr,
       IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem());
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 6004c3ab4073d..17e56b681df4c 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -567,12 +567,14 @@ static Expected<OptimizationLevel> parseOptLevelParam(StringRef S) {
 }
 
 PassBuilder::PassBuilder(LLVMContext &Context, TargetMachine *TM,
-                         PipelineTuningOptions PTO,
+                         std::optional<PipelineTuningOptions> PTO,
                          std::optional<PGOOptions> PGOOpt,
                          PassInstrumentationCallbacks *PIC,
                          IntrusiveRefCntPtr<vfs::FileSystem> FS)
     : Context(Context), Opts(Context.getLibraryOptions().get<PassesOptions>()),
-      TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
+      TM(TM),
+      PTO(PTO ? *PTO : PipelineTuningOptions(&Context.getLibraryOptions())),
+      PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
   if (TM)
     TM->registerPassBuilderCallbacks(*this);
   if (PIC) {
diff --git a/llvm/tools/llc/lib/NewPMDriver.cpp b/llvm/tools/llc/lib/NewPMDriver.cpp
index 03f5afd45c5e8..4c4b9f8271618 100644
--- a/llvm/tools/llc/lib/NewPMDriver.cpp
+++ b/llvm/tools/llc/lib/NewPMDriver.cpp
@@ -143,8 +143,7 @@ int llvm::compileModuleWithNewPM(
 
   MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });
 
-  PassBuilder PB(Context, Target.get(), PipelineTuningOptions(), std::nullopt,
-                 &PIC);
+  PassBuilder PB(Context, Target.get(), std::nullopt, std::nullopt, &PIC);
   for (auto &PassPlugin : PassPlugins)
     PassPlugin.registerPassBuilderCallbacks(PB);
   PB.registerModuleAnalyses(MAM);
diff --git a/llvm/tools/llvm-reduce/deltas/RunIRPasses.cpp b/llvm/tools/llvm-reduce/deltas/RunIRPasses.cpp
index daf33c5ee24fc..00bb7fb6d2fc1 100644
--- a/llvm/tools/llvm-reduce/deltas/RunIRPasses.cpp
+++ b/llvm/tools/llvm-reduce/deltas/RunIRPasses.cpp
@@ -33,8 +33,8 @@ void llvm::runIRPassesDeltaPass(Oracle &O, ReducerWorkItem &WorkItem) {
   PassInstrumentationCallbacks PIC;
   PIC.registerShouldRunOptionalPassCallback(
       [&](StringRef, IRUnitRef) { return !O.shouldKeep(); });
-  PassBuilder PB(Program.getContext(), nullptr, PipelineTuningOptions(),
-                 std::nullopt, &PIC);
+  PassBuilder PB(Program.getContext(), nullptr, std::nullopt, std::nullopt,
+                 &PIC);
 
   PB.registerModuleAnalyses(MAM);
   PB.registerCGSCCAnalyses(CGAM);
diff --git a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
index 0567476aa13e8..ebaddbe68ca47 100644
--- a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
+++ b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
@@ -460,8 +460,8 @@ class PassBuilderCallbacksTest<PassManager<
                   "exit:\n"
                   "  ret void\n"
                   "}\n")),
-        CallbacksHandle(), PB(Context, nullptr, PipelineTuningOptions(),
-                              std::nullopt, &CallbacksHandle.Callbacks),
+        CallbacksHandle(), PB(Context, nullptr, std::nullopt, std::nullopt,
+                              &CallbacksHandle.Callbacks),
         PM(), LAM(), FAM(), CGAM(), AM() {
 
     EXPECT_TRUE(&CallbacksHandle.Callbacks ==
diff --git a/mlir/lib/ExecutionEngine/OptUtils.cpp b/mlir/lib/ExecutionEngine/OptUtils.cpp
index e657366086e23..2e2f36a35c1af 100644
--- a/mlir/lib/ExecutionEngine/OptUtils.cpp
+++ b/mlir/lib/ExecutionEngine/OptUtils.cpp
@@ -60,7 +60,7 @@ mlir::makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel,
     CGSCCAnalysisManager cgam;
     ModuleAnalysisManager mam;
 
-    PipelineTuningOptions tuningOptions;
+    PipelineTuningOptions tuningOptions(&m->getContext().getLibraryOptions());
     tuningOptions.LoopUnrolling = true;
     tuningOptions.LoopInterleaving = true;
     tuningOptions.LoopVectorization = true;
diff --git a/offload/plugins-nextgen/common/src/JIT.cpp b/offload/plugins-nextgen/common/src/JIT.cpp
index fa70b702c10f6..afa31a0ae3f72 100644
--- a/offload/plugins-nextgen/common/src/JIT.cpp
+++ b/offload/plugins-nextgen/common/src/JIT.cpp
@@ -147,7 +147,6 @@ JITEngine::JITEngine(Triple::ArchType TA) : TT(Triple::getArchTypeName(TA)) {
 
 void JITEngine::opt(TargetMachine *TM, TargetLibraryInfoImpl *TLII, Module &M,
                     unsigned OptLevel) {
-  PipelineTuningOptions PTO;
   std::optional<PGOOptions> PGOOpt;
 
   LoopAnalysisManager LAM;
@@ -156,7 +155,7 @@ void JITEngine::opt(TargetMachine *TM, TargetLibraryInfoImpl *TLII, Module &M,
   ModuleAnalysisManager MAM;
   ModulePassManager MPM;
 
-  PassBuilder PB(M.getContext(), TM, PTO, PGOOpt, nullptr);
+  PassBuilder PB(M.getContext(), TM, std::nullopt, PGOOpt, nullptr);
 
   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
 
diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index fd648d2a20adc..eb98b220f3934 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -463,8 +463,7 @@ static void buildCommonPollyPipeline(LLVMContext &Context,
                                      OptimizationLevel Level,
                                      IntrusiveRefCntPtr<vfs::FileSystem> FS,
                                      bool EnableForOpt) {
-  PassBuilder PB(Context, /*TM=*/nullptr,
-                 PipelineTuningOptions(&Context.getLibraryOptions()),
+  PassBuilder PB(Context, /*TM=*/nullptr, /*PTO=*/std::nullopt,
                  /*PGOOpt=*/{},
                  /*PIC=*/nullptr, std::move(FS));
 
diff --git a/polly/lib/Transform/ScopInliner.cpp b/polly/lib/Transform/ScopInliner.cpp
index 60ef37438c34c..85b8695be8396 100644
--- a/polly/lib/Transform/ScopInliner.cpp
+++ b/polly/lib/Transform/ScopInliner.cpp
@@ -52,7 +52,7 @@ bool runScopInlinerImpl(Function *F, SCC_t &SCC,
     return false;
   }
 
-  PassBuilder PB(F->getContext(), /*TM=*/nullptr, PipelineTuningOptions(),
+  PassBuilder PB(F->getContext(), /*TM=*/nullptr, /*PTO=*/std::nullopt,
                  /*PGOOpt=*/{},
                  /*PIC=*/nullptr, std::move(FS));
   // Populate analysis managers and register Polly-specific analyses.



More information about the Mlir-commits mailing list