[llvm-branch-commits] [llvm] [CodeGen] Declare command line options in TableGen (PR #228729)

Fangrui Song via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Oct 4 00:05:51 PDT 2026


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

>From 952926c5958234e2e5a86c0f103a35047a2e1e44 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sat, 3 Oct 2026 08:05:12 -0700
Subject: [PATCH] [CodeGen] Declare command line options in TableGen

Move the cl::opts of TargetPassConfig.cpp and CodeGenPrepare.cpp into
CodeGenOptions.td, private to lib/CodeGen; other files will follow.
-enable-machine-outliner (cl::ValueOptional) and -regalloc
(RegisterPassParser) stay cl::opt.

CodeGenPrepare and its addressing-mode helpers hold
`const CodeGenOptions &Opts`; TargetPassConfig functions read
CodeGenOptions::Global. getCGPassBuilderOption() converts BoolOrDefault
members to the cl::boolOrDefault and std::optional<bool> fields of the
public CGPassBuilderOption. -basic-block-section-match-infer, which was
not cl::Hidden, is now listed by -help-hidden only.

Aided by Opus 5.5
---
 llvm/lib/CodeGen/CMakeLists.txt               |   8 +
 llvm/lib/CodeGen/CodeGenOptions.cpp           |  15 +
 llvm/lib/CodeGen/CodeGenOptions.h             |  19 +
 llvm/lib/CodeGen/CodeGenOptions.td            | 199 ++++++++
 llvm/lib/CodeGen/CodeGenPrepare.cpp           | 316 ++++--------
 llvm/lib/CodeGen/RegisterUsageInfo.cpp        |   7 +-
 llvm/lib/CodeGen/TargetPassConfig.cpp         | 462 ++++++------------
 .../gn/secondary/llvm/lib/CodeGen/BUILD.gn    |  10 +
 .../llvm-project-overlay/llvm/BUILD.bazel     |  11 +
 9 files changed, 504 insertions(+), 543 deletions(-)
 create mode 100644 llvm/lib/CodeGen/CodeGenOptions.cpp
 create mode 100644 llvm/lib/CodeGen/CodeGenOptions.h
 create mode 100644 llvm/lib/CodeGen/CodeGenOptions.td

diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 7db7c1ca932437..211ce644a4162d 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -33,6 +33,11 @@ elseif (DEFINED LLVM_HAVE_TF_AOT OR LLVM_HAVE_TFLITE)
   endif()
 endif()
 
+set(LLVM_TABLEGEN_PROJECT LLVM_HEADERS)
+set(LLVM_TARGET_DEFINITIONS CodeGenOptions.td)
+tablegen(LLVM CodeGenOptions.inc -gen-opt-parser-defs)
+add_public_tablegen_target(CodeGenOptionsTableGen)
+
 add_llvm_component_library(LLVMCodeGen
   AggressiveAntiDepBreaker.cpp
   AllocationOrder.cpp
@@ -54,6 +59,7 @@ add_llvm_component_library(LLVMCodeGen
   CFIInstrInserter.cpp
   CodeGen.cpp
   CodeGenCommonISel.cpp
+  CodeGenOptions.cpp
   CodeGenPrepare.cpp
   CommandFlags.cpp
   ComplexDeinterleavingPass.cpp
@@ -284,6 +290,7 @@ add_llvm_component_library(LLVMCodeGen
   LINK_LIBS ${LLVM_PTHREAD_LIB} ${MLLinkDeps}
 
   DEPENDS
+  CodeGenOptionsTableGen
   intrinsics_gen
   vt_gen
   ${MLDeps}
@@ -297,6 +304,7 @@ add_llvm_component_library(LLVMCodeGen
   Core
   MC
   ObjCARC
+  Option
   ProfileData
   Scalar
   Support
diff --git a/llvm/lib/CodeGen/CodeGenOptions.cpp b/llvm/lib/CodeGen/CodeGenOptions.cpp
new file mode 100644
index 00000000000000..31cb2dafa020b2
--- /dev/null
+++ b/llvm/lib/CodeGen/CodeGenOptions.cpp
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenOptions.h"
+#include "llvm/Option/LibraryOptions.h"
+
+#define OPTIONS_STRUCT_DEFS
+#include "CodeGenOptions.inc"
+
+static llvm::opt::RegisterLibraryOptions<llvm::CodeGenOptions> Registration;
diff --git a/llvm/lib/CodeGen/CodeGenOptions.h b/llvm/lib/CodeGen/CodeGenOptions.h
new file mode 100644
index 00000000000000..657850dcbe5dff
--- /dev/null
+++ b/llvm/lib/CodeGen/CodeGenOptions.h
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_CODEGENOPTIONS_H
+#define LLVM_LIB_CODEGEN_CODEGENOPTIONS_H
+
+#include "llvm/Target/TargetOptions.h"
+#include <cstdint>
+#include <optional>
+
+#define OPTIONS_STRUCT_DECL
+#include "CodeGenOptions.inc"
+
+#endif // LLVM_LIB_CODEGEN_CODEGENOPTIONS_H
diff --git a/llvm/lib/CodeGen/CodeGenOptions.td b/llvm/lib/CodeGen/CodeGenOptions.td
new file mode 100644
index 00000000000000..7e57091aec67df
--- /dev/null
+++ b/llvm/lib/CodeGen/CodeGenOptions.td
@@ -0,0 +1,199 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/Option/LibraryOptions.td"
+
+def CodeGenOptions : OptionsStruct;
+
+defm : BoolField<"basic-block-section-match-infer", "false",
+  "Enable matching and inference when generating basic block sections">;
+defm : BoolField<"bbsections-guided-section-prefix", "true",
+  "Use the basic-block-sections profile to determine the text section prefix for hot functions. "
+  "Functions with basic-block-sections profile will be placed in `.text.hot` regardless of their FDO profile info. "
+  "Other functions won't be impacted, i.e., their prefixes will be decided by FDO/sampleFDO profiles">;
+defm : BoolField<"cgp-addr-sink-combine-base-gv", "true",
+  "Allow combining of BaseGV field in Address sinking">;
+defm : BoolField<"cgp-addr-sink-combine-base-offs", "true",
+  "Allow combining of BaseOffs field in Address sinking">;
+defm : BoolField<"cgp-addr-sink-combine-base-reg", "true",
+  "Allow combining of BaseReg field in Address sinking">;
+defm : BoolField<"cgp-addr-sink-combine-scaled-reg", "true",
+  "Allow combining of ScaledReg field in Address sinking">;
+defm : BoolField<"cgp-addr-sink-new-phis", "false",
+  "Allow creation of Phis in Address sinking">;
+defm : BoolField<"cgp-addr-sink-new-select", "true",
+  "Allow creation of selects in Address sinking">;
+defm : OptionalBoolField<"cgp-addr-sink-using-gep",
+  "Address sinking in CGP using GEPs">;
+defm : BoolField<"cgp-andcmp-sinking", "true",
+  "Enable sinking and/cmp into branches">;
+defm : BoolField<"cgp-branch-opts", "true",
+  "Enable branch optimizations in CodeGenPrepare">;
+defm : BoolField<"cgp-complex-addr-modes", "true",
+  "Enable combining addressing modes with different parts in optimizeMemoryInst">;
+defm : BoolField<"cgp-delete-phis", "true",
+  "Enable elimination of dead PHI nodes">;
+defm : BoolField<"cgp-ext-ld-promotion", "true",
+  "Enable ext(promotable(ld)) -> promoted(ext(ld)) optimization in CodeGenPrepare">;
+defm : BoolField<"cgp-force-split-store", "false",
+  "Force store splitting no matter what the target query says">;
+defm : ValueField<"cgp-freq-ratio-to-skip-merge", "uint64_t", "2",
+  "Skip merging empty blocks if (frequency of empty block) / (frequency of destination block) is greater than this ratio">;
+defm : BoolField<"cgp-gc-opts", "true",
+  "Enable GC optimizations in CodeGenPrepare">;
+defm : ValueField<"cgp-huge-func", "unsigned", "10000",
+  "Least BB number of huge function">;
+defm : BoolField<"cgp-icmp-eq2icmp-st", "false",
+  "Enable ICMP_EQ to ICMP_S(L|G)T conversion">;
+defm : ValueField<"cgp-max-address-users-to-scan", "unsigned", "100",
+  "Max number of address users to look at">;
+defm : BoolField<"cgp-optimize-phi-types", "true",
+  "Enable converting phi types in CodeGenPrepare">;
+defm : BoolField<"cgp-preheader-prot", "true",
+  "Protect loop preheaders from removal">;
+defm : BoolField<"cgp-select2branch", "true",
+  "Enable select to branch conversion">;
+defm : BoolField<"cgp-split-large-offset-gep", "true",
+  "Enable splitting large offset of GEP">;
+defm : BoolField<"cgp-store-extract", "true",
+  "Enable store(extract) optimizations in CodeGenPrepare">;
+defm : BoolField<"cgp-stress-ext-ld-promotion", "false",
+  "Stress test ext(promotable(ld)) -> promoted(ext(ld)) optimization in CodeGenPrepare">;
+defm : BoolField<"cgp-stress-store-extract", "false",
+  "Stress test store(extract) optimizations in CodeGenPrepare">;
+defm : BoolField<"cgp-type-promotion-merge", "true",
+  "Enable merging of redundant sexts when one is dominating the other">;
+defm : BoolField<"cgp-verify-bfi-updates", "false",
+  "Enable BFI update verification for CodeGenPrepare">;
+defm : BoolField<"codegen-pipeline-trigger-crash", "false",
+  "Trigger crash in codegen pipeline">;
+defm : OptionalBoolField<"debugify-and-strip-all-safe",
+  "Debugify MIR before and Strip debug after each pass except those known to be unsafe when debug info is present">;
+defm : OptionalBoolField<"debugify-check-and-strip-all-safe",
+  "Debugify MIR before, by checking and stripping the debug info after, each pass except those known to be unsafe when debug info is present">;
+defm : BoolField<"disable-atexit-based-global-dtor-lowering", "false",
+  "For MachO, disable atexit()-based global destructor lowering">;
+defm : BoolField<"disable-block-placement", "false",
+  "Disable probability-driven block placement">;
+defm : BoolField<"disable-branch-fold", "false",
+  "Disable branch folding">;
+// Disable the pass to fix unwind information. Whether the pass is included in
+// the pipeline is controlled via the target options, this option serves as
+// manual override.
+defm : BoolField<"disable-cfi-fixup", "false",
+  "Disable the CFI fixup pass">;
+defm : BoolField<"disable-cgp", "false",
+  "Disable Codegen Prepare">;
+defm : BoolField<"disable-constant-hoisting", "false",
+  "Disable ConstantHoisting">;
+defm : BoolField<"disable-copyprop", "false",
+  "Disable Copy Propagation pass">;
+defm : BoolField<"disable-early-ifcvt", "false",
+  "Disable Early If-conversion">;
+defm : BoolField<"disable-early-taildup", "false",
+  "Disable pre-register allocation tail duplication">;
+defm : BoolField<"disable-expand-reductions", "false",
+  "Disable the expand reduction intrinsics pass from running">;
+// Disable MIRProfileLoader before BlockPlacement. This is for debugging and
+// tuning purposes.
+defm : BoolField<"disable-layout-fsprofile-loader", "false",
+  "Disable MIRProfileLoader before BlockPlacement">;
+defm : BoolField<"disable-lsr", "false",
+  "Disable Loop Strength Reduction Pass">;
+defm : BoolField<"disable-machine-cse", "false",
+  "Disable Machine Common Subexpression Elimination">;
+defm : BoolField<"disable-machine-dce", "false",
+  "Disable Machine Dead Code Elimination">;
+defm : BoolField<"disable-machine-licm", "false",
+  "Disable Machine LICM">;
+defm : BoolField<"disable-machine-sink", "false",
+  "Disable Machine Sinking">;
+defm : BoolField<"disable-partial-libcall-inlining", "false",
+  "Disable Partial Libcall Inlining">;
+defm : BoolField<"disable-post-ra", "false",
+  "Disable Post Regalloc Scheduler">;
+defm : BoolField<"disable-postra-machine-licm", "false",
+  "Disable Machine LICM">;
+defm : BoolField<"disable-postra-machine-sink", "false",
+  "Disable PostRA Machine Sinking">;
+// Disable MIRProfileLoader before RegAlloc. This is for debugging and tuning
+// purpose.
+defm : BoolField<"disable-ra-fsprofile-loader", "false",
+  "Disable MIRProfileLoader before RegAlloc">;
+defm : BoolField<"disable-replace-with-vec-lib", "false",
+  "Disable replace with vector math call pass">;
+defm : BoolField<"disable-select-optimize", "true",
+  "Disable the select-optimization pass from running">;
+defm : BoolField<"disable-ssc", "false",
+  "Disable Stack Slot Coloring">;
+defm : BoolField<"disable-tail-duplicate", "false",
+  "Disable tail duplication">;
+defm : BoolField<"enable-block-placement-stats", "false",
+  "Collect probability-driven block placement stats">;
+defm : BoolField<"enable-gc-empty-basic-blocks", "false",
+  "Enable garbage-collecting empty basic blocks">;
+defm : BoolField<"enable-global-merge-func", "false",
+  "Enable global merge functions that are based on hash function">;
+defm : BoolField<"enable-implicit-null-checks", "false",
+  "Fold null checks into faulting memory operations">;
+defm : OptionalBoolField<"enable-ipra",
+  "Enable interprocedural register allocation to reduce load/store at procedure calls">;
+defm : BoolField<"enable-split-machine-functions", "false",
+  "Split out cold blocks from machine functions based on profile information">;
+// -fast-isel selects FastISel at any optimization level, and -fast-isel=0
+// disables it at -O0, where it is used unless GlobalISel is enabled.
+defm : OptionalBoolField<"fast-isel",
+  "Enable the \"fast\" instruction selector">;
+let MetaVarName = "<filename>" in
+defm : ValueField<"fs-profile-file", "StringRef", "",
+  "Flow Sensitive profile file name">;
+let MetaVarName = "<filename>" in
+defm : ValueField<"fs-remapping-file", "StringRef", "",
+  "Flow Sensitive profile remapping file name">;
+defm : OptionalBoolField<"global-isel",
+  "Enable the \"global\" instruction selector">;
+defm : EnumField<"global-isel-abort", "std::optional<GlobalISelAbortMode>", "std::nullopt",
+  "0,1,2", ["GlobalISelAbortMode::Disable", "GlobalISelAbortMode::Enable",
+            "GlobalISelAbortMode::DisableWithDiag"],
+  "Enable abort calls when \"global\" instruction selection fails to lower/select an instruction">;
+// Temporary option to allow experimenting with MachineScheduler as a post-RA
+// scheduler. Targets can "properly" enable this with
+// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID).
+// Targets can return true in targetSchedulesPostRAScheduling() and
+// insert a PostRA scheduling pass wherever it wants.
+defm : BoolField<"misched-postra", "false",
+  "Run MachineScheduler post regalloc (independent of preRA sched)">;
+// FIXME: remove this after switching to NPM or GlobalISel, whichever gets there
+// first...
+defm : BoolField<"print-after-isel", "false",
+  "Print machine instrs after ISel">;
+defm : BoolField<"print-isel-input", "false",
+  "Print LLVM IR input to isel pass">;
+defm : BoolField<"print-regusage", "false",
+  "Print register usage details collected for IPRA">;
+defm : BoolField<"profile-guided-section-prefix", "true",
+  "Use profile info to add section prefix for hot/cold functions">;
+defm : BoolField<"profile-unknown-in-special-section", "false",
+  "In profiling mode like sampleFDO, if a function doesn't have profile, we cannot tell the function is cold for sure because it may be a function newly added without ever being sampled. "
+  "With the flag enabled, compiler can put such profile unknown functions into a special section, so runtime system can choose to handle it in a different way than .text section, to save RAM for example">;
+defm : BoolField<"split-static-data", "false",
+  "Split static data sections into hot and cold sections using profile information">;
+let MetaVarName = "<pass-name>" in
+defm : ValueField<"start-after", "StringRef", "",
+  "Resume compilation after a specific pass">;
+let MetaVarName = "<pass-name>" in
+defm : ValueField<"start-before", "StringRef", "",
+  "Resume compilation before a specific pass">;
+let MetaVarName = "<pass-name>" in
+defm : ValueField<"stop-after", "StringRef", "",
+  "Stop compilation after a specific pass">;
+let MetaVarName = "<pass-name>" in
+defm : ValueField<"stop-before", "StringRef", "",
+  "Stop compilation before a specific pass">;
+defm : OptionalBoolField<"verify-machineinstrs",
+  "Verify generated machine code">;
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index bf88bcaeb466f7..f6e9f3cd42db75 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/CodeGenPrepare.h"
+#include "CodeGenOptions.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
@@ -137,146 +138,6 @@ STATISTIC(NumDbgValueMoved, "Number of debug value instructions moved");
 STATISTIC(NumSelectsExpanded, "Number of selects turned into branches");
 STATISTIC(NumStoreExtractExposed, "Number of store(extractelement) exposed");
 
-static cl::opt<bool>
-    EnableBranchOpts("cgp-branch-opts", cl::Hidden, cl::init(true),
-                     cl::desc("Enable branch optimizations in CodeGenPrepare"));
-
-static cl::opt<bool>
-    EnableGCOpts("cgp-gc-opts", cl::Hidden, cl::init(true),
-                 cl::desc("Enable GC optimizations in CodeGenPrepare"));
-
-static cl::opt<bool>
-    EnableSelectToBranch("cgp-select2branch", cl::Hidden, cl::init(true),
-                         cl::desc("Enable select to branch conversion."));
-
-static cl::opt<bool>
-    AddrSinkUsingGEPs("cgp-addr-sink-using-gep", cl::Hidden, cl::init(true),
-                      cl::desc("Address sinking in CGP using GEPs."));
-
-static cl::opt<bool>
-    EnableAndCmpSinking("cgp-andcmp-sinking", cl::Hidden, cl::init(true),
-                        cl::desc("Enable sinking and/cmp into branches."));
-
-static cl::opt<bool> EnableStoreExtract(
-    "cgp-store-extract", cl::Hidden, cl::init(true),
-    cl::desc("Enable store(extract) optimizations in CodeGenPrepare"));
-
-static cl::opt<bool> StressStoreExtract(
-    "cgp-stress-store-extract", cl::Hidden, cl::init(false),
-    cl::desc("Stress test store(extract) optimizations in CodeGenPrepare"));
-
-static cl::opt<bool> EnableExtLdPromotion(
-    "cgp-ext-ld-promotion", cl::Hidden, cl::init(true),
-    cl::desc("Enable ext(promotable(ld)) -> promoted(ext(ld)) optimization in "
-             "CodeGenPrepare"));
-
-static cl::opt<bool> StressExtLdPromotion(
-    "cgp-stress-ext-ld-promotion", cl::Hidden, cl::init(false),
-    cl::desc("Stress test ext(promotable(ld)) -> promoted(ext(ld)) "
-             "optimization in CodeGenPrepare"));
-
-static cl::opt<bool>
-    EnablePreheaderProtect("cgp-preheader-prot", cl::Hidden, cl::init(true),
-                           cl::desc("Protect loop preheaders from removal"));
-
-static cl::opt<bool> ProfileGuidedSectionPrefix(
-    "profile-guided-section-prefix", cl::Hidden, cl::init(true),
-    cl::desc("Use profile info to add section prefix for hot/cold functions"));
-
-static cl::opt<bool> ProfileUnknownInSpecialSection(
-    "profile-unknown-in-special-section", cl::Hidden,
-    cl::desc("In profiling mode like sampleFDO, if a function doesn't have "
-             "profile, we cannot tell the function is cold for sure because "
-             "it may be a function newly added without ever being sampled. "
-             "With the flag enabled, compiler can put such profile unknown "
-             "functions into a special section, so runtime system can choose "
-             "to handle it in a different way than .text section, to save "
-             "RAM for example. "));
-
-static cl::opt<bool> BBSectionsGuidedSectionPrefix(
-    "bbsections-guided-section-prefix", cl::Hidden, cl::init(true),
-    cl::desc("Use the basic-block-sections profile to determine the text "
-             "section prefix for hot functions. Functions with "
-             "basic-block-sections profile will be placed in `.text.hot` "
-             "regardless of their FDO profile info. Other functions won't be "
-             "impacted, i.e., their prefixes will be decided by FDO/sampleFDO "
-             "profiles."));
-
-static cl::opt<uint64_t> FreqRatioToSkipMerge(
-    "cgp-freq-ratio-to-skip-merge", cl::Hidden, cl::init(2),
-    cl::desc("Skip merging empty blocks if (frequency of empty block) / "
-             "(frequency of destination block) is greater than this ratio"));
-
-static cl::opt<bool> ForceSplitStore(
-    "cgp-force-split-store", cl::Hidden, cl::init(false),
-    cl::desc("Force store splitting no matter what the target query says."));
-
-static cl::opt<bool> EnableTypePromotionMerge(
-    "cgp-type-promotion-merge", cl::Hidden,
-    cl::desc("Enable merging of redundant sexts when one is dominating"
-             " the other."),
-    cl::init(true));
-
-static cl::opt<bool> EnableComplexAddrModes(
-    "cgp-complex-addr-modes", cl::Hidden, cl::init(true),
-    cl::desc("Enable combining addressing modes with different parts "
-             "in optimizeMemoryInst."));
-
-static cl::opt<bool>
-    AddrSinkNewPhis("cgp-addr-sink-new-phis", cl::Hidden, cl::init(false),
-                    cl::desc("Allow creation of Phis in Address sinking."));
-
-static cl::opt<bool> AddrSinkNewSelects(
-    "cgp-addr-sink-new-select", cl::Hidden, cl::init(true),
-    cl::desc("Allow creation of selects in Address sinking."));
-
-static cl::opt<bool> AddrSinkCombineBaseReg(
-    "cgp-addr-sink-combine-base-reg", cl::Hidden, cl::init(true),
-    cl::desc("Allow combining of BaseReg field in Address sinking."));
-
-static cl::opt<bool> AddrSinkCombineBaseGV(
-    "cgp-addr-sink-combine-base-gv", cl::Hidden, cl::init(true),
-    cl::desc("Allow combining of BaseGV field in Address sinking."));
-
-static cl::opt<bool> AddrSinkCombineBaseOffs(
-    "cgp-addr-sink-combine-base-offs", cl::Hidden, cl::init(true),
-    cl::desc("Allow combining of BaseOffs field in Address sinking."));
-
-static cl::opt<bool> AddrSinkCombineScaledReg(
-    "cgp-addr-sink-combine-scaled-reg", cl::Hidden, cl::init(true),
-    cl::desc("Allow combining of ScaledReg field in Address sinking."));
-
-static cl::opt<bool>
-    EnableGEPOffsetSplit("cgp-split-large-offset-gep", cl::Hidden,
-                         cl::init(true),
-                         cl::desc("Enable splitting large offset of GEP."));
-
-static cl::opt<bool> EnableICMP_EQToICMP_ST(
-    "cgp-icmp-eq2icmp-st", cl::Hidden, cl::init(false),
-    cl::desc("Enable ICMP_EQ to ICMP_S(L|G)T conversion."));
-
-static cl::opt<bool>
-    VerifyBFIUpdates("cgp-verify-bfi-updates", cl::Hidden, cl::init(false),
-                     cl::desc("Enable BFI update verification for "
-                              "CodeGenPrepare."));
-
-static cl::opt<bool>
-    OptimizePhiTypes("cgp-optimize-phi-types", cl::Hidden, cl::init(true),
-                     cl::desc("Enable converting phi types in CodeGenPrepare"));
-
-static cl::opt<unsigned>
-    HugeFuncThresholdInCGPP("cgp-huge-func", cl::init(10000), cl::Hidden,
-                            cl::desc("Least BB number of huge function."));
-
-static cl::opt<unsigned>
-    MaxAddressUsersToScan("cgp-max-address-users-to-scan", cl::init(100),
-                          cl::Hidden,
-                          cl::desc("Max number of address users to look at"));
-
-static cl::opt<bool>
-    EnableDeletePHIs("cgp-delete-phis", cl::Hidden, cl::init(true),
-                     cl::desc("Enable elimination of dead PHI nodes."));
-
 namespace {
 
 enum ExtType {
@@ -307,6 +168,7 @@ class TypePromotionTransaction;
 
 class CodeGenPrepare {
   friend class CodeGenPrepareLegacyPass;
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   const TargetMachine *TM = nullptr;
   const TargetSubtargetInfo *SubtargetInfo = nullptr;
   const TargetLowering *TLI = nullptr;
@@ -587,10 +449,10 @@ bool CodeGenPrepare::_run(Function &F) {
   OptSize = F.hasOptSize();
   // Use the basic-block-sections profile to promote hot functions to .text.hot
   // if requested.
-  if (BBSectionsGuidedSectionPrefix && BBSectionsProfileReader &&
+  if (Opts.bbsections_guided_section_prefix && BBSectionsProfileReader &&
       BBSectionsProfileReader->isFunctionHot(F.getName())) {
     (void)F.setSectionPrefix("hot");
-  } else if (ProfileGuidedSectionPrefix) {
+  } else if (Opts.profile_guided_section_prefix) {
     // The hot attribute overwrites profile count based hotness while profile
     // counts based hotness overwrite the cold attribute.
     // This is a conservative behabvior.
@@ -603,8 +465,8 @@ bool CodeGenPrepare::_run(Function &F) {
     else if (PSI->isFunctionColdInCallGraph(&F, *BFI) ||
              F.hasFnAttribute(Attribute::Cold))
       (void)F.setSectionPrefix("unlikely");
-    else if (ProfileUnknownInSpecialSection && PSI->hasPartialSampleProfile() &&
-             PSI->isFunctionHotnessUnknown(F))
+    else if (Opts.profile_unknown_in_special_section &&
+             PSI->hasPartialSampleProfile() && PSI->isFunctionHotnessUnknown(F))
       (void)F.setSectionPrefix("unknown");
   }
 
@@ -641,7 +503,7 @@ bool CodeGenPrepare::_run(Function &F) {
   if (ResetLI)
     resetLoopInfo();
 
-  if (EnableBranchOpts)
+  if (Opts.cgp_branch_opts)
     EverMadeChange |= splitBranchCondition(F);
 
   // Split some critical edges where one of the sources is an indirect branch,
@@ -663,7 +525,7 @@ bool CodeGenPrepare::_run(Function &F) {
 
   // If we are optimzing huge function, we need to consider the build time.
   // Because the basic algorithm's complex is near O(N!).
-  IsHugeFunc = F.size() > HugeFuncThresholdInCGPP;
+  IsHugeFunc = F.size() > Opts.cgp_huge_func;
 
   bool MadeChange = true;
   bool FuncIterated = false;
@@ -707,7 +569,7 @@ bool CodeGenPrepare::_run(Function &F) {
     // We have iterated all the BB in the (only work for huge) function.
     FuncIterated = IsHugeFunc;
 
-    if (EnableTypePromotionMerge && !ValToSExtendedUses.empty())
+    if (Opts.cgp_type_promotion_merge && !ValToSExtendedUses.empty())
       MadeChange |= mergeSExts(F);
     if (!LargeOffsetGEPMap.empty())
       MadeChange |= splitLargeGEPOffsets();
@@ -743,7 +605,7 @@ bool CodeGenPrepare::_run(Function &F) {
   // LoopInfo is not needed anymore and ConstantFoldTerminator can break it.
   LI = nullptr;
 
-  if (EnableBranchOpts) {
+  if (Opts.cgp_branch_opts) {
     MadeChange = false;
     // Use a set vector to get deterministic iteration order. The order the
     // blocks are removed may affect whether or not PHI nodes in successors
@@ -784,7 +646,7 @@ bool CodeGenPrepare::_run(Function &F) {
     EverMadeChange |= MadeChange;
   }
 
-  if (EnableGCOpts) {
+  if (Opts.cgp_gc_opts) {
     SmallVector<GCStatepointInst *, 2> Statepoints;
     for (BasicBlock &BB : F)
       for (Instruction &I : BB)
@@ -800,7 +662,7 @@ bool CodeGenPrepare::_run(Function &F) {
   EverMadeChange |= placePseudoProbes(F);
 
 #ifndef NDEBUG
-  if (VerifyBFIUpdates)
+  if (Opts.cgp_verify_bfi_updates)
     verifyBFIUpdates(F);
 #endif
 
@@ -951,7 +813,7 @@ bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &F, bool &ResetLI) {
   // Note that this intentionally skips the entry block.
   for (auto &Block : llvm::drop_begin(F)) {
     // Delete phi nodes that could block deleting other empty blocks.
-    if (EnableDeletePHIs)
+    if (Opts.cgp_delete_phis)
       MadeChange |= DeleteDeadPHIs(&Block, TLInfo, nullptr, &KnownNonDeadPHIs);
   }
 
@@ -977,7 +839,7 @@ bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
   // Loop preheaders can be good locations to spill registers. If the
   // preheader is deleted and we create a critical edge, registers may be
   // spilled in the loop body instead.
-  if (EnablePreheaderProtect && isPreheader &&
+  if (Opts.cgp_preheader_prot && isPreheader &&
       !(BB->getSinglePredecessor() &&
         BB->getSinglePredecessor()->getSingleSuccessor()))
     return false;
@@ -1050,7 +912,8 @@ bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB,
         DestBB == findDestBlockOfMergeableEmptyBlock(SameValueBB))
       BBFreq += BFI->getBlockFreq(SameValueBB);
 
-  std::optional<BlockFrequency> Limit = BBFreq.mul(FreqRatioToSkipMerge);
+  std::optional<BlockFrequency> Limit =
+      BBFreq.mul(Opts.cgp_freq_ratio_to_skip_merge);
   return !Limit || PredFreq <= *Limit;
 }
 
@@ -2012,9 +1875,9 @@ static bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI,
 /// comparison.
 ///
 /// Return true if any changes are made.
-static bool foldICmpWithDominatingICmp(CmpInst *Cmp,
-                                       const TargetLowering &TLI) {
-  if (!EnableICMP_EQToICMP_ST && TLI.isEqualityCmpFoldedWithSignedCmp())
+static bool foldICmpWithDominatingICmp(CmpInst *Cmp, const TargetLowering &TLI,
+                                       bool EnableICmpEqToICmpSt) {
+  if (!EnableICmpEqToICmpSt && TLI.isEqualityCmpFoldedWithSignedCmp())
     return false;
 
   ICmpInst::Predicate Pred = Cmp->getPredicate();
@@ -2318,7 +2181,7 @@ bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) {
   if (unfoldPowerOf2Test(Cmp))
     return true;
 
-  if (foldICmpWithDominatingICmp(Cmp, *TLI))
+  if (foldICmpWithDominatingICmp(Cmp, *TLI, Opts.cgp_icmp_eq2icmp_st))
     return true;
 
   if (swapICmpOperandsToExposeCSEOpportunities(Cmp))
@@ -3158,7 +3021,7 @@ bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB,
 
     // Duplicate the return into TailCallBB.
     (void)FoldReturnIntoUncondBranch(RetI, BB, TailCallBB, DTU);
-    assert(!VerifyBFIUpdates ||
+    assert(!Opts.cgp_verify_bfi_updates ||
            BFI->getBlockFreq(BB) >= BFI->getBlockFreq(TailCallBB));
     BFI->setBlockFreq(BB,
                       (BFI->getBlockFreq(BB) - BFI->getBlockFreq(TailCallBB)));
@@ -3890,6 +3753,7 @@ class AddressingModeMatcher {
 
   ProfileSummaryInfo *PSI;
   BlockFrequencyInfo *BFI;
+  const CodeGenOptions &Opts;
 
   AddressingModeMatcher(
       SmallVectorImpl<Instruction *> &AMI, const TargetLowering &TLI,
@@ -3899,12 +3763,13 @@ class AddressingModeMatcher {
       const SetOfInstrs &InsertedInsts, InstrToOrigTy &PromotedInsts,
       TypePromotionTransaction &TPT,
       std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
-      bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI)
-      : AddrModeInsts(AMI), TLI(TLI), TRI(TRI),
-        DL(MI->getDataLayout()), LI(LI), getDTFn(getDTFn),
-        AccessTy(AT), AddrSpace(AS), MemoryInst(MI), AddrMode(AM),
-        InsertedInsts(InsertedInsts), PromotedInsts(PromotedInsts), TPT(TPT),
-        LargeOffsetGEP(LargeOffsetGEP), OptSize(OptSize), PSI(PSI), BFI(BFI) {
+      bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
+      const CodeGenOptions &Opts)
+      : AddrModeInsts(AMI), TLI(TLI), TRI(TRI), DL(MI->getDataLayout()), LI(LI),
+        getDTFn(getDTFn), AccessTy(AT), AddrSpace(AS), MemoryInst(MI),
+        AddrMode(AM), InsertedInsts(InsertedInsts),
+        PromotedInsts(PromotedInsts), TPT(TPT), LargeOffsetGEP(LargeOffsetGEP),
+        OptSize(OptSize), PSI(PSI), BFI(BFI), Opts(Opts) {
     IgnoreProfitability = false;
   }
 
@@ -3924,13 +3789,14 @@ class AddressingModeMatcher {
         const TargetRegisterInfo &TRI, const SetOfInstrs &InsertedInsts,
         InstrToOrigTy &PromotedInsts, TypePromotionTransaction &TPT,
         std::pair<AssertingVH<GetElementPtrInst>, int64_t> &LargeOffsetGEP,
-        bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
+        bool OptSize, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
+        const CodeGenOptions &Opts) {
     ExtAddrMode Result;
 
-    bool Success = AddressingModeMatcher(AddrModeInsts, TLI, TRI, LI, getDTFn,
-                                         AccessTy, AS, MemoryInst, Result,
-                                         InsertedInsts, PromotedInsts, TPT,
-                                         LargeOffsetGEP, OptSize, PSI, BFI)
+    bool Success = AddressingModeMatcher(
+                       AddrModeInsts, TLI, TRI, LI, getDTFn, AccessTy, AS,
+                       MemoryInst, Result, InsertedInsts, PromotedInsts, TPT,
+                       LargeOffsetGEP, OptSize, PSI, BFI, Opts)
                        .matchAddr(V, 0);
     (void)Success;
     assert(Success && "Couldn't select *anything*?");
@@ -4170,6 +4036,7 @@ class AddressingModeCombiner {
   Type *CommonType = nullptr;
 
   const DataLayout &DL;
+  const CodeGenOptions &Opts;
 
   /// Original Address.
   Value *Original;
@@ -4178,8 +4045,9 @@ class AddressingModeCombiner {
   Value *CommonValue = nullptr;
 
 public:
-  AddressingModeCombiner(const DataLayout &DL, Value *OriginalValue)
-      : DL(DL), Original(OriginalValue) {}
+  AddressingModeCombiner(const DataLayout &DL, const CodeGenOptions &Opts,
+                         Value *OriginalValue)
+      : DL(DL), Opts(Opts), Original(OriginalValue) {}
 
   ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
 
@@ -4351,14 +4219,14 @@ class AddressingModeCombiner {
     // Second Step, fill new nodes by merged values and simplify if possible.
     FillPlaceholders(Map, TraverseOrder, ST);
 
-    if (!AddrSinkNewSelects && ST.countNewSelectNodes() > 0) {
+    if (!Opts.cgp_addr_sink_new_select && ST.countNewSelectNodes() > 0) {
       ST.destroyNewNodes(CommonType);
       return nullptr;
     }
 
     // Now we'd like to match New Phi nodes to existed ones.
     unsigned PhiNotMatchedCount = 0;
-    if (!MatchPhiSet(ST, AddrSinkNewPhis, PhiNotMatchedCount)) {
+    if (!MatchPhiSet(ST, Opts.cgp_addr_sink_new_phis, PhiNotMatchedCount)) {
       ST.destroyNewNodes(CommonType);
       return nullptr;
     }
@@ -4551,19 +4419,19 @@ class AddressingModeCombiner {
   }
 
   bool addrModeCombiningAllowed() {
-    if (!EnableComplexAddrModes)
+    if (!Opts.cgp_complex_addr_modes)
       return false;
     switch (DifferentField) {
     default:
       return false;
     case ExtAddrMode::BaseRegField:
-      return AddrSinkCombineBaseReg;
+      return Opts.cgp_addr_sink_combine_base_reg;
     case ExtAddrMode::BaseGVField:
-      return AddrSinkCombineBaseGV;
+      return Opts.cgp_addr_sink_combine_base_gv;
     case ExtAddrMode::BaseOffsField:
-      return AddrSinkCombineBaseOffs;
+      return Opts.cgp_addr_sink_combine_base_offs;
     case ExtAddrMode::ScaledRegField:
-      return AddrSinkCombineScaledReg;
+      return Opts.cgp_addr_sink_combine_scaled_reg;
     }
   }
 };
@@ -5331,26 +5199,26 @@ bool AddressingModeMatcher::matchOperationAddr(User *AddrInst, unsigned Opcode,
       }
       AddrMode.BaseOffs -= ConstantOffset;
 
-      if (EnableGEPOffsetSplit && isa<GetElementPtrInst>(AddrInst) &&
+      if (Opts.cgp_split_large_offset_gep && isa<GetElementPtrInst>(AddrInst) &&
           TLI.shouldConsiderGEPOffsetSplit() && Depth == 0 &&
           ConstantOffset > 0) {
-          // Record GEPs with non-zero offsets as candidates for splitting in
-          // the event that the offset cannot fit into the r+i addressing mode.
-          // Simple and common case that only one GEP is used in calculating the
-          // address for the memory access.
-          Value *Base = AddrInst->getOperand(0);
-          auto *BaseI = dyn_cast<Instruction>(Base);
-          auto *GEP = cast<GetElementPtrInst>(AddrInst);
-          if (isa<Argument>(Base) || isa<GlobalValue>(Base) ||
-              (BaseI && !isa<CastInst>(BaseI) &&
-               !isa<GetElementPtrInst>(BaseI))) {
-            // Make sure the parent block allows inserting non-PHI instructions
-            // before the terminator.
-            BasicBlock *Parent = BaseI ? BaseI->getParent()
-                                       : &GEP->getFunction()->getEntryBlock();
-            if (!Parent->getTerminator()->isEHPad())
+        // Record GEPs with non-zero offsets as candidates for splitting in
+        // the event that the offset cannot fit into the r+i addressing mode.
+        // Simple and common case that only one GEP is used in calculating the
+        // address for the memory access.
+        Value *Base = AddrInst->getOperand(0);
+        auto *BaseI = dyn_cast<Instruction>(Base);
+        auto *GEP = cast<GetElementPtrInst>(AddrInst);
+        if (isa<Argument>(Base) || isa<GlobalValue>(Base) ||
+            (BaseI && !isa<CastInst>(BaseI) &&
+             !isa<GetElementPtrInst>(BaseI))) {
+          // Make sure the parent block allows inserting non-PHI instructions
+          // before the terminator.
+          BasicBlock *Parent =
+              BaseI ? BaseI->getParent() : &GEP->getFunction()->getEntryBlock();
+          if (!Parent->getTerminator()->isEHPad())
             LargeOffsetGEP = std::make_pair(GEP, ConstantOffset);
-          }
+        }
       }
 
       return false;
@@ -5593,7 +5461,7 @@ static bool FindAllMemoryUses(
     Instruction *I, SmallVectorImpl<std::pair<Use *, Type *>> &MemoryUses,
     SmallPtrSetImpl<Instruction *> &ConsideredInsts, const TargetLowering &TLI,
     const TargetRegisterInfo &TRI, bool OptSize, ProfileSummaryInfo *PSI,
-    BlockFrequencyInfo *BFI, unsigned &SeenInsts) {
+    BlockFrequencyInfo *BFI, unsigned &SeenInsts, unsigned MaxUsersToScan) {
   // If we already considered this instruction, we're done.
   if (!ConsideredInsts.insert(I).second)
     return false;
@@ -5606,7 +5474,7 @@ static bool FindAllMemoryUses(
   for (Use &U : I->uses()) {
     // Conservatively return true if we're seeing a large number or a deep chain
     // of users. This avoids excessive compilation times in pathological cases.
-    if (SeenInsts++ >= MaxAddressUsersToScan)
+    if (SeenInsts++ >= MaxUsersToScan)
       return true;
 
     Instruction *UserI = cast<Instruction>(U.getUser());
@@ -5668,7 +5536,7 @@ static bool FindAllMemoryUses(
     }
 
     if (FindAllMemoryUses(UserI, MemoryUses, ConsideredInsts, TLI, TRI, OptSize,
-                          PSI, BFI, SeenInsts))
+                          PSI, BFI, SeenInsts, MaxUsersToScan))
       return true;
   }
 
@@ -5678,14 +5546,13 @@ static bool FindAllMemoryUses(
 static bool FindAllMemoryUses(
     Instruction *I, SmallVectorImpl<std::pair<Use *, Type *>> &MemoryUses,
     const TargetLowering &TLI, const TargetRegisterInfo &TRI, bool OptSize,
-    ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) {
+    ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, unsigned MaxUsersToScan) {
   unsigned SeenInsts = 0;
   SmallPtrSet<Instruction *, 16> ConsideredInsts;
   return FindAllMemoryUses(I, MemoryUses, ConsideredInsts, TLI, TRI, OptSize,
-                           PSI, BFI, SeenInsts);
+                           PSI, BFI, SeenInsts, MaxUsersToScan);
 }
 
-
 /// Return true if Val is already known to be live at the use site that we're
 /// folding it into. If so, there is no cost to include it in the addressing
 /// mode. KnownLive1 and KnownLive2 are two values that we know are live at the
@@ -5768,7 +5635,8 @@ bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
   // for another (at worst.)  In this context, folding an addressing mode into
   // the use is just a particularly nice way of sinking it.
   SmallVector<std::pair<Use *, Type *>, 16> MemoryUses;
-  if (FindAllMemoryUses(I, MemoryUses, TLI, TRI, OptSize, PSI, BFI))
+  if (FindAllMemoryUses(I, MemoryUses, TLI, TRI, OptSize, PSI, BFI,
+                        Opts.cgp_max_address_users_to_scan))
     return false; // Has a non-memory, non-foldable use!
 
   // Now that we know that all uses of this instruction are part of a chain of
@@ -5798,7 +5666,7 @@ bool AddressingModeMatcher::isProfitableToFoldIntoAddressingMode(
     AddressingModeMatcher Matcher(MatchedAddrModeInsts, TLI, TRI, LI, getDTFn,
                                   AddressAccessTy, AS, UserI, Result,
                                   InsertedInsts, PromotedInsts, TPT,
-                                  LargeOffsetGEP, OptSize, PSI, BFI);
+                                  LargeOffsetGEP, OptSize, PSI, BFI, Opts);
     Matcher.IgnoreProfitability = true;
     bool Success = Matcher.matchAddr(Address, 0);
     (void)Success;
@@ -5890,7 +5758,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
   // the graph are compatible.
   bool PhiOrSelectSeen = false;
   SmallVector<Instruction *, 16> AddrModeInsts;
-  AddressingModeCombiner AddrModes(*DL, Addr);
+  AddressingModeCombiner AddrModes(*DL, Opts, Addr);
   TypePromotionTransaction TPT(RemovedInsts);
   TypePromotionTransaction::ConstRestorationPt LastKnownGood =
       TPT.getRestorationPoint();
@@ -5936,7 +5804,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
     ExtAddrMode NewAddrMode = AddressingModeMatcher::Match(
         V, AccessTy, AddrSpace, MemoryInst, AddrModeInsts, *TLI, *LI, getDTFn,
         *TRI, InsertedInsts, PromotedInsts, TPT, LargeOffsetGEP, OptSize, PSI,
-        BFI);
+        BFI, Opts);
 
     GetElementPtrInst *GEP = LargeOffsetGEP.first;
     if (GEP && !NewGEPBases.count(GEP)) {
@@ -6020,8 +5888,9 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
       } else
         SunkAddr = Builder.CreatePointerCast(SunkAddr, Addr->getType());
     }
-  } else if (AddrSinkUsingGEPs || (!AddrSinkUsingGEPs.getNumOccurrences() &&
-                                   SubtargetInfo->addrSinkUsingGEPs())) {
+  } else if (valueOr(Opts.cgp_addr_sink_using_gep, true) ||
+             (Opts.cgp_addr_sink_using_gep == BoolOrDefault::Default &&
+              SubtargetInfo->addrSinkUsingGEPs())) {
     // By default, we use the GEP-based method when AA is used later. This
     // prevents new inttoptr/ptrtoint pairs from degrading AA capabilities.
     LLVM_DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode
@@ -6719,7 +6588,7 @@ bool CodeGenPrepare::tryToPromoteExts(
     // this check inside the for loop is to catch the case where an extension
     // is directly fed by a load because in such case the extension can be moved
     // up without any promotion on its operands.
-    if (!TLI->enableExtLdPromotion() || !EnableExtLdPromotion)
+    if (!TLI->enableExtLdPromotion() || !Opts.cgp_ext_ld_promotion)
       return false;
 
     // Get the action to perform the promotion.
@@ -6757,7 +6626,7 @@ bool CodeGenPrepare::tryToPromoteExts(
     // conservatively ceiling it to 0.
     TotalCreatedInstsCost =
         std::max((long long)0, (TotalCreatedInstsCost - ExtCost));
-    if (!StressExtLdPromotion &&
+    if (!Opts.cgp_stress_ext_ld_promotion &&
         (TotalCreatedInstsCost > 1 ||
          !isPromotedInstructionLegal(*TLI, *DL, PromotedVal) ||
          (ExtCost == 0 && NewExts.size() > 1))) {
@@ -6778,7 +6647,8 @@ bool CodeGenPrepare::tryToPromoteExts(
       // If we have reached to a load, we need this extra profitability check
       // as it could potentially be merged into an ext(load).
       if (isa<LoadInst>(ExtOperand) &&
-          !(StressExtLdPromotion || NewCreatedInstsCost <= ExtCost ||
+          !(Opts.cgp_stress_ext_ld_promotion ||
+            NewCreatedInstsCost <= ExtCost ||
             (ExtOperand->hasOneUse() || hasSameExtUse(ExtOperand, *TLI))))
         continue;
 
@@ -7141,7 +7011,7 @@ bool CodeGenPrepare::optimizePhiType(
 }
 
 bool CodeGenPrepare::optimizePhiTypes(Function &F) {
-  if (!OptimizePhiTypes)
+  if (!Opts.cgp_optimize_phi_types)
     return false;
 
   bool Changed = false;
@@ -7739,7 +7609,7 @@ bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
 /// If we have a SelectInst that will likely profit from branch prediction,
 /// turn it into a branch.
 bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
-  if (!EnableSelectToBranch)
+  if (!Opts.cgp_select2branch)
     return false;
 
   // If the SelectOptimize pass is enabled, selects have already been optimized.
@@ -8205,6 +8075,8 @@ class VectorPromoteHelper {
   /// Cost of combining a store and an extract.
   unsigned StoreExtractCombineCost;
 
+  bool StressStoreExtract;
+
   /// Instruction that will be combined with the transition.
   Instruction *CombineInst = nullptr;
 
@@ -8370,9 +8242,10 @@ class VectorPromoteHelper {
 public:
   VectorPromoteHelper(const DataLayout &DL, const TargetLowering &TLI,
                       const TargetTransformInfo &TTI, Instruction *Transition,
-                      unsigned CombineCost)
+                      unsigned CombineCost, bool StressStoreExtract)
       : DL(DL), TLI(TLI), TTI(TTI), Transition(Transition),
-        StoreExtractCombineCost(CombineCost) {
+        StoreExtractCombineCost(CombineCost),
+        StressStoreExtract(StressStoreExtract) {
     assert(Transition && "Do not know how to promote null");
   }
 
@@ -8493,8 +8366,8 @@ void VectorPromoteHelper::promoteImpl(Instruction *ToBePromoted) {
 /// has this feature and this is profitable.
 bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
   unsigned CombineCost = std::numeric_limits<unsigned>::max();
-  if (!EnableStoreExtract ||
-      (!StressStoreExtract &&
+  if (!Opts.cgp_store_extract ||
+      (!Opts.cgp_stress_store_extract &&
        !TLI->canCombineStoreAndExtract(Inst->getOperand(0)->getType(),
                                        Inst->getOperand(1), CombineCost)))
     return false;
@@ -8508,7 +8381,8 @@ bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
   //      we do not do that for now.
   BasicBlock *Parent = Inst->getParent();
   LLVM_DEBUG(dbgs() << "Found an interesting transition: " << *Inst << '\n');
-  VectorPromoteHelper VPH(*DL, *TLI, *TTI, Inst, CombineCost);
+  VectorPromoteHelper VPH(*DL, *TLI, *TTI, Inst, CombineCost,
+                          Opts.cgp_stress_store_extract);
   // If the transition has more than one use, assume this is not going to be
   // beneficial.
   while (Inst->hasOneUse()) {
@@ -8577,7 +8451,8 @@ bool CodeGenPrepare::optimizeExtractElementInst(Instruction *Inst) {
 /// multiple BBs. The logic in DAG Combine is kept to catch case generated
 /// during code expansion.
 static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL,
-                                const TargetLowering &TLI) {
+                                const TargetLowering &TLI,
+                                bool ForceSplitStore) {
   // Handle simple but common cases only.
   Type *StoreType = SI.getValueOperand()->getType();
 
@@ -9001,7 +8876,7 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) {
   }
 
   if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
-    if (splitMergedValStore(*SI, *DL, *TLI))
+    if (splitMergedValStore(*SI, *DL, *TLI, Opts.cgp_force_split_store))
       return true;
     SI->setMetadata(LLVMContext::MD_invariant_group, nullptr);
     unsigned AS = SI->getPointerAddressSpace();
@@ -9022,7 +8897,8 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) {
 
   BinaryOperator *BinOp = dyn_cast<BinaryOperator>(I);
 
-  if (BinOp && BinOp->getOpcode() == Instruction::And && EnableAndCmpSinking &&
+  if (BinOp && BinOp->getOpcode() == Instruction::And &&
+      Opts.cgp_andcmp_sinking &&
       sinkAndCmp0Expression(BinOp, *TLI, InsertedInsts))
     return true;
 
diff --git a/llvm/lib/CodeGen/RegisterUsageInfo.cpp b/llvm/lib/CodeGen/RegisterUsageInfo.cpp
index d139bd430fb20b..bf2ee0fc57b83f 100644
--- a/llvm/lib/CodeGen/RegisterUsageInfo.cpp
+++ b/llvm/lib/CodeGen/RegisterUsageInfo.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/RegisterUsageInfo.h"
+#include "CodeGenOptions.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
@@ -22,7 +23,6 @@
 #include "llvm/IR/PassManager.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetMachine.h"
 #include <cstdint>
@@ -31,9 +31,6 @@
 
 using namespace llvm;
 
-// Defined in TargetPassConfig.cpp
-extern cl::opt<bool> PrintRegUsage;
-
 INITIALIZE_PASS(PhysicalRegisterUsageInfoWrapperLegacy, "reg-usage-info",
                 "Register Usage Information Storage", false, true)
 
@@ -49,7 +46,7 @@ bool PhysicalRegisterUsageInfo::doInitialization(Module &M) {
 }
 
 bool PhysicalRegisterUsageInfo::doFinalization(Module &M) {
-  if (PrintRegUsage)
+  if (CodeGenOptions::Global.print_regusage)
     print(errs());
 
   RegMasks.shrink_and_clear();
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 9683d988e80848..d4d0b90591c27f 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -12,6 +12,7 @@
 //===---------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/TargetPassConfig.h"
+#include "CodeGenOptions.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -57,51 +58,6 @@
 
 using namespace llvm;
 
-static cl::opt<bool>
-    EnableIPRA("enable-ipra", cl::init(false), cl::Hidden,
-               cl::desc("Enable interprocedural register allocation "
-                        "to reduce load/store at procedure calls."));
-static cl::opt<bool> DisablePostRASched("disable-post-ra", cl::Hidden,
-    cl::desc("Disable Post Regalloc Scheduler"));
-static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
-    cl::desc("Disable branch folding"));
-static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
-    cl::desc("Disable tail duplication"));
-static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden,
-    cl::desc("Disable pre-register allocation tail duplication"));
-static cl::opt<bool> DisableBlockPlacement("disable-block-placement",
-    cl::Hidden, cl::desc("Disable probability-driven block placement"));
-static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats",
-    cl::Hidden, cl::desc("Collect probability-driven block placement stats"));
-static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
-    cl::desc("Disable Stack Slot Coloring"));
-static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden,
-    cl::desc("Disable Machine Dead Code Elimination"));
-static cl::opt<bool> DisableEarlyIfConversion("disable-early-ifcvt", cl::Hidden,
-    cl::desc("Disable Early If-conversion"));
-static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
-    cl::desc("Disable Machine LICM"));
-static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
-    cl::desc("Disable Machine Common Subexpression Elimination"));
-static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm",
-    cl::Hidden,
-    cl::desc("Disable Machine LICM"));
-static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden,
-    cl::desc("Disable Machine Sinking"));
-static cl::opt<bool> DisablePostRAMachineSink("disable-postra-machine-sink",
-    cl::Hidden,
-    cl::desc("Disable PostRA Machine Sinking"));
-static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden,
-    cl::desc("Disable Loop Strength Reduction Pass"));
-static cl::opt<bool> DisableConstantHoisting("disable-constant-hoisting",
-    cl::Hidden, cl::desc("Disable ConstantHoisting"));
-static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden,
-    cl::desc("Disable Codegen Prepare"));
-
-static cl::opt<bool>
-    TriggerCrash("codegen-pipeline-trigger-crash", cl::init(false), cl::Hidden,
-                 cl::desc("Trigger crash in codegen pipeline"));
-
 namespace {
 class TriggerCrashFunctionLegacyPass : public FunctionPass {
 public:
@@ -117,37 +73,6 @@ class TriggerCrashFunctionLegacyPass : public FunctionPass {
 
 char TriggerCrashFunctionLegacyPass::ID = 0;
 
-static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden,
-    cl::desc("Disable Copy Propagation pass"));
-static cl::opt<bool> DisablePartialLibcallInlining("disable-partial-libcall-inlining",
-    cl::Hidden, cl::desc("Disable Partial Libcall Inlining"));
-static cl::opt<bool> DisableAtExitBasedGlobalDtorLowering(
-    "disable-atexit-based-global-dtor-lowering", cl::Hidden,
-    cl::desc("For MachO, disable atexit()-based global destructor lowering"));
-static cl::opt<bool> EnableImplicitNullChecks(
-    "enable-implicit-null-checks",
-    cl::desc("Fold null checks into faulting memory operations"),
-    cl::init(false), cl::Hidden);
-static cl::opt<bool>
-    PrintISelInput("print-isel-input", cl::Hidden,
-                   cl::desc("Print LLVM IR input to isel pass"));
-cl::opt<bool>
-    PrintRegUsage("print-regusage", cl::Hidden,
-                  cl::desc("Print register usage details collected for IPRA"));
-static cl::opt<cl::boolOrDefault>
-    VerifyMachineCode("verify-machineinstrs", cl::Hidden,
-                      cl::desc("Verify generated machine code"));
-static cl::opt<cl::boolOrDefault>
-    DebugifyAndStripAll("debugify-and-strip-all-safe", cl::Hidden,
-                        cl::desc("Debugify MIR before and Strip debug after "
-                                 "each pass except those known to be unsafe "
-                                 "when debug info is present"));
-static cl::opt<cl::boolOrDefault> DebugifyCheckAndStripAll(
-    "debugify-check-and-strip-all-safe", cl::Hidden,
-    cl::desc(
-        "Debugify MIR before, by checking and stripping the debug info after, "
-        "each pass except those known to be unsafe when debug info is "
-        "present"));
 // Enable or disable the MachineOutliner.
 static cl::opt<RunOutliner> EnableMachineOutliner(
     "enable-machine-outliner", cl::desc("Enable the machine outliner"),
@@ -164,73 +89,6 @@ static cl::opt<RunOutliner> EnableMachineOutliner(
         clEnumValN(RunOutliner::NeverOutline, "never", "Disable all outlining"),
         // Sentinel value for unspecified option.
         clEnumValN(RunOutliner::AlwaysOutline, "", "")));
-static cl::opt<bool> EnableGlobalMergeFunc(
-    "enable-global-merge-func", cl::Hidden,
-    cl::desc("Enable global merge functions that are based on hash function"));
-// Disable the pass to fix unwind information. Whether the pass is included in
-// the pipeline is controlled via the target options, this option serves as
-// manual override.
-static cl::opt<bool> DisableCFIFixup("disable-cfi-fixup", cl::Hidden,
-                                     cl::desc("Disable the CFI fixup pass"));
-// Enable or disable FastISel. Both options are needed, because
-// FastISel is enabled by default with -fast, and we wish to be
-// able to enable or disable fast-isel independently from -O0.
-static cl::opt<cl::boolOrDefault>
-EnableFastISelOption("fast-isel", cl::Hidden,
-  cl::desc("Enable the \"fast\" instruction selector"));
-
-static cl::opt<cl::boolOrDefault> EnableGlobalISelOption(
-    "global-isel", cl::Hidden,
-    cl::desc("Enable the \"global\" instruction selector"));
-
-// FIXME: remove this after switching to NPM or GlobalISel, whichever gets there
-//        first...
-static cl::opt<bool>
-    PrintAfterISel("print-after-isel", cl::init(false), cl::Hidden,
-                   cl::desc("Print machine instrs after ISel"));
-
-static cl::opt<GlobalISelAbortMode> EnableGlobalISelAbort(
-    "global-isel-abort", cl::Hidden,
-    cl::desc("Enable abort calls when \"global\" instruction selection "
-             "fails to lower/select an instruction"),
-    cl::values(
-        clEnumValN(GlobalISelAbortMode::Disable, "0", "Disable the abort"),
-        clEnumValN(GlobalISelAbortMode::Enable, "1", "Enable the abort"),
-        clEnumValN(GlobalISelAbortMode::DisableWithDiag, "2",
-                   "Disable the abort but emit a diagnostic on failure")));
-
-// Disable MIRProfileLoader before RegAlloc. This is for for debugging and
-// tuning purpose.
-static cl::opt<bool> DisableRAFSProfileLoader(
-    "disable-ra-fsprofile-loader", cl::init(false), cl::Hidden,
-    cl::desc("Disable MIRProfileLoader before RegAlloc"));
-// Disable MIRProfileLoader before BloackPlacement. This is for for debugging
-// and tuning purpose.
-static cl::opt<bool> DisableLayoutFSProfileLoader(
-    "disable-layout-fsprofile-loader", cl::init(false), cl::Hidden,
-    cl::desc("Disable MIRProfileLoader before BlockPlacement"));
-// Specify FSProfile file name.
-static cl::opt<std::string>
-    FSProfileFile("fs-profile-file", cl::init(""), cl::value_desc("filename"),
-                  cl::desc("Flow Sensitive profile file name."), cl::Hidden);
-// Specify Remapping file for FSProfile.
-static cl::opt<std::string> FSRemappingFile(
-    "fs-remapping-file", cl::init(""), cl::value_desc("filename"),
-    cl::desc("Flow Sensitive profile remapping file name."), cl::Hidden);
-
-// Temporary option to allow experimenting with MachineScheduler as a post-RA
-// scheduler. Targets can "properly" enable this with
-// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID).
-// Targets can return true in targetSchedulesPostRAScheduling() and
-// insert a PostRA scheduling pass wherever it wants.
-static cl::opt<bool> MISchedPostRA(
-    "misched-postra", cl::Hidden,
-    cl::desc(
-        "Run MachineScheduler post regalloc (independent of preRA sched)"));
-
-static cl::opt<bool> DisableReplaceWithVecLib(
-    "disable-replace-with-vec-lib", cl::Hidden,
-    cl::desc("Disable replace with vector math call pass"));
 
 /// Option names for limiting the codegen pipeline.
 /// Those are used in error reporting and we didn't want
@@ -240,59 +98,6 @@ static const char StartBeforeOptName[] = "start-before";
 static const char StopAfterOptName[] = "stop-after";
 static const char StopBeforeOptName[] = "stop-before";
 
-static cl::opt<std::string>
-    StartAfterOpt(StringRef(StartAfterOptName),
-                  cl::desc("Resume compilation after a specific pass"),
-                  cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
-
-static cl::opt<std::string>
-    StartBeforeOpt(StringRef(StartBeforeOptName),
-                   cl::desc("Resume compilation before a specific pass"),
-                   cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
-
-static cl::opt<std::string>
-    StopAfterOpt(StringRef(StopAfterOptName),
-                 cl::desc("Stop compilation after a specific pass"),
-                 cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
-
-static cl::opt<std::string>
-    StopBeforeOpt(StringRef(StopBeforeOptName),
-                  cl::desc("Stop compilation before a specific pass"),
-                  cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
-
-/// Enable the machine function splitter pass.
-static cl::opt<bool> EnableMachineFunctionSplitter(
-    "enable-split-machine-functions", cl::Hidden,
-    cl::desc("Split out cold blocks from machine functions based on profile "
-             "information."));
-
-/// Disable the expand reductions pass for testing.
-static cl::opt<bool> DisableExpandReductions(
-    "disable-expand-reductions", cl::init(false), cl::Hidden,
-    cl::desc("Disable the expand reduction intrinsics pass from running"));
-
-/// Disable the select optimization pass.
-static cl::opt<bool> DisableSelectOptimize(
-    "disable-select-optimize", cl::init(true), cl::Hidden,
-    cl::desc("Disable the select-optimization pass from running"));
-
-/// Enable garbage-collecting empty basic blocks.
-static cl::opt<bool> EnableGCEmptyBlocks(
-    "enable-gc-empty-basic-blocks", cl::init(false), cl::Hidden,
-    cl::desc("Enable garbage-collecting empty basic blocks"));
-
-static cl::opt<bool>
-    SplitStaticData("split-static-data", cl::Hidden, cl::init(false),
-                    cl::desc("Split static data sections into hot and cold "
-                             "sections using profile information"));
-
-/// Enable matching and inference when using propeller.
-static cl::opt<bool> BasicBlockSectionMatchInfer(
-    "basic-block-section-match-infer",
-    cl::desc(
-        "Enable matching and inference when generating basic block sections"),
-    cl::init(false));
-
 /// Allow standard passes to be disabled by command line options. This supports
 /// simple binary flags that either suppress the pass or do nothing.
 /// i.e. -disable-mypass=false has no effect.
@@ -318,47 +123,48 @@ static IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID,
 /// on where in the pipeline that pass is added.
 static IdentifyingPassPtr overridePass(AnalysisID StandardID,
                                        IdentifyingPassPtr TargetID) {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   if (StandardID == &PostRASchedulerID)
-    return applyDisable(TargetID, DisablePostRASched);
+    return applyDisable(TargetID, Opts.disable_post_ra);
 
   if (StandardID == &BranchFolderPassID)
-    return applyDisable(TargetID, DisableBranchFold);
+    return applyDisable(TargetID, Opts.disable_branch_fold);
 
   if (StandardID == &TailDuplicateLegacyID)
-    return applyDisable(TargetID, DisableTailDuplicate);
+    return applyDisable(TargetID, Opts.disable_tail_duplicate);
 
   if (StandardID == &EarlyTailDuplicateLegacyID)
-    return applyDisable(TargetID, DisableEarlyTailDup);
+    return applyDisable(TargetID, Opts.disable_early_taildup);
 
   if (StandardID == &MachineBlockPlacementID)
-    return applyDisable(TargetID, DisableBlockPlacement);
+    return applyDisable(TargetID, Opts.disable_block_placement);
 
   if (StandardID == &StackSlotColoringID)
-    return applyDisable(TargetID, DisableSSC);
+    return applyDisable(TargetID, Opts.disable_ssc);
 
   if (StandardID == &DeadMachineInstructionElimID)
-    return applyDisable(TargetID, DisableMachineDCE);
+    return applyDisable(TargetID, Opts.disable_machine_dce);
 
   if (StandardID == &EarlyIfConverterLegacyID)
-    return applyDisable(TargetID, DisableEarlyIfConversion);
+    return applyDisable(TargetID, Opts.disable_early_ifcvt);
 
   if (StandardID == &EarlyMachineLICMID)
-    return applyDisable(TargetID, DisableMachineLICM);
+    return applyDisable(TargetID, Opts.disable_machine_licm);
 
   if (StandardID == &MachineCSELegacyID)
-    return applyDisable(TargetID, DisableMachineCSE);
+    return applyDisable(TargetID, Opts.disable_machine_cse);
 
   if (StandardID == &MachineLICMID)
-    return applyDisable(TargetID, DisablePostRAMachineLICM);
+    return applyDisable(TargetID, Opts.disable_postra_machine_licm);
 
   if (StandardID == &MachineSinkingLegacyID)
-    return applyDisable(TargetID, DisableMachineSink);
+    return applyDisable(TargetID, Opts.disable_machine_sink);
 
   if (StandardID == &PostRAMachineSinkingID)
-    return applyDisable(TargetID, DisablePostRAMachineSink);
+    return applyDisable(TargetID, Opts.disable_postra_machine_sink);
 
   if (StandardID == &MachineCopyPropagationID)
-    return applyDisable(TargetID, DisableCopyProp);
+    return applyDisable(TargetID, Opts.disable_copyprop);
 
   return TargetID;
 }
@@ -366,8 +172,9 @@ static IdentifyingPassPtr overridePass(AnalysisID StandardID,
 // Find the FSProfile file name. The internal option takes the precedence
 // before getting from TargetMachine.
 static std::string getFSProfileFile(const TargetMachine *TM) {
-  if (!FSProfileFile.empty())
-    return FSProfileFile.getValue();
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
+  if (!Opts.fs_profile_file.empty())
+    return Opts.fs_profile_file.str();
   const std::optional<PGOOptions> &PGOOpt = TM->getPGOOption();
   if (PGOOpt == std::nullopt || PGOOpt->Action != PGOOptions::SampleUse)
     return std::string();
@@ -377,8 +184,9 @@ static std::string getFSProfileFile(const TargetMachine *TM) {
 // Find the Profile remapping file name. The internal option takes the
 // precedence before getting from TargetMachine.
 static std::string getFSRemappingFile(const TargetMachine *TM) {
-  if (!FSRemappingFile.empty())
-    return FSRemappingFile.getValue();
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
+  if (!Opts.fs_remapping_file.empty())
+    return Opts.fs_remapping_file.str();
   const std::optional<PGOOptions> &PGOOpt = TM->getPGOOption();
   if (PGOOpt == std::nullopt || PGOOpt->Action != PGOOptions::SampleUse)
     return std::string();
@@ -469,21 +277,22 @@ getPassNameAndInstanceNum(StringRef PassName) {
 }
 
 void TargetPassConfig::setStartStopPasses() {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   StringRef StartBeforeName;
   std::tie(StartBeforeName, StartBeforeInstanceNum) =
-    getPassNameAndInstanceNum(StartBeforeOpt);
+      getPassNameAndInstanceNum(Opts.start_before);
 
   StringRef StartAfterName;
   std::tie(StartAfterName, StartAfterInstanceNum) =
-    getPassNameAndInstanceNum(StartAfterOpt);
+      getPassNameAndInstanceNum(Opts.start_after);
 
   StringRef StopBeforeName;
-  std::tie(StopBeforeName, StopBeforeInstanceNum)
-    = getPassNameAndInstanceNum(StopBeforeOpt);
+  std::tie(StopBeforeName, StopBeforeInstanceNum) =
+      getPassNameAndInstanceNum(Opts.stop_before);
 
   StringRef StopAfterName;
-  std::tie(StopAfterName, StopAfterInstanceNum)
-    = getPassNameAndInstanceNum(StopAfterOpt);
+  std::tie(StopAfterName, StopAfterInstanceNum) =
+      getPassNameAndInstanceNum(Opts.stop_after);
 
   StartBefore = getPassIDFromName(StartBeforeName);
   StartAfter = getPassIDFromName(StartAfterName);
@@ -498,44 +307,46 @@ void TargetPassConfig::setStartStopPasses() {
   Started = (StartAfter == nullptr) && (StartBefore == nullptr);
 }
 
+static cl::boolOrDefault toBoolOrDefault(BoolOrDefault B) {
+  if (B == BoolOrDefault::Default)
+    return cl::boolOrDefault::BOU_UNSET;
+  return B == BoolOrDefault::True ? cl::boolOrDefault::BOU_TRUE
+                                  : cl::boolOrDefault::BOU_FALSE;
+}
+
 CGPassBuilderOption llvm::getCGPassBuilderOption() {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   CGPassBuilderOption Opt;
-
-#define SET_OPTION_IF_PRESENT(Option)                                          \
-  if (Option.getNumOccurrences())                                              \
-    Opt.Option = Option;
-
-  SET_OPTION_IF_PRESENT(EnableGlobalISelAbort)
-  SET_OPTION_IF_PRESENT(EnableIPRA)
-
-#define SET_OPTION(Option) Opt.Option = Option;
-
-  SET_OPTION(EnableFastISelOption)
-  SET_OPTION(EnableGlobalISelOption)
-  SET_OPTION(VerifyMachineCode)
-  SET_OPTION(DisableAtExitBasedGlobalDtorLowering)
-  SET_OPTION(DisableExpandReductions)
-  SET_OPTION(PrintAfterISel)
-  SET_OPTION(FSProfileFile)
-  SET_OPTION(EnableGCEmptyBlocks)
-  SET_OPTION(EnableBlockPlacementStats)
-  SET_OPTION(EnableGlobalMergeFunc)
-  SET_OPTION(EnableImplicitNullChecks)
-  SET_OPTION(EnableMachineOutliner)
-  SET_OPTION(MISchedPostRA)
-  SET_OPTION(DisableLSR)
-  SET_OPTION(DisableConstantHoisting)
-  SET_OPTION(DisableCGP)
-  SET_OPTION(DisablePartialLibcallInlining)
-  SET_OPTION(DisableSelectOptimize)
-  SET_OPTION(PrintISelInput)
-  SET_OPTION(PrintRegUsage)
-  SET_OPTION(DebugifyAndStripAll)
-  SET_OPTION(DebugifyCheckAndStripAll)
-  SET_OPTION(DisableRAFSProfileLoader)
-  SET_OPTION(DisableCFIFixup)
-  SET_OPTION(EnableMachineFunctionSplitter)
-
+  Opt.EnableGlobalISelAbort = Opts.global_isel_abort;
+  if (Opts.enable_ipra != BoolOrDefault::Default)
+    Opt.EnableIPRA = Opts.enable_ipra == BoolOrDefault::True;
+  Opt.EnableFastISelOption = toBoolOrDefault(Opts.fast_isel);
+  Opt.EnableGlobalISelOption = toBoolOrDefault(Opts.global_isel);
+  Opt.VerifyMachineCode = toBoolOrDefault(Opts.verify_machineinstrs);
+  Opt.DisableAtExitBasedGlobalDtorLowering =
+      Opts.disable_atexit_based_global_dtor_lowering;
+  Opt.DisableExpandReductions = Opts.disable_expand_reductions;
+  Opt.PrintAfterISel = Opts.print_after_isel;
+  Opt.FSProfileFile = Opts.fs_profile_file.str();
+  Opt.EnableGCEmptyBlocks = Opts.enable_gc_empty_basic_blocks;
+  Opt.EnableBlockPlacementStats = Opts.enable_block_placement_stats;
+  Opt.EnableGlobalMergeFunc = Opts.enable_global_merge_func;
+  Opt.EnableImplicitNullChecks = Opts.enable_implicit_null_checks;
+  Opt.EnableMachineOutliner = EnableMachineOutliner;
+  Opt.MISchedPostRA = Opts.misched_postra;
+  Opt.DisableLSR = Opts.disable_lsr;
+  Opt.DisableConstantHoisting = Opts.disable_constant_hoisting;
+  Opt.DisableCGP = Opts.disable_cgp;
+  Opt.DisablePartialLibcallInlining = Opts.disable_partial_libcall_inlining;
+  Opt.DisableSelectOptimize = Opts.disable_select_optimize;
+  Opt.PrintISelInput = Opts.print_isel_input;
+  Opt.PrintRegUsage = Opts.print_regusage;
+  Opt.DebugifyAndStripAll = toBoolOrDefault(Opts.debugify_and_strip_all_safe);
+  Opt.DebugifyCheckAndStripAll =
+      toBoolOrDefault(Opts.debugify_check_and_strip_all_safe);
+  Opt.DisableRAFSProfileLoader = Opts.disable_ra_fsprofile_loader;
+  Opt.DisableCFIFixup = Opts.disable_cfi_fixup;
+  Opt.EnableMachineFunctionSplitter = Opts.enable_split_machine_functions;
   return Opt;
 }
 
@@ -544,24 +355,25 @@ void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
 
   // Register a callback for disabling passes.
   PIC.registerShouldRunOptionalPassCallback([](StringRef P, IRUnitRef) {
+    const CodeGenOptions &Opts = CodeGenOptions::Global;
 
 #define DISABLE_PASS(Option, Name)                                             \
   if (Option && P.contains(#Name))                                             \
     return false;
-    DISABLE_PASS(DisableBlockPlacement, MachineBlockPlacementPass)
-    DISABLE_PASS(DisableBranchFold, BranchFolderPass)
-    DISABLE_PASS(DisableCopyProp, MachineCopyPropagationPass)
-    DISABLE_PASS(DisableEarlyIfConversion, EarlyIfConverterLegacyPass)
-    DISABLE_PASS(DisableEarlyTailDup, EarlyTailDuplicatePass)
-    DISABLE_PASS(DisableMachineCSE, MachineCSELegacyPass)
-    DISABLE_PASS(DisableMachineDCE, DeadMachineInstructionElimPass)
-    DISABLE_PASS(DisableMachineLICM, EarlyMachineLICMPass)
-    DISABLE_PASS(DisableMachineSink, MachineSinkingPass)
-    DISABLE_PASS(DisablePostRAMachineLICM, MachineLICMPass)
-    DISABLE_PASS(DisablePostRAMachineSink, PostRAMachineSinkingPass)
-    DISABLE_PASS(DisablePostRASched, PostRASchedulerPass)
-    DISABLE_PASS(DisableSSC, StackSlotColoringPass)
-    DISABLE_PASS(DisableTailDuplicate, TailDuplicatePass)
+    DISABLE_PASS(Opts.disable_block_placement, MachineBlockPlacementPass)
+    DISABLE_PASS(Opts.disable_branch_fold, BranchFolderPass)
+    DISABLE_PASS(Opts.disable_copyprop, MachineCopyPropagationPass)
+    DISABLE_PASS(Opts.disable_early_ifcvt, EarlyIfConverterLegacyPass)
+    DISABLE_PASS(Opts.disable_early_taildup, EarlyTailDuplicatePass)
+    DISABLE_PASS(Opts.disable_machine_cse, MachineCSELegacyPass)
+    DISABLE_PASS(Opts.disable_machine_dce, DeadMachineInstructionElimPass)
+    DISABLE_PASS(Opts.disable_machine_licm, EarlyMachineLICMPass)
+    DISABLE_PASS(Opts.disable_machine_sink, MachineSinkingPass)
+    DISABLE_PASS(Opts.disable_postra_machine_licm, MachineLICMPass)
+    DISABLE_PASS(Opts.disable_postra_machine_sink, PostRAMachineSinkingPass)
+    DISABLE_PASS(Opts.disable_post_ra, PostRASchedulerPass)
+    DISABLE_PASS(Opts.disable_ssc, StackSlotColoringPass)
+    DISABLE_PASS(Opts.disable_tail_duplicate, TailDuplicatePass)
 
     return true;
   });
@@ -569,14 +381,15 @@ void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
 
 Expected<TargetPassConfig::StartStopInfo>
 TargetPassConfig::getStartStopInfo(PassInstrumentationCallbacks &PIC) {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   auto [StartBefore, StartBeforeInstanceNum] =
-      getPassNameAndInstanceNum(StartBeforeOpt);
+      getPassNameAndInstanceNum(Opts.start_before);
   auto [StartAfter, StartAfterInstanceNum] =
-      getPassNameAndInstanceNum(StartAfterOpt);
+      getPassNameAndInstanceNum(Opts.start_after);
   auto [StopBefore, StopBeforeInstanceNum] =
-      getPassNameAndInstanceNum(StopBeforeOpt);
+      getPassNameAndInstanceNum(Opts.stop_before);
   auto [StopAfter, StopAfterInstanceNum] =
-      getPassNameAndInstanceNum(StopAfterOpt);
+      getPassNameAndInstanceNum(Opts.stop_after);
 
   if (!StartBefore.empty() && !StartAfter.empty())
     return make_error<StringError>(
@@ -605,6 +418,7 @@ TargetPassConfig::getStartStopInfo(PassInstrumentationCallbacks &PIC) {
 // registers all common codegen passes.
 TargetPassConfig::TargetPassConfig(TargetMachine &TM, PassManagerBase &PM)
     : ImmutablePass(ID), PM(&PM), TM(&TM) {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   Impl = new PassConfigImpl();
 
   PassRegistry &PR = *PassRegistry::getPassRegistry();
@@ -618,8 +432,8 @@ TargetPassConfig::TargetPassConfig(TargetMachine &TM, PassManagerBase &PM)
   initializeBasicAAWrapperPassPass(PR);
   initializeAAResultsWrapperPassPass(PR);
 
-  if (EnableIPRA.getNumOccurrences()) {
-    TM.Options.EnableIPRA = EnableIPRA;
+  if (Opts.enable_ipra != BoolOrDefault::Default) {
+    TM.Options.EnableIPRA = Opts.enable_ipra == BoolOrDefault::True;
   } else {
     // If not explicitly specified, use target default.
     TM.Options.EnableIPRA |= TM.useIPRA();
@@ -628,8 +442,8 @@ TargetPassConfig::TargetPassConfig(TargetMachine &TM, PassManagerBase &PM)
   if (TM.Options.EnableIPRA)
     setRequiresCodeGenSCCOrder();
 
-  if (EnableGlobalISelAbort.getNumOccurrences())
-    TM.Options.GlobalISelAbort = EnableGlobalISelAbort;
+  if (Opts.global_isel_abort)
+    TM.Options.GlobalISelAbort = *Opts.global_isel_abort;
 
   setStartStopPasses();
 }
@@ -666,25 +480,28 @@ TargetPassConfig::TargetPassConfig()
 }
 
 bool TargetPassConfig::willCompleteCodeGenPipeline() {
-  return StopBeforeOpt.empty() && StopAfterOpt.empty();
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
+  return Opts.stop_before.empty() && Opts.stop_after.empty();
 }
 
 bool TargetPassConfig::hasLimitedCodeGenPipeline() {
-  return !StartBeforeOpt.empty() || !StartAfterOpt.empty() ||
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
+  return !Opts.start_before.empty() || !Opts.start_after.empty() ||
          !willCompleteCodeGenPipeline();
 }
 
 std::string TargetPassConfig::getLimitedCodeGenPipelineReason() {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   if (!hasLimitedCodeGenPipeline())
     return std::string();
   std::string Res;
-  static cl::opt<std::string> *PassNames[] = {&StartAfterOpt, &StartBeforeOpt,
-                                              &StopAfterOpt, &StopBeforeOpt};
+  StringRef PassNames[] = {Opts.start_after, Opts.start_before, Opts.stop_after,
+                           Opts.stop_before};
   static const char *OptNames[] = {StartAfterOptName, StartBeforeOptName,
                                    StopAfterOptName, StopBeforeOptName};
   bool IsFirst = true;
   for (int Idx = 0; Idx < 4; ++Idx)
-    if (!PassNames[Idx]->empty()) {
+    if (!PassNames[Idx].empty()) {
       if (!IsFirst)
         Res += " and ";
       IsFirst = false;
@@ -797,14 +614,15 @@ void TargetPassConfig::printAndVerify(const std::string &Banner) {
 }
 
 void TargetPassConfig::addPrintPass(const std::string &Banner) {
-  if (PrintAfterISel)
+  if (CodeGenOptions::Global.print_after_isel)
     PM->add(createMachineFunctionPrinterPass(dbgs(), Banner));
 }
 
 void TargetPassConfig::addVerifyPass(const std::string &Banner) {
-  bool Verify = VerifyMachineCode == cl::boolOrDefault::BOU_TRUE;
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
+  bool Verify = valueOr(Opts.verify_machineinstrs, false);
 #ifdef EXPENSIVE_CHECKS
-  if (VerifyMachineCode == cl::boolOrDefault::BOU_UNSET)
+  if (Opts.verify_machineinstrs == BoolOrDefault::Default)
     Verify = TM->isMachineVerifierClean();
 #endif
   if (Verify)
@@ -824,18 +642,20 @@ void TargetPassConfig::addCheckDebugPass() {
 }
 
 void TargetPassConfig::addMachinePrePasses(bool AllowDebugify) {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   if (AllowDebugify && DebugifyIsSafe &&
-      (DebugifyAndStripAll == cl::boolOrDefault::BOU_TRUE ||
-       DebugifyCheckAndStripAll == cl::boolOrDefault::BOU_TRUE))
+      (valueOr(Opts.debugify_and_strip_all_safe, false) ||
+       valueOr(Opts.debugify_check_and_strip_all_safe, false)))
     addDebugifyPass();
 }
 
 void TargetPassConfig::addMachinePostPasses(const std::string &Banner) {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   if (DebugifyIsSafe) {
-    if (DebugifyCheckAndStripAll == cl::boolOrDefault::BOU_TRUE) {
+    if (valueOr(Opts.debugify_check_and_strip_all_safe, false)) {
       addCheckDebugPass();
       addStripDebugPass();
-    } else if (DebugifyAndStripAll == cl::boolOrDefault::BOU_TRUE)
+    } else if (valueOr(Opts.debugify_and_strip_all_safe, false))
       addStripDebugPass();
   }
   addVerifyPass(Banner);
@@ -844,6 +664,7 @@ void TargetPassConfig::addMachinePostPasses(const std::string &Banner) {
 /// Add common target configurable passes that perform LLVM IR to IR transforms
 /// following machine independent optimization.
 void TargetPassConfig::addIRPasses() {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   // Before running any passes, run the verifier to determine if the input
   // coming from the front-end and/or optimizer is valid.
   if (!DisableVerify)
@@ -859,7 +680,7 @@ void TargetPassConfig::addIRPasses() {
     addPass(createBasicAAWrapperPass());
 
     // Run loop strength reduction before anything else.
-    if (!DisableLSR) {
+    if (!Opts.disable_lsr) {
       addPass(createCanonicalizeFreezeInLoopsPass());
       addPass(createLoopStrengthReducePass());
       if (EnableLoopTermFold)
@@ -875,20 +696,22 @@ void TargetPassConfig::addIRPasses() {
   // For MachO, lower @llvm.global_dtors into @llvm.global_ctors with
   // __cxa_atexit() calls to avoid emitting the deprecated __mod_term_func.
   if (TM->getTargetTriple().isOSBinFormatMachO() &&
-      !DisableAtExitBasedGlobalDtorLowering)
+      !Opts.disable_atexit_based_global_dtor_lowering)
     addPass(createLowerGlobalDtorsLegacyPass());
 
   // Make sure that no unreachable blocks are instruction selected.
   addPass(createUnreachableBlockEliminationPass());
 
   // Prepare expensive constants for SelectionDAG.
-  if (getOptLevel() != CodeGenOptLevel::None && !DisableConstantHoisting)
+  if (getOptLevel() != CodeGenOptLevel::None && !Opts.disable_constant_hoisting)
     addPass(createConstantHoistingPass());
 
-  if (getOptLevel() != CodeGenOptLevel::None && !DisableReplaceWithVecLib)
+  if (getOptLevel() != CodeGenOptLevel::None &&
+      !Opts.disable_replace_with_vec_lib)
     addPass(createReplaceWithVeclibLegacyPass());
 
-  if (getOptLevel() != CodeGenOptLevel::None && !DisablePartialLibcallInlining)
+  if (getOptLevel() != CodeGenOptLevel::None &&
+      !Opts.disable_partial_libcall_inlining)
     addPass(createPartiallyInlineLibCallsPass());
 
   // Instrument function entry after all inlining.
@@ -901,14 +724,14 @@ void TargetPassConfig::addIRPasses() {
 
   // Expand reduction intrinsics into shuffle sequences if the target wants to.
   // Allow disabling it for testing purposes.
-  if (!DisableExpandReductions)
+  if (!Opts.disable_expand_reductions)
     addPass(createExpandReductionsPass());
 
   // Convert conditional moves to conditional jumps when profitable.
-  if (getOptLevel() != CodeGenOptLevel::None && !DisableSelectOptimize)
+  if (getOptLevel() != CodeGenOptLevel::None && !Opts.disable_select_optimize)
     addPass(createSelectOptimizePass());
 
-  if (EnableGlobalMergeFunc)
+  if (Opts.enable_global_merge_func)
     addPass(createGlobalMergeFuncPass());
 
   if (TM->getTargetTriple().isOSWindows())
@@ -966,7 +789,8 @@ void TargetPassConfig::addPassesToHandleExceptions() {
 /// Add pass to prepare the LLVM IR for code generation. This should be done
 /// before exception handling preparation passes.
 void TargetPassConfig::addCodeGenPrepare() {
-  if (getOptLevel() != CodeGenOptLevel::None && !DisableCGP)
+  if (getOptLevel() != CodeGenOptLevel::None &&
+      !CodeGenOptions::Global.disable_cgp)
     addPass(createCodeGenPrepareLegacyPass());
 }
 
@@ -986,7 +810,7 @@ void TargetPassConfig::addISelPrepare() {
   addPass(createSafeStackPass());
   addPass(createStackProtectorPass());
 
-  if (PrintISelInput)
+  if (CodeGenOptions::Global.print_isel_input)
     addPass(createPrintFunctionPass(
         dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"));
 
@@ -997,18 +821,18 @@ void TargetPassConfig::addISelPrepare() {
 }
 
 bool TargetPassConfig::addCoreISelPasses() {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   // Enable FastISel with -fast-isel, but allow that to be overridden.
-  TM->setO0WantsFastISel(EnableFastISelOption != cl::boolOrDefault::BOU_FALSE);
+  TM->setO0WantsFastISel(valueOr(Opts.fast_isel, true));
 
   // Determine an instruction selector.
   enum class SelectorType { SelectionDAG, FastISel, GlobalISel };
   SelectorType Selector;
 
-  if (EnableFastISelOption == cl::boolOrDefault::BOU_TRUE)
+  if (valueOr(Opts.fast_isel, false))
     Selector = SelectorType::FastISel;
-  else if (EnableGlobalISelOption == cl::boolOrDefault::BOU_TRUE ||
-           (TM->Options.EnableGlobalISel &&
-            EnableGlobalISelOption != cl::boolOrDefault::BOU_FALSE))
+  else if (valueOr(Opts.global_isel, false) ||
+           (TM->Options.EnableGlobalISel && valueOr(Opts.global_isel, true)))
     Selector = SelectorType::GlobalISel;
   else if (TM->getOptLevel() == CodeGenOptLevel::None &&
            TM->getO0WantsFastISel())
@@ -1097,7 +921,7 @@ bool TargetPassConfig::addISelPasses() {
   addPass(createExpandIRInstsPass(getOptLevel()));
   addIRPasses();
 
-  if (TriggerCrash)
+  if (CodeGenOptions::Global.codegen_pipeline_trigger_crash)
     addPass(new TriggerCrashFunctionLegacyPass());
 
   addCodeGenPrepare();
@@ -1133,6 +957,7 @@ static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
 /// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
 /// before/after any target-independent pass. But it's currently overkill.
 void TargetPassConfig::addMachinePasses() {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   AddingMachinePasses = true;
 
   // Add passes that optimize machine instructions in SSA form.
@@ -1161,7 +986,7 @@ void TargetPassConfig::addMachinePasses() {
     addPass(createMIRAddFSDiscriminatorsPass(
         sampleprof::FSDiscriminatorPass::Pass1));
     const std::string ProfileFile = getFSProfileFile(TM);
-    if (!ProfileFile.empty() && !DisableRAFSProfileLoader)
+    if (!ProfileFile.empty() && !Opts.disable_ra_fsprofile_loader)
       addPass(createMIRProfileLoaderPass(ProfileFile, getFSRemappingFile(TM),
                                          sampleprof::FSDiscriminatorPass::Pass1,
                                          nullptr));
@@ -1202,7 +1027,7 @@ void TargetPassConfig::addMachinePasses() {
   // Run pre-sched2 passes.
   addPreSched2();
 
-  if (EnableImplicitNullChecks)
+  if (Opts.enable_implicit_null_checks)
     addPass(&ImplicitNullChecksID);
 
   // Second pass scheduler.
@@ -1210,7 +1035,7 @@ void TargetPassConfig::addMachinePasses() {
   // point.
   if (getOptLevel() != CodeGenOptLevel::None &&
       !TM->targetSchedulesPostRAScheduling()) {
-    if (MISchedPostRA)
+    if (Opts.misched_postra)
       addPass(&PostMachineSchedulerID);
     else
       addPass(&PostRASchedulerID);
@@ -1253,7 +1078,7 @@ void TargetPassConfig::addMachinePasses() {
       addPass(createMachineOutlinerPass(EnableMachineOutliner));
   }
 
-  if (EnableGCEmptyBlocks)
+  if (Opts.enable_gc_empty_basic_blocks)
     addPass(llvm::createGCEmptyBasicBlocksLegacyPass());
 
   if (EnableFSDiscriminator)
@@ -1261,7 +1086,7 @@ void TargetPassConfig::addMachinePasses() {
         sampleprof::FSDiscriminatorPass::PassLast));
 
   if (TM->Options.EnableMachineFunctionSplitter ||
-      EnableMachineFunctionSplitter || SplitStaticData ||
+      Opts.enable_split_machine_functions || Opts.split_static_data ||
       TM->Options.EnableStaticDataPartitioning) {
     const std::string ProfileFile = getFSProfileFile(TM);
     if (!ProfileFile.empty()) {
@@ -1285,10 +1110,10 @@ void TargetPassConfig::addMachinePasses() {
   // basic-block-sections optimizations (`=all`, or `=list=` with function
   // included in the list profile) will get that optimization instead.
   if (TM->Options.EnableMachineFunctionSplitter ||
-      EnableMachineFunctionSplitter)
+      Opts.enable_split_machine_functions)
     addPass(createMachineFunctionSplitterPass());
 
-  if (SplitStaticData || TM->Options.EnableStaticDataPartitioning) {
+  if (Opts.split_static_data || TM->Options.EnableStaticDataPartitioning) {
     // The static data splitter pass is a machine function pass. and
     // static data annotator pass is a module-wide pass. See the file comment
     // in StaticDataAnnotator.cpp for the motivation.
@@ -1299,12 +1124,12 @@ void TargetPassConfig::addMachinePasses() {
   // address map (or both).
   if (TM->getBBSectionsType() != llvm::BasicBlockSection::None ||
       TM->Options.BBAddrMap) {
-    if (shouldEmitBBHash() || BasicBlockSectionMatchInfer)
+    if (shouldEmitBBHash() || Opts.basic_block_section_match_infer)
       addPass(llvm::createMachineBlockHashInfoPass());
     if (TM->getBBSectionsType() == llvm::BasicBlockSection::List) {
       addPass(llvm::createBasicBlockSectionsProfileReaderWrapperPass(
           TM->getBBSectionsFuncListBuf()));
-      if (BasicBlockSectionMatchInfer)
+      if (Opts.basic_block_section_match_infer)
         addPass(llvm::createBasicBlockMatchingAndInferencePass());
       else {
         addPass(llvm::createBasicBlockPathCloningPass());
@@ -1316,7 +1141,7 @@ void TargetPassConfig::addMachinePasses() {
 
   addPostBBSections();
 
-  if (!DisableCFIFixup && TM->Options.EnableCFIFixup)
+  if (!Opts.disable_cfi_fixup && TM->Options.EnableCFIFixup)
     addPass(createCFIFixupLegacy());
 
   PM->add(createStackFrameLayoutAnalysisPass());
@@ -1575,18 +1400,19 @@ bool TargetPassConfig::addGCPasses() {
 
 /// Add standard basic block placement passes.
 void TargetPassConfig::addBlockPlacement() {
+  const CodeGenOptions &Opts = CodeGenOptions::Global;
   if (EnableFSDiscriminator) {
     addPass(createMIRAddFSDiscriminatorsPass(
         sampleprof::FSDiscriminatorPass::Pass2));
     const std::string ProfileFile = getFSProfileFile(TM);
-    if (!ProfileFile.empty() && !DisableLayoutFSProfileLoader)
+    if (!ProfileFile.empty() && !Opts.disable_layout_fsprofile_loader)
       addPass(createMIRProfileLoaderPass(ProfileFile, getFSRemappingFile(TM),
                                          sampleprof::FSDiscriminatorPass::Pass2,
                                          nullptr));
   }
   if (addPass(&MachineBlockPlacementID)) {
     // Run a separate pass to collect block placement statistics.
-    if (EnableBlockPlacementStats)
+    if (Opts.enable_block_placement_stats)
       addPass(&MachineBlockPlacementStatsID);
   }
 }
diff --git a/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn
index cc1463cbe9e3ae..dfcb12d75a4657 100644
--- a/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn
@@ -1,3 +1,10 @@
+import("//llvm/utils/TableGen/tablegen.gni")
+
+tablegen("CodeGenOptions") {
+  visibility = [ ":CodeGen" ]
+  args = [ "-gen-opt-parser-defs" ]
+}
+
 static_library("CodeGen") {
   output_name = "LLVMCodeGen"
   public_deps = [
@@ -5,6 +12,7 @@ static_library("CodeGen") {
     "//llvm/include/llvm/Config:llvm-config",
   ]
   deps = [
+    ":CodeGenOptions",
     "//llvm/include/llvm/CodeGen:GenVT",
     "//llvm/lib/Analysis",
     "//llvm/lib/Bitcode/Reader",
@@ -13,6 +21,7 @@ static_library("CodeGen") {
     "//llvm/lib/CodeGenTypes",
     "//llvm/lib/IR",
     "//llvm/lib/MC",
+    "//llvm/lib/Option",
     "//llvm/lib/ProfileData",
     "//llvm/lib/Support",
     "//llvm/lib/Target",
@@ -42,6 +51,7 @@ static_library("CodeGen") {
     "CallingConvLower.cpp",
     "CodeGen.cpp",
     "CodeGenCommonISel.cpp",
+    "CodeGenOptions.cpp",
     "CodeGenPrepare.cpp",
     "CodeGenTargetMachineImpl.cpp",
     "CommandFlags.cpp",
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index df9cbbf9a29ae1..826ac64b62006a 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -2454,6 +2454,15 @@ cc_library(
     ],
 )
 
+gentbl_cc_library(
+    name = "CodeGenOptionsTableGen",
+    strip_include_prefix = "lib/CodeGen",
+    tbl_outs = {"lib/CodeGen/CodeGenOptions.inc": ["-gen-opt-parser-defs"]},
+    tblgen = ":llvm-min-tblgen",
+    td_file = "lib/CodeGen/CodeGenOptions.td",
+    deps = [":OptParserTdFiles"],
+)
+
 cc_library(
     name = "CodeGen",
     srcs = glob(
@@ -2485,6 +2494,7 @@ cc_library(
         ":BitWriter",
         ":CFGuard",
         ":CGData",
+        ":CodeGenOptionsTableGen",
         ":CodeGenTypes",
         ":Core",
         ":DebugInfoCodeView",
@@ -2497,6 +2507,7 @@ cc_library(
         ":MCParser",
         ":ObjCARC",
         ":Object",
+        ":Option",
         ":ProfileData",
         ":Remarks",
         ":Scalar",



More information about the llvm-branch-commits mailing list