serge-sans-paille created this revision.
serge-sans-paille added reviewers: MaskRay, tstellar.
Herald added subscribers: llvm-commits, cfe-commits, dexonsmith, steven_wu, 
gbedwell, aheejin, hiraditya, mgorny, dschuff.
Herald added a reviewer: JDevlieghere.
Herald added a reviewer: andreadb.
Herald added projects: clang, LLVM.

MCTargetOptionsCommandFlags.inc and CommandFlags.inc are headers which contain 
cl::opt with static storage.
These headers are meant to be incuded by tools to make it easier to parametrize 
codegen/mc.

However, these headers are also included in at least two libraries: lldCommon 
and handle-llvm. As a result, when creating DYLIB, clang-cpp holds a reference 
to the options, and lldCommon holds another reference. Linking the two in a 
single executable, as zig does[0], results in a double registration.

This patch explores an other approach: instead of bundling headers, bindle them 
as non-component libs, that way we get shared libraries that are only loaded 
once.

It's a WIP, not fully tested, to gather feedback.

[0] https://bugzilla.redhat.com/show_bug.cgi?id=1756977#c5


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75579

Files:
  clang/tools/clang-fuzzer/handle-llvm/CMakeLists.txt
  clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
  lld/Common/CMakeLists.txt
  lld/Common/TargetOptionsCommandFlags.cpp
  llvm/include/llvm/CodeGen/CommandFlags.h
  llvm/include/llvm/CodeGen/CommandFlags.inc
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.inc
  llvm/lib/CodeGen/CMakeLists.txt
  llvm/lib/CodeGen/CommandFlags/CMakeLists.txt
  llvm/lib/CodeGen/CommandFlags/CommandFlags.cpp
  llvm/lib/MC/CMakeLists.txt
  llvm/lib/MC/CommandFlags/CMakeLists.txt
  llvm/lib/MC/CommandFlags/MCTargetOptionsCommandFlags.cpp
  llvm/tools/dsymutil/CMakeLists.txt
  llvm/tools/dsymutil/DwarfStreamer.cpp
  llvm/tools/llc/CMakeLists.txt
  llvm/tools/llc/llc.cpp
  llvm/tools/lli/CMakeLists.txt
  llvm/tools/lli/lli.cpp
  llvm/tools/llvm-dwp/CMakeLists.txt
  llvm/tools/llvm-dwp/llvm-dwp.cpp
  llvm/tools/llvm-isel-fuzzer/CMakeLists.txt
  llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp
  llvm/tools/llvm-lto/CMakeLists.txt
  llvm/tools/llvm-lto/llvm-lto.cpp
  llvm/tools/llvm-lto2/CMakeLists.txt
  llvm/tools/llvm-lto2/llvm-lto2.cpp
  llvm/tools/llvm-mc/CMakeLists.txt
  llvm/tools/llvm-mc/llvm-mc.cpp
  llvm/tools/llvm-mca/CMakeLists.txt
  llvm/tools/llvm-mca/llvm-mca.cpp
  llvm/tools/llvm-ml/CMakeLists.txt
  llvm/tools/llvm-ml/llvm-ml.cpp
  llvm/tools/llvm-opt-fuzzer/CMakeLists.txt
  llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp
  llvm/tools/lto/CMakeLists.txt
  llvm/tools/lto/lto.cpp
  llvm/tools/opt/CMakeLists.txt
  llvm/tools/opt/opt.cpp
  llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
  llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp

Index: llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
===================================================================
--- llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
+++ llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
@@ -25,7 +25,7 @@
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
 #include "llvm/PassAnalysisSupport.h"
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/TargetRegistry.h"
@@ -433,7 +433,7 @@
                                        TripleName,
                                    inconvertibleErrorCode());
 
-  MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
+  MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
   MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
   if (!MAI)
     return make_error<StringError>("no asm info for target " + TripleName,
Index: llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
===================================================================
--- llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
+++ llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
@@ -22,3 +22,4 @@
   )
 
 target_link_libraries(DebugInfoDWARFTests PRIVATE LLVMTestingSupport)
+target_link_libraries(DebugInfoDWARFTests PUBLIC LLVMMCCommandFlags)
Index: llvm/tools/opt/opt.cpp
===================================================================
--- llvm/tools/opt/opt.cpp
+++ llvm/tools/opt/opt.cpp
@@ -22,7 +22,7 @@
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Bitcode/BitcodeWriterPass.h"
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/IR/DataLayout.h"
@@ -471,16 +471,17 @@
                                        StringRef FeaturesStr,
                                        const TargetOptions &Options) {
   std::string Error;
-  const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
-                                                         Error);
+  const Target *TheTarget =
+      TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
   // Some modules don't specify a triple, and this is okay.
   if (!TheTarget) {
     return nullptr;
   }
 
-  return TheTarget->createTargetMachine(TheTriple.getTriple(), CPUStr,
-                                        FeaturesStr, Options, getRelocModel(),
-                                        getCodeModel(), GetCodeGenOptLevel());
+  return TheTarget->createTargetMachine(
+      TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(),
+      Options, codegen::getRelocModel(), codegen::getCodeModel(),
+      GetCodeGenOptLevel());
 }
 
 #ifdef BUILD_EXAMPLES
@@ -667,11 +668,11 @@
   Triple ModuleTriple(M->getTargetTriple());
   std::string CPUStr, FeaturesStr;
   TargetMachine *Machine = nullptr;
-  const TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  const TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags();
 
   if (ModuleTriple.getArch()) {
-    CPUStr = getCPUStr();
-    FeaturesStr = getFeaturesStr();
+    CPUStr = codegen::getCPUStr();
+    FeaturesStr = codegen::getFeaturesStr();
     Machine = GetTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options);
   } else if (ModuleTriple.getArchName() != "unknown" &&
              ModuleTriple.getArchName() != "") {
@@ -684,7 +685,7 @@
 
   // Override function attributes based on CPUStr, FeaturesStr, and command line
   // flags.
-  setFunctionAttributes(CPUStr, FeaturesStr, *M);
+  codegen::setFunctionAttributes(CPUStr, FeaturesStr, *M);
 
   // If the output is set to be emitted to standard out, and standard out is a
   // console, print out a warning message and refuse to do it.  We don't
Index: llvm/tools/opt/CMakeLists.txt
===================================================================
--- llvm/tools/opt/CMakeLists.txt
+++ llvm/tools/opt/CMakeLists.txt
@@ -40,6 +40,7 @@
   SUPPORT_PLUGINS
   )
 export_executable_symbols(opt)
+target_link_libraries(opt PUBLIC LLVMCodeGenCommandFlags)
 
 if(LLVM_BUILD_EXAMPLES)
     target_link_libraries(opt PRIVATE ExampleIRTransforms)
Index: llvm/tools/lto/lto.cpp
===================================================================
--- llvm/tools/lto/lto.cpp
+++ llvm/tools/lto/lto.cpp
@@ -15,7 +15,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LLVMContext.h"
@@ -28,6 +28,8 @@
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
 
+using namespace llvm;
+
 // extra command-line flags needed for LTOCodeGenerator
 static cl::opt<char>
 OptLevel("O",
@@ -154,12 +156,12 @@
 // Convert the subtarget features into a string to pass to LTOCodeGenerator.
 static void lto_add_attrs(lto_code_gen_t cg) {
   LTOCodeGenerator *CG = unwrap(cg);
-  if (MAttrs.size()) {
+  if (llvm::codegen::getMAttrs().size()) {
     std::string attrs;
-    for (unsigned i = 0; i < MAttrs.size(); ++i) {
+    for (unsigned i = 0; i < llvm::codegen::getMAttrs().size(); ++i) {
       if (i > 0)
         attrs.append(",");
-      attrs.append(MAttrs[i]);
+      attrs.append(llvm::codegen::getMAttrs()[i]);
     }
 
     CG->setAttr(attrs);
@@ -219,7 +221,8 @@
 
 lto_module_t lto_module_create(const char* path) {
   lto_initialize();
-  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  llvm::TargetOptions Options =
+      llvm::codegen::InitTargetOptionsFromCodeGenFlags();
   ErrorOr<std::unique_ptr<LTOModule>> M =
       LTOModule::createFromFile(*LTOContext, StringRef(path), Options);
   if (!M)
@@ -229,7 +232,8 @@
 
 lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) {
   lto_initialize();
-  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  llvm::TargetOptions Options =
+      llvm::codegen::InitTargetOptionsFromCodeGenFlags();
   ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromOpenFile(
       *LTOContext, fd, StringRef(path), size, Options);
   if (!M)
@@ -242,7 +246,8 @@
                                                  size_t map_size,
                                                  off_t offset) {
   lto_initialize();
-  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  llvm::TargetOptions Options =
+      llvm::codegen::InitTargetOptionsFromCodeGenFlags();
   ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromOpenFileSlice(
       *LTOContext, fd, StringRef(path), map_size, offset, Options);
   if (!M)
@@ -252,7 +257,8 @@
 
 lto_module_t lto_module_create_from_memory(const void* mem, size_t length) {
   lto_initialize();
-  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  llvm::TargetOptions Options =
+      llvm::codegen::InitTargetOptionsFromCodeGenFlags();
   ErrorOr<std::unique_ptr<LTOModule>> M =
       LTOModule::createFromBuffer(*LTOContext, mem, length, Options);
   if (!M)
@@ -264,7 +270,8 @@
                                                      size_t length,
                                                      const char *path) {
   lto_initialize();
-  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  llvm::TargetOptions Options =
+      llvm::codegen::InitTargetOptionsFromCodeGenFlags();
   ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromBuffer(
       *LTOContext, mem, length, Options, StringRef(path));
   if (!M)
@@ -275,7 +282,8 @@
 lto_module_t lto_module_create_in_local_context(const void *mem, size_t length,
                                                 const char *path) {
   lto_initialize();
-  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  llvm::TargetOptions Options =
+      llvm::codegen::InitTargetOptionsFromCodeGenFlags();
 
   // Create a local context. Ownership will be transferred to LTOModule.
   std::unique_ptr<LLVMContext> Context = std::make_unique<LLVMContext>();
@@ -294,7 +302,8 @@
                                                   const char *path,
                                                   lto_code_gen_t cg) {
   lto_initialize();
-  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  llvm::TargetOptions Options =
+      llvm::codegen::InitTargetOptionsFromCodeGenFlags();
   ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromBuffer(
       unwrap(cg)->getContext(), mem, length, Options, StringRef(path));
   return wrap(M->release());
@@ -357,7 +366,7 @@
 static lto_code_gen_t createCodeGen(bool InLocalContext) {
   lto_initialize();
 
-  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  TargetOptions Options = llvm::codegen::InitTargetOptionsFromCodeGenFlags();
 
   LibLTOCodeGenerator *CodeGen =
       InLocalContext ? new LibLTOCodeGenerator(std::make_unique<LLVMContext>())
@@ -505,7 +514,7 @@
 thinlto_code_gen_t thinlto_create_codegen(void) {
   lto_initialize();
   ThinLTOCodeGenerator *CodeGen = new ThinLTOCodeGenerator();
-  CodeGen->setTargetOptions(InitTargetOptionsFromCodeGenFlags());
+  CodeGen->setTargetOptions(llvm::codegen::InitTargetOptionsFromCodeGenFlags());
   CodeGen->setFreestanding(EnableFreestanding);
 
   if (OptLevel.getNumOccurrences()) {
Index: llvm/tools/lto/CMakeLists.txt
===================================================================
--- llvm/tools/lto/CMakeLists.txt
+++ llvm/tools/lto/CMakeLists.txt
@@ -20,7 +20,8 @@
 
 set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/lto.exports)
 
-add_llvm_library(LTO SHARED INSTALL_WITH_TOOLCHAIN ${SOURCES} DEPENDS intrinsics_gen)
+add_llvm_library(LTO SHARED INSTALL_WITH_TOOLCHAIN ${SOURCES} DEPENDS
+    intrinsics_gen LINK_LIBS LLVMCodeGenCommandFlags)
 
 install(FILES ${LLVM_MAIN_INCLUDE_DIR}/llvm-c/lto.h
   DESTINATION include/llvm-c
Index: llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp
===================================================================
--- llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp
+++ llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp
@@ -12,7 +12,7 @@
 
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/FuzzMutate/FuzzerCLI.h"
 #include "llvm/FuzzMutate/IRMutator.h"
 #include "llvm/IR/Verifier.h"
@@ -124,7 +124,8 @@
 
   M->setTargetTriple(TM->getTargetTriple().normalize());
   M->setDataLayout(TM->createDataLayout());
-  setFunctionAttributes(TM->getTargetCPU(), TM->getTargetFeatureString(), *M);
+  llvm::codegen::setFunctionAttributes(TM->getTargetCPU(),
+                                       TM->getTargetFeatureString(), *M);
 
   // Create pass pipeline
   //
@@ -213,17 +214,18 @@
   Triple TargetTriple = Triple(Triple::normalize(TargetTripleStr));
 
   std::string Error;
-  const Target *TheTarget =
-      TargetRegistry::lookupTarget(MArch, TargetTriple, Error);
+  const Target *TheTarget = TargetRegistry::lookupTarget(
+      llvm::codegen::getMArch(), TargetTriple, Error);
   if (!TheTarget) {
     errs() << *argv[0] << ": " << Error;
     exit(1);
   }
 
-  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  TargetOptions Options = llvm::codegen::InitTargetOptionsFromCodeGenFlags();
   TM.reset(TheTarget->createTargetMachine(
-      TargetTriple.getTriple(), getCPUStr(), getFeaturesStr(),
-     Options, getRelocModel(), getCodeModel(), CodeGenOpt::Default));
+      TargetTriple.getTriple(), llvm::codegen::getCPUStr(),
+      llvm::codegen::getFeaturesStr(), Options, llvm::codegen::getRelocModel(),
+      llvm::codegen::getCodeModel(), CodeGenOpt::Default));
   assert(TM && "Could not allocate target machine!");
 
   // Check that pass pipeline is specified and correct
Index: llvm/tools/llvm-opt-fuzzer/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-opt-fuzzer/CMakeLists.txt
+++ llvm/tools/llvm-opt-fuzzer/CMakeLists.txt
@@ -29,3 +29,4 @@
   llvm-opt-fuzzer.cpp
   DUMMY_MAIN DummyOptFuzzer.cpp
   )
+target_link_libraries(llvm-opt-fuzzer PUBLIC LLVMCodeGenCommandFlags)
Index: llvm/tools/llvm-ml/llvm-ml.cpp
===================================================================
--- llvm/tools/llvm-ml/llvm-ml.cpp
+++ llvm/tools/llvm-ml/llvm-ml.cpp
@@ -25,7 +25,7 @@
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/FileUtilities.h"
@@ -222,7 +222,7 @@
   cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
 
   cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
-  MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
+  MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
   MCOptions.AssemblyLanguage = "masm";
 
   const char *ProgName = argv[0];
Index: llvm/tools/llvm-ml/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-ml/CMakeLists.txt
+++ llvm/tools/llvm-ml/CMakeLists.txt
@@ -12,3 +12,4 @@
   llvm-ml.cpp
   Disassembler.cpp
   )
+target_link_libraries(llvm-ml PUBLIC LLVMMCCommandFlags)
Index: llvm/tools/llvm-mca/llvm-mca.cpp
===================================================================
--- llvm/tools/llvm-mca/llvm-mca.cpp
+++ llvm/tools/llvm-mca/llvm-mca.cpp
@@ -39,7 +39,7 @@
 #include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
 #include "llvm/MCA/CodeEmitter.h"
 #include "llvm/MCA/Context.h"
 #include "llvm/MCA/InstrBuilder.h"
@@ -353,7 +353,7 @@
   std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
   assert(MRI && "Unable to create target register info!");
 
-  MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
+  MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
   std::unique_ptr<MCAsmInfo> MAI(
       TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
   assert(MAI && "Unable to create target asm info!");
@@ -443,7 +443,7 @@
       TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
 
   std::unique_ptr<MCAsmBackend> MAB(TheTarget->createMCAsmBackend(
-      *STI, *MRI, InitMCTargetOptionsFromFlags()));
+      *STI, *MRI, mc::InitMCTargetOptionsFromFlags()));
 
   for (const std::unique_ptr<mca::CodeRegion> &Region : Regions) {
     // Skip empty code regions.
Index: llvm/tools/llvm-mca/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-mca/CMakeLists.txt
+++ llvm/tools/llvm-mca/CMakeLists.txt
@@ -27,5 +27,6 @@
   Views/TimelineView.cpp
   Views/View.cpp
   )
+target_link_libraries(llvm-mca PUBLIC LLVMMCCommandFlags)
 
 set(LLVM_MCA_SOURCE_DIR ${CURRENT_SOURCE_DIR})
Index: llvm/tools/llvm-mc/llvm-mc.cpp
===================================================================
--- llvm/tools/llvm-mc/llvm-mc.cpp
+++ llvm/tools/llvm-mc/llvm-mc.cpp
@@ -25,7 +25,7 @@
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/FileUtilities.h"
@@ -317,7 +317,7 @@
   cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
 
   cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
-  const MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
+  const MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
   setDwarfDebugFlags(argc, argv);
 
   setDwarfDebugProducer();
Index: llvm/tools/llvm-mc/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-mc/CMakeLists.txt
+++ llvm/tools/llvm-mc/CMakeLists.txt
@@ -12,3 +12,4 @@
   llvm-mc.cpp
   Disassembler.cpp
   )
+target_link_libraries(llvm-mc PUBLIC LLVMMCCommandFlags)
Index: llvm/tools/llvm-lto2/llvm-lto2.cpp
===================================================================
--- llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -16,7 +16,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/LTO/Caching.h"
 #include "llvm/LTO/LTO.h"
@@ -220,12 +220,12 @@
       exit(1);
   };
 
-  Conf.CPU = MCPU;
-  Conf.Options = InitTargetOptionsFromCodeGenFlags();
-  Conf.MAttrs = MAttrs;
-  if (auto RM = getRelocModel())
+  Conf.CPU = codegen::getMCPU();
+  Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags();
+  Conf.MAttrs = codegen::getMAttrs();
+  if (auto RM = codegen::getRelocModel())
     Conf.RelocModel = *RM;
-  Conf.CodeModel = getCodeModel();
+  Conf.CodeModel = codegen::getCodeModel();
 
   Conf.DebugPassManager = DebugPassManager;
 
@@ -267,8 +267,8 @@
     return 1;
   }
 
-  if (FileType.getNumOccurrences())
-    Conf.CGFileType = FileType;
+  if (codegen::getFileType())
+    Conf.CGFileType = codegen::getFileType();
 
   Conf.OverrideTriple = OverrideTriple;
   Conf.DefaultTriple = DefaultTriple;
Index: llvm/tools/llvm-lto2/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-lto2/CMakeLists.txt
+++ llvm/tools/llvm-lto2/CMakeLists.txt
@@ -20,3 +20,4 @@
   DEPENDS
   intrinsics_gen
   )
+target_link_libraries(llvm-lto2 PUBLIC LLVMCodeGenCommandFlags)
Index: llvm/tools/llvm-lto/llvm-lto.cpp
===================================================================
--- llvm/tools/llvm-lto/llvm-lto.cpp
+++ llvm/tools/llvm-lto/llvm-lto.cpp
@@ -21,7 +21,7 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LLVMContext.h"
@@ -412,7 +412,7 @@
   LLVMContext Context;
   Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
                                true);
-  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  TargetOptions Options = llvm::codegen::InitTargetOptionsFromCodeGenFlags();
   for (auto &Filename : InputFilenames) {
     ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
         LTOModule::createFromFile(Context, Filename, Options);
@@ -549,7 +549,7 @@
   ThinLTOCodeGenerator ThinGenerator;
 
   ThinLTOProcessing(const TargetOptions &Options) {
-    ThinGenerator.setCodePICModel(getRelocModel());
+    ThinGenerator.setCodePICModel(llvm::codegen::getRelocModel());
     ThinGenerator.setTargetOptions(Options);
     ThinGenerator.setCacheDir(ThinLTOCacheDir);
     ThinGenerator.setCachePruningInterval(ThinLTOCachePruningInterval);
@@ -901,7 +901,7 @@
   InitializeAllAsmParsers();
 
   // set up the TargetOptions for the machine
-  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  TargetOptions Options = llvm::codegen::InitTargetOptionsFromCodeGenFlags();
 
   if (ListSymbolsOnly) {
     listSymbols(Options);
@@ -962,7 +962,7 @@
   if (UseDiagnosticHandler)
     CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr);
 
-  CodeGen.setCodePICModel(getRelocModel());
+  CodeGen.setCodePICModel(llvm::codegen::getRelocModel());
   CodeGen.setFreestanding(EnableFreestanding);
 
   CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF);
@@ -1013,22 +1013,21 @@
     CodeGen.addMustPreserveSymbol(KeptDSOSyms[i]);
 
   // Set cpu and attrs strings for the default target/subtarget.
-  CodeGen.setCpu(MCPU.c_str());
+  CodeGen.setCpu(llvm::codegen::getMCPU().c_str());
 
   CodeGen.setOptLevel(OptLevel - '0');
 
   std::string attrs;
-  for (unsigned i = 0; i < MAttrs.size(); ++i) {
+  for (unsigned i = 0; i < llvm::codegen::getMAttrs().size(); ++i) {
     if (i > 0)
       attrs.append(",");
-    attrs.append(MAttrs[i]);
+    attrs.append(llvm::codegen::getMAttrs()[i]);
   }
 
   if (!attrs.empty())
     CodeGen.setAttr(attrs);
 
-  if (FileType.getNumOccurrences())
-    CodeGen.setFileType(FileType);
+  CodeGen.setFileType(llvm::codegen::getFileType());
 
   if (!OutputFilename.empty()) {
     if (!CodeGen.optimize(DisableVerify, DisableInline, DisableGVNLoadPRE,
Index: llvm/tools/llvm-lto/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-lto/CMakeLists.txt
+++ llvm/tools/llvm-lto/CMakeLists.txt
@@ -17,7 +17,8 @@
 add_llvm_tool(llvm-lto
   llvm-lto.cpp
 
-  DEPENDS
-  intrinsics_gen
+  DEPENDS intrinsics_gen
   )
+target_link_libraries(llvm-lto PUBLIC
+  LLVMCodeGenCommandFlags)
 
Index: llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp
===================================================================
--- llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp
+++ llvm/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp
@@ -14,7 +14,7 @@
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/FuzzMutate/FuzzerCLI.h"
 #include "llvm/FuzzMutate/IRMutator.h"
 #include "llvm/FuzzMutate/Operations.h"
@@ -133,14 +133,15 @@
   // Get the target specific parser.
   std::string Error;
   const Target *TheTarget =
-      TargetRegistry::lookupTarget(MArch, TheTriple, Error);
+      TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
   if (!TheTarget) {
     errs() << argv[0] << ": " << Error;
     return 1;
   }
 
   // Set up the pipeline like llc does.
-  std::string CPUStr = getCPUStr(), FeaturesStr = getFeaturesStr();
+  std::string CPUStr = codegen::getCPUStr(),
+              FeaturesStr = codegen::getFeaturesStr();
 
   CodeGenOpt::Level OLvl = CodeGenOpt::Default;
   switch (OptLevel) {
@@ -154,10 +155,10 @@
   case '3': OLvl = CodeGenOpt::Aggressive; break;
   }
 
-  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
-  TM.reset(TheTarget->createTargetMachine(TheTriple.getTriple(), CPUStr,
-                                          FeaturesStr, Options, getRelocModel(),
-                                          getCodeModel(), OLvl));
+  TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags();
+  TM.reset(TheTarget->createTargetMachine(
+      TheTriple.getTriple(), CPUStr, FeaturesStr, Options,
+      codegen::getRelocModel(), codegen::getCodeModel(), OLvl));
   assert(TM && "Could not allocate target machine!");
 
   // Make sure we print the summary and the current unit when LLVM errors out.
Index: llvm/tools/llvm-isel-fuzzer/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-isel-fuzzer/CMakeLists.txt
+++ llvm/tools/llvm-isel-fuzzer/CMakeLists.txt
@@ -21,3 +21,4 @@
   llvm-isel-fuzzer.cpp
   DUMMY_MAIN DummyISelFuzzer.cpp
   )
+target_link_libraries(llvm-isel-fuzzer PUBLIC LLVMCodeGenCommandFlags)
Index: llvm/tools/llvm-dwp/llvm-dwp.cpp
===================================================================
--- llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -27,7 +27,7 @@
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
 #include "llvm/Object/Decompressor.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/DataExtractor.h"
@@ -686,7 +686,7 @@
   if (!MRI)
     return error(Twine("no register info for target ") + TripleName, Context);
 
-  MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
+  MCTargetOptions MCOptions = llvm::mc::InitMCTargetOptionsFromFlags();
   std::unique_ptr<MCAsmInfo> MAI(
       TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
   if (!MAI)
Index: llvm/tools/llvm-dwp/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-dwp/CMakeLists.txt
+++ llvm/tools/llvm-dwp/CMakeLists.txt
@@ -18,6 +18,8 @@
   DEPENDS
   intrinsics_gen
   )
+target_link_libraries(llvm-dwp PUBLIC
+    LLVMMCCommandFlags)
 
 if(LLVM_INSTALL_BINUTILS_SYMLINKS)
   add_llvm_tool_symlink(dwp llvm-dwp)
Index: llvm/tools/lli/lli.cpp
===================================================================
--- llvm/tools/lli/lli.cpp
+++ llvm/tools/lli/lli.cpp
@@ -16,7 +16,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/CodeGen/LinkAllCodegenComponents.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/ExecutionEngine/GenericValue.h"
@@ -435,13 +435,13 @@
 
   std::string ErrorMsg;
   EngineBuilder builder(std::move(Owner));
-  builder.setMArch(MArch);
-  builder.setMCPU(getCPUStr());
-  builder.setMAttrs(getFeatureList());
-  if (RelocModel.getNumOccurrences())
-    builder.setRelocationModel(RelocModel);
-  if (CMModel.getNumOccurrences())
-    builder.setCodeModel(CMModel);
+  builder.setMArch(codegen::getMArch());
+  builder.setMCPU(codegen::getCPUStr());
+  builder.setMAttrs(codegen::getFeatureList());
+  if (codegen::getRelocModel())
+    builder.setRelocationModel(codegen::getRelocModel().getValue());
+  if (codegen::getCodeModel())
+    builder.setCodeModel(codegen::getCodeModel().getValue());
   builder.setErrorStr(&ErrorMsg);
   builder.setEngineKind(ForceInterpreter
                         ? EngineKind::Interpreter
@@ -473,9 +473,9 @@
 
   builder.setOptLevel(getOptLevel());
 
-  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
-  if (FloatABIForCalls != FloatABI::Default)
-    Options.FloatABIType = FloatABIForCalls;
+  TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags();
+  if (codegen::getFloatABIForCalls() != FloatABI::Default)
+    Options.FloatABIType = codegen::getFloatABIForCalls();
 
   builder.setTargetOptions(Options);
 
@@ -827,18 +827,15 @@
   if (DL)
     Builder.setDataLayout(DL);
 
-  if (!MArch.empty())
-    Builder.getJITTargetMachineBuilder()->getTargetTriple().setArchName(MArch);
+  if (!codegen::getMArch().empty())
+    Builder.getJITTargetMachineBuilder()->getTargetTriple().setArchName(
+        codegen::getMArch());
 
   Builder.getJITTargetMachineBuilder()
-      ->setCPU(getCPUStr())
-      .addFeatures(getFeatureList())
-      .setRelocationModel(RelocModel.getNumOccurrences()
-                              ? Optional<Reloc::Model>(RelocModel)
-                              : None)
-      .setCodeModel(CMModel.getNumOccurrences()
-                        ? Optional<CodeModel::Model>(CMModel)
-                        : None);
+      ->setCPU(codegen::getCPUStr())
+      .addFeatures(codegen::getFeatureList())
+      .setRelocationModel(codegen::getRelocModel())
+      .setCodeModel(codegen::getCodeModel());
 
   Builder.setLazyCompileFailureAddr(
       pointerToJITTargetAddress(exitOnLazyCallThroughFailure));
Index: llvm/tools/lli/CMakeLists.txt
===================================================================
--- llvm/tools/lli/CMakeLists.txt
+++ llvm/tools/lli/CMakeLists.txt
@@ -53,4 +53,5 @@
   DEPENDS
   intrinsics_gen
   )
+target_link_libraries(lli PUBLIC LLVMCodeGenCommandFlags)
 export_executable_symbols(lli)
Index: llvm/tools/llc/llc.cpp
===================================================================
--- llvm/tools/llc/llc.cpp
+++ llvm/tools/llc/llc.cpp
@@ -15,7 +15,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
 #include "llvm/CodeGen/LinkAllCodegenComponents.h"
 #include "llvm/CodeGen/MIRParser/MIRParser.h"
@@ -202,7 +202,7 @@
       else
         OutputFilename = std::string(IFN);
 
-      switch (FileType) {
+      switch (codegen::getFileType()) {
       case CGFT_AssemblyFile:
         if (TargetName[0] == 'c') {
           if (TargetName[1] == 0)
@@ -229,7 +229,7 @@
 
   // Decide if we need "binary" output.
   bool Binary = false;
-  switch (FileType) {
+  switch (codegen::getFileType()) {
   case CGFT_AssemblyFile:
     break;
   case CGFT_ObjectFile:
@@ -395,15 +395,17 @@
   std::unique_ptr<Module> M;
   std::unique_ptr<MIRParser> MIR;
   Triple TheTriple;
-  std::string CPUStr = getCPUStr(), FeaturesStr = getFeaturesStr();
+  std::string CPUStr = codegen::getCPUStr(),
+              FeaturesStr = codegen::getFeaturesStr();
 
   // Set attributes on functions as loaded from MIR from command line arguments.
   auto setMIRFunctionAttributes = [&CPUStr, &FeaturesStr](Function &F) {
-    setFunctionAttributes(CPUStr, FeaturesStr, F);
+    codegen::setFunctionAttributes(CPUStr, FeaturesStr, F);
   };
 
-  bool SkipModule = MCPU == "help" ||
-                    (!MAttrs.empty() && MAttrs.front() == "help");
+  bool SkipModule =
+      codegen::getMCPU() == "help" ||
+      (!codegen::getMAttrs().empty() && codegen::getMAttrs().front() == "help");
 
   // If user just wants to list available options, skip module loading
   if (!SkipModule) {
@@ -433,8 +435,8 @@
 
   // Get the target specific parser.
   std::string Error;
-  const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
-                                                         Error);
+  const Target *TheTarget =
+      TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
   if (!TheTarget) {
     WithColor::error(errs(), argv[0]) << Error;
     return 1;
@@ -452,7 +454,7 @@
   case '3': OLvl = CodeGenOpt::Aggressive; break;
   }
 
-  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  TargetOptions Options = llvm::codegen::InitTargetOptionsFromCodeGenFlags();
   Options.DisableIntegratedAS = NoIntegratedAssembler;
   Options.MCOptions.ShowMCEncoding = ShowMCEncoding;
   Options.MCOptions.MCUseDwarfDirectory = EnableDwarfDirectory;
@@ -463,7 +465,7 @@
 
   // On AIX, setting the relocation model to anything other than PIC is considered
   // a user error.
-  Optional<Reloc::Model> RM = getRelocModel();
+  Optional<Reloc::Model> RM = codegen::getRelocModel();
   if (TheTriple.isOSAIX() && RM.hasValue() && *RM != Reloc::PIC_) {
     WithColor::error(errs(), argv[0])
         << "invalid relocation model, AIX only supports PIC.\n";
@@ -472,7 +474,7 @@
 
   std::unique_ptr<TargetMachine> Target(TheTarget->createTargetMachine(
       TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM,
-      getCodeModel(), OLvl));
+      llvm::codegen::getCodeModel(), OLvl));
 
   assert(Target && "Could not allocate target machine!");
 
@@ -483,8 +485,8 @@
     return 0;
 
   assert(M && "Should have exited if we didn't have a module!");
-  if (FloatABIForCalls != FloatABI::Default)
-    Options.FloatABIType = FloatABIForCalls;
+  if (codegen::getFloatABIForCalls() != FloatABI::Default)
+    Options.FloatABIType = codegen::getFloatABIForCalls();
 
   // Figure out where we are going to send the output.
   std::unique_ptr<ToolOutputFile> Out =
@@ -531,10 +533,10 @@
 
   // Override function attributes based on CPUStr, FeaturesStr, and command line
   // flags.
-  setFunctionAttributes(CPUStr, FeaturesStr, *M);
+  codegen::setFunctionAttributes(CPUStr, FeaturesStr, *M);
 
-  if (RelaxAll.getNumOccurrences() > 0 &&
-      FileType != CGFT_ObjectFile)
+  if (mc::getRelaxAll() && // FIXME: num occurence
+      codegen::getFileType() != CGFT_ObjectFile)
     WithColor::warning(errs(), argv[0])
         << ": warning: ignoring -mc-relax-all because filetype != obj";
 
@@ -545,7 +547,7 @@
     // so we can memcmp the contents in CompileTwice mode
     SmallVector<char, 0> Buffer;
     std::unique_ptr<raw_svector_ostream> BOS;
-    if ((FileType != CGFT_AssemblyFile &&
+    if ((codegen::getFileType() != CGFT_AssemblyFile &&
          !Out->os().supportsSeeking()) ||
         CompileTwice) {
       BOS = std::make_unique<raw_svector_ostream>(Buffer);
@@ -584,9 +586,9 @@
       TPC.setInitialized();
       PM.add(createPrintMIRPass(*OS));
       PM.add(createFreeMachineFunctionPass());
-    } else if (Target->addPassesToEmitFile(PM, *OS,
-                                           DwoOut ? &DwoOut->os() : nullptr,
-                                           FileType, NoVerify, MMIWP)) {
+    } else if (Target->addPassesToEmitFile(
+                   PM, *OS, DwoOut ? &DwoOut->os() : nullptr,
+                   codegen::getFileType(), NoVerify, MMIWP)) {
       WithColor::warning(errs(), argv[0])
           << "target does not support generation of this"
           << " file type!\n";
Index: llvm/tools/llc/CMakeLists.txt
===================================================================
--- llvm/tools/llc/CMakeLists.txt
+++ llvm/tools/llc/CMakeLists.txt
@@ -26,4 +26,5 @@
   intrinsics_gen
   SUPPORT_PLUGINS
   )
+target_link_libraries(llc PUBLIC LLVMCodeGenCommandFlags LLVMMCCommandFlags)
 export_executable_symbols(llc)
Index: llvm/tools/dsymutil/DwarfStreamer.cpp
===================================================================
--- llvm/tools/dsymutil/DwarfStreamer.cpp
+++ llvm/tools/dsymutil/DwarfStreamer.cpp
@@ -13,7 +13,7 @@
 #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/MC/MCTargetOptions.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Target/TargetMachine.h"
@@ -39,7 +39,7 @@
   if (!MRI)
     return error(Twine("no register info for target ") + TripleName, Context);
 
-  MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
+  MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
   MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
   if (!MAI)
     return error("no asm info for target " + TripleName, Context);
Index: llvm/tools/dsymutil/CMakeLists.txt
===================================================================
--- llvm/tools/dsymutil/CMakeLists.txt
+++ llvm/tools/dsymutil/CMakeLists.txt
@@ -34,6 +34,8 @@
   ${tablegen_deps}
   )
 
+target_link_libraries(dsymutil PUBLIC LLVMMCCommandFlags)
+
 if(APPLE)
   target_link_libraries(dsymutil PRIVATE "-framework CoreFoundation")
 endif(APPLE)
Index: llvm/lib/MC/CommandFlags/MCTargetOptionsCommandFlags.cpp
===================================================================
--- /dev/null
+++ llvm/lib/MC/CommandFlags/MCTargetOptionsCommandFlags.cpp
@@ -0,0 +1,82 @@
+//===-- MCTargetOptionsCommandFlags.cpp --------------------------*- C++
+//-*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains machine code-specific flags that are shared between
+// different command line tools.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
+
+using namespace llvm;
+
+static cl::opt<bool>
+    RelaxAll("mc-relax-all",
+             cl::desc("When used with filetype=obj, "
+                      "relax all fixups in the emitted object file"));
+bool llvm::mc::getRelaxAll() { return RelaxAll; }
+
+static cl::opt<bool> IncrementalLinkerCompatible(
+    "incremental-linker-compatible",
+    cl::desc(
+        "When used with filetype=obj, "
+        "emit an object file which can be used with an incremental linker"));
+
+bool llvm::mc::getIncrementalLinkerCompatible() {
+  return IncrementalLinkerCompatible;
+}
+
+static cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
+                                 cl::init(0));
+
+int llvm::mc::getDwarfVersion() { return DwarfVersion; }
+
+static cl::opt<bool>
+    ShowMCInst("asm-show-inst",
+               cl::desc("Emit internal instruction representation to "
+                        "assembly file"));
+
+bool llvm::mc::getShowMCInst() { return ShowMCInst; }
+
+static cl::opt<bool> FatalWarnings("fatal-warnings",
+                                   cl::desc("Treat warnings as errors"));
+
+bool llvm::mc::getFatalWarnings() { return FatalWarnings; }
+
+static cl::opt<bool> NoWarn("no-warn", cl::desc("Suppress all warnings"));
+static cl::alias NoWarnW("W", cl::desc("Alias for --no-warn"),
+                         cl::aliasopt(NoWarn));
+
+bool llvm::mc::getNoWarn() { return NoWarn; }
+
+static cl::opt<bool>
+    NoDeprecatedWarn("no-deprecated-warn",
+                     cl::desc("Suppress all deprecated warnings"));
+
+bool llvm::mc::getNoDeprecatedWarn() { return NoDeprecatedWarn; }
+
+static cl::opt<std::string>
+    ABIName("target-abi", cl::Hidden,
+            cl::desc("The name of the ABI to be targeted from the backend."),
+            cl::init(""));
+
+std::string llvm::mc::getABIName() { return ABIName; }
+
+MCTargetOptions llvm::mc::InitMCTargetOptionsFromFlags() {
+  MCTargetOptions Options;
+  Options.MCRelaxAll = RelaxAll;
+  Options.MCIncrementalLinkerCompatible = IncrementalLinkerCompatible;
+  Options.DwarfVersion = DwarfVersion;
+  Options.ShowMCInst = ShowMCInst;
+  Options.ABIName = ABIName;
+  Options.MCFatalWarnings = FatalWarnings;
+  Options.MCNoWarn = NoWarn;
+  Options.MCNoDeprecatedWarn = NoDeprecatedWarn;
+  return Options;
+}
Index: llvm/lib/MC/CommandFlags/CMakeLists.txt
===================================================================
--- /dev/null
+++ llvm/lib/MC/CommandFlags/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_llvm_library(LLVMMCCommandFlags
+    MCTargetOptionsCommandFlags.cpp
+
+    LINK_COMPONENTS
+
+    Core
+    Support
+    MC
+
+)
+
Index: llvm/lib/MC/CMakeLists.txt
===================================================================
--- llvm/lib/MC/CMakeLists.txt
+++ llvm/lib/MC/CMakeLists.txt
@@ -65,3 +65,4 @@
 
 add_subdirectory(MCParser)
 add_subdirectory(MCDisassembler)
+add_subdirectory(CommandFlags)
Index: llvm/lib/CodeGen/CommandFlags/CommandFlags.cpp
===================================================================
--- /dev/null
+++ llvm/lib/CodeGen/CommandFlags/CommandFlags.cpp
@@ -0,0 +1,530 @@
+//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains codegen-specific flags that are shared between different
+// command line tools. The tools "llc" and "opt" both use this file to prevent
+// flag duplication.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/CommandFlags.h"
+using namespace llvm;
+
+static cl::opt<std::string>
+    MArch("march",
+          cl::desc("Architecture to generate code for (see --version)"));
+
+std::string llvm::codegen::getMArch() { return MArch; }
+
+static cl::opt<std::string>
+    MCPU("mcpu",
+         cl::desc("Target a specific cpu type (-mcpu=help for details)"),
+         cl::value_desc("cpu-name"), cl::init(""));
+
+std::string llvm::codegen::getMCPU() { return MCPU; }
+
+static cl::list<std::string>
+    MAttrs("mattr", cl::CommaSeparated,
+           cl::desc("Target specific attributes (-mattr=help for details)"),
+           cl::value_desc("a1,+a2,-a3,..."));
+
+std::vector<std::string> llvm::codegen::getMAttrs() { return MAttrs; }
+
+static cl::opt<Reloc::Model> RelocModel(
+    "relocation-model", cl::desc("Choose relocation model"),
+    cl::values(
+        clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
+        clEnumValN(Reloc::PIC_, "pic",
+                   "Fully relocatable, position independent code"),
+        clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
+                   "Relocatable external references, non-relocatable code"),
+        clEnumValN(Reloc::ROPI, "ropi",
+                   "Code and read-only data relocatable, accessed PC-relative"),
+        clEnumValN(
+            Reloc::RWPI, "rwpi",
+            "Read-write data relocatable, accessed relative to static base"),
+        clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
+                   "Combination of ropi and rwpi")));
+
+Optional<Reloc::Model> llvm::codegen::getRelocModel() {
+  if (RelocModel.getNumOccurrences()) {
+    Reloc::Model R = RelocModel;
+    return R;
+  }
+  return None;
+}
+
+static cl::opt<ThreadModel::Model> TMModel(
+    "thread-model", cl::desc("Choose threading model"),
+    cl::init(ThreadModel::POSIX),
+    cl::values(clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
+               clEnumValN(ThreadModel::Single, "single",
+                          "Single thread model")));
+ThreadModel::Model llvm::codegen::getTMModel() { return TMModel; }
+
+static cl::opt<llvm::CodeModel::Model> CMModel(
+    "code-model", cl::desc("Choose code model"),
+    cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),
+               clEnumValN(CodeModel::Small, "small", "Small code model"),
+               clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
+               clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
+               clEnumValN(CodeModel::Large, "large", "Large code model")));
+
+Optional<CodeModel::Model> llvm::codegen::getCodeModel() {
+  if (CMModel.getNumOccurrences()) {
+    CodeModel::Model M = CMModel;
+    return M;
+  }
+  return None;
+}
+
+static cl::opt<llvm::ExceptionHandling> ExceptionModel(
+    "exception-model", cl::desc("exception model"),
+    cl::init(ExceptionHandling::None),
+    cl::values(
+        clEnumValN(ExceptionHandling::None, "default",
+                   "default exception handling model"),
+        clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
+                   "DWARF-like CFI based exception handling"),
+        clEnumValN(ExceptionHandling::SjLj, "sjlj", "SjLj exception handling"),
+        clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
+        clEnumValN(ExceptionHandling::WinEH, "wineh",
+                   "Windows exception model"),
+        clEnumValN(ExceptionHandling::Wasm, "wasm",
+                   "WebAssembly exception handling")));
+
+llvm::ExceptionHandling llvm::codegen::getExceptionModel() {
+  return ExceptionModel;
+}
+
+static cl::opt<CodeGenFileType> FileType(
+    "filetype", cl::init(CGFT_AssemblyFile),
+    cl::desc(
+        "Choose a file type (not all types are supported by all targets):"),
+    cl::values(
+        clEnumValN(CGFT_AssemblyFile, "asm", "Emit an assembly ('.s') file"),
+        clEnumValN(CGFT_ObjectFile, "obj", "Emit a native object ('.o') file"),
+        clEnumValN(CGFT_Null, "null",
+                   "Emit nothing, for performance testing")));
+CodeGenFileType llvm::codegen::getFileType() { return FileType; }
+
+static cl::opt<llvm::FramePointer::FP> FramePointerUsage(
+    "frame-pointer", cl::desc("Specify frame pointer elimination optimization"),
+    cl::init(llvm::FramePointer::None),
+    cl::values(
+        clEnumValN(llvm::FramePointer::All, "all",
+                   "Disable frame pointer elimination"),
+        clEnumValN(llvm::FramePointer::NonLeaf, "non-leaf",
+                   "Disable frame pointer elimination for non-leaf frame"),
+        clEnumValN(llvm::FramePointer::None, "none",
+                   "Enable frame pointer elimination")));
+
+llvm::FramePointer::FP llvm::codegen::getFramePointerUsage() {
+  return FramePointerUsage;
+}
+
+static cl::opt<bool> EnableUnsafeFPMath(
+    "enable-unsafe-fp-math",
+    cl::desc("Enable optimizations that may decrease FP precision"),
+    cl::init(false));
+bool llvm::codegen::getEnableUnsafeFPMath() { return EnableUnsafeFPMath; }
+
+static cl::opt<bool> EnableNoInfsFPMath(
+    "enable-no-infs-fp-math",
+    cl::desc("Enable FP math optimizations that assume no +-Infs"),
+    cl::init(false));
+bool llvm::codegen::getEnableNoInfsFPMath() { return EnableNoInfsFPMath; }
+
+static cl::opt<bool> EnableNoNaNsFPMath(
+    "enable-no-nans-fp-math",
+    cl::desc("Enable FP math optimizations that assume no NaNs"),
+    cl::init(false));
+
+bool llvm::codegen::getEnableNoNaNsFPMath() { return EnableNoNaNsFPMath; }
+
+static cl::opt<bool> EnableNoSignedZerosFPMath(
+    "enable-no-signed-zeros-fp-math",
+    cl::desc("Enable FP math optimizations that assume "
+             "the sign of 0 is insignificant"),
+    cl::init(false));
+
+bool llvm::codegen::getEnableNoSignedZerosFPMath() {
+  return EnableNoSignedZerosFPMath;
+}
+
+static cl::opt<bool>
+    EnableNoTrappingFPMath("enable-no-trapping-fp-math",
+                           cl::desc("Enable setting the FP exceptions build "
+                                    "attribute not to use exceptions"),
+                           cl::init(false));
+
+bool llvm::codegen::getEnableNoTrappingFPMath() {
+  return EnableNoTrappingFPMath;
+}
+
+static cl::opt<llvm::FPDenormal::DenormalMode> DenormalFPMath(
+    "denormal-fp-math",
+    cl::desc("Select which denormal numbers the code is permitted to require"),
+    cl::init(FPDenormal::IEEE),
+    cl::values(clEnumValN(FPDenormal::IEEE, "ieee",
+                          "IEEE 754 denormal numbers"),
+               clEnumValN(FPDenormal::PreserveSign, "preserve-sign",
+                          "the sign of a  flushed-to-zero number is preserved "
+                          "in the sign of 0"),
+               clEnumValN(FPDenormal::PositiveZero, "positive-zero",
+                          "denormals are flushed to positive zero")));
+
+llvm::FPDenormal::DenormalMode getDenormalFPMath() { return DenormalFPMath; }
+
+static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
+    "enable-sign-dependent-rounding-fp-math", cl::Hidden,
+    cl::desc("Force codegen to assume rounding mode can change dynamically"),
+    cl::init(false));
+
+bool llvm::codegen::getEnableHonorSignDependentRoundingFPMath() {
+  return EnableHonorSignDependentRoundingFPMath;
+}
+
+static cl::opt<llvm::FloatABI::ABIType> FloatABIForCalls(
+    "float-abi", cl::desc("Choose float ABI type"), cl::init(FloatABI::Default),
+    cl::values(clEnumValN(FloatABI::Default, "default",
+                          "Target default float ABI type"),
+               clEnumValN(FloatABI::Soft, "soft",
+                          "Soft float ABI (implied by -soft-float)"),
+               clEnumValN(FloatABI::Hard, "hard",
+                          "Hard float ABI (uses FP registers)")));
+
+llvm::FloatABI::ABIType llvm::codegen::getFloatABIForCalls() {
+  return FloatABIForCalls;
+}
+
+static cl::opt<llvm::FPOpFusion::FPOpFusionMode> FuseFPOps(
+    "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
+    cl::init(FPOpFusion::Standard),
+    cl::values(
+        clEnumValN(FPOpFusion::Fast, "fast", "Fuse FP ops whenever profitable"),
+        clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
+        clEnumValN(FPOpFusion::Strict, "off",
+                   "Only fuse FP ops when the result won't be affected.")));
+
+llvm::FPOpFusion::FPOpFusionMode llvm::codegen::getFuseFPOps() {
+  return FuseFPOps;
+}
+
+static cl::opt<bool> DontPlaceZerosInBSS(
+    "nozero-initialized-in-bss",
+    cl::desc("Don't place zero-initialized symbols into bss section"),
+    cl::init(false));
+
+bool llvm::codegen::getDontPlaceZerosInBSS() { return DontPlaceZerosInBSS; }
+
+static cl::opt<bool> EnableGuaranteedTailCallOpt(
+    "tailcallopt",
+    cl::desc(
+        "Turn fastcc calls into tail calls by (potentially) changing ABI."),
+    cl::init(false));
+
+bool llvm::codegen::getEnableGuaranteedTailCallOpt() {
+  return EnableGuaranteedTailCallOpt;
+}
+
+static cl::opt<bool> DisableTailCalls("disable-tail-calls",
+                                      cl::desc("Never emit tail calls"),
+                                      cl::init(false));
+
+bool llvm::codegen::getDisableTailCalls() { return DisableTailCalls; }
+
+static cl::opt<bool> StackSymbolOrdering("stack-symbol-ordering",
+                                         cl::desc("Order local stack symbols."),
+                                         cl::init(true));
+
+bool llvm::codegen::getStackSymbolOrdering() { return StackSymbolOrdering; }
+
+static cl::opt<unsigned>
+    OverrideStackAlignment("stack-alignment",
+                           cl::desc("Override default stack alignment"),
+                           cl::init(0));
+
+unsigned llvm::codegen::getOverrideStackAlignment() {
+  return OverrideStackAlignment;
+}
+
+static cl::opt<bool>
+    StackRealign("stackrealign",
+                 cl::desc("Force align the stack to the minimum alignment"),
+                 cl::init(false));
+
+bool llvm::codegen::getStackRealign() { return StackRealign; }
+
+static cl::opt<std::string> TrapFuncName(
+    "trap-func", cl::Hidden,
+    cl::desc("Emit a call to trap function rather than a trap instruction"),
+    cl::init(""));
+
+std::string llvm::codegen::getTrapFuncName() { return TrapFuncName; }
+
+static cl::opt<bool> UseCtors("use-ctors",
+                              cl::desc("Use .ctors instead of .init_array."),
+                              cl::init(false));
+
+bool llvm::codegen::getUseCtors() { return UseCtors; }
+
+static cl::opt<bool> RelaxELFRelocations(
+    "relax-elf-relocations",
+    cl::desc("Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
+    cl::init(false));
+
+bool llvm::codegen::getRelaxELFRelocations() { return RelaxELFRelocations; }
+
+static cl::opt<bool> DataSections("data-sections",
+                                  cl::desc("Emit data into separate sections"),
+                                  cl::init(false));
+
+bool llvm::codegen::getDataSections() { return DataSections; }
+
+static cl::opt<bool>
+    FunctionSections("function-sections",
+                     cl::desc("Emit functions into separate sections"),
+                     cl::init(false));
+
+bool llvm::codegen::getFunctionSections() { return FunctionSections; }
+
+static cl::opt<unsigned> TLSSize("tls-size",
+                                 cl::desc("Bit size of immediate TLS offsets"),
+                                 cl::init(0));
+
+unsigned llvm::codegen::getTLSSize() { return TLSSize; }
+
+static cl::opt<bool> EmulatedTLS("emulated-tls",
+                                 cl::desc("Use emulated TLS model"),
+                                 cl::init(false));
+
+bool llvm::codegen::getEmulatedTLS() { return EmulatedTLS; }
+
+static cl::opt<bool>
+    UniqueSectionNames("unique-section-names",
+                       cl::desc("Give unique names to every section"),
+                       cl::init(true));
+
+bool llvm::codegen::getUniqueSectionNames() { return UniqueSectionNames; }
+
+static cl::opt<llvm::EABI>
+    EABIVersion("meabi", cl::desc("Set EABI type (default depends on triple):"),
+                cl::init(EABI::Default),
+                cl::values(clEnumValN(EABI::Default, "default",
+                                      "Triple default EABI version"),
+                           clEnumValN(EABI::EABI4, "4", "EABI version 4"),
+                           clEnumValN(EABI::EABI5, "5", "EABI version 5"),
+                           clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
+
+llvm::EABI llvm::codegen::getEABIVersion() { return EABIVersion; }
+
+static cl::opt<DebuggerKind> DebuggerTuningOpt(
+    "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
+    cl::init(DebuggerKind::Default),
+    cl::values(clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
+               clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
+               clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
+
+DebuggerKind llvm::codegen::getDebuggerTuningOpt() { return DebuggerTuningOpt; }
+
+static cl::opt<bool> EnableStackSizeSection(
+    "stack-size-section",
+    cl::desc("Emit a section containing stack size metadata"), cl::init(false));
+bool llvm::codegen::getEnableStackSizeSection() {
+  return EnableStackSizeSection;
+}
+static cl::opt<bool>
+    EnableAddrsig("addrsig", cl::desc("Emit an address-significance table"),
+                  cl::init(false));
+bool llvm::codegen::getEnableAddrsig() { return EnableAddrsig; }
+static cl::opt<bool> EnableDebugEntryValues(
+    "debug-entry-values",
+    cl::desc("Emit debug info about parameter's entry values"),
+    cl::init(false));
+bool llvm::codegen::getEnableDebugEntryValues() {
+  return EnableDebugEntryValues;
+}
+
+static cl::opt<bool>
+    ForceDwarfFrameSection("force-dwarf-frame-section",
+                           cl::desc("Always emit a debug frame section."),
+                           cl::init(false));
+
+bool llvm::codegen::getForceDwarfFrameSection() {
+  return ForceDwarfFrameSection;
+}
+
+// Common utility function tightly tied to the options listed here. Initializes
+// a TargetOptions object with CodeGen flags and returns it.
+TargetOptions llvm::codegen::InitTargetOptionsFromCodeGenFlags() {
+  TargetOptions Options;
+  Options.AllowFPOpFusion = FuseFPOps;
+  Options.UnsafeFPMath = EnableUnsafeFPMath;
+  Options.NoInfsFPMath = EnableNoInfsFPMath;
+  Options.NoNaNsFPMath = EnableNoNaNsFPMath;
+  Options.NoSignedZerosFPMath = EnableNoSignedZerosFPMath;
+  Options.NoTrappingFPMath = EnableNoTrappingFPMath;
+  Options.FPDenormalMode = DenormalFPMath;
+  Options.HonorSignDependentRoundingFPMathOption =
+      EnableHonorSignDependentRoundingFPMath;
+  if (FloatABIForCalls != FloatABI::Default)
+    Options.FloatABIType = FloatABIForCalls;
+  Options.NoZerosInBSS = DontPlaceZerosInBSS;
+  Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
+  Options.StackAlignmentOverride = OverrideStackAlignment;
+  Options.StackSymbolOrdering = StackSymbolOrdering;
+  Options.UseInitArray = !UseCtors;
+  Options.RelaxELFRelocations = RelaxELFRelocations;
+  Options.DataSections = DataSections;
+  Options.FunctionSections = FunctionSections;
+  Options.UniqueSectionNames = UniqueSectionNames;
+  Options.TLSSize = TLSSize;
+  Options.EmulatedTLS = EmulatedTLS;
+  Options.ExplicitEmulatedTLS = EmulatedTLS.getNumOccurrences() > 0;
+  Options.ExceptionModel = ExceptionModel;
+  Options.EmitStackSizeSection = EnableStackSizeSection;
+  Options.EmitAddrsig = EnableAddrsig;
+  Options.EnableDebugEntryValues = EnableDebugEntryValues;
+  Options.ForceDwarfFrameSection = ForceDwarfFrameSection;
+
+  Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
+
+  Options.ThreadModel = TMModel;
+  Options.EABIVersion = EABIVersion;
+  Options.DebuggerTuning = DebuggerTuningOpt;
+
+  return Options;
+}
+
+std::string llvm::codegen::getCPUStr() {
+  // If user asked for the 'native' CPU, autodetect here. If autodection fails,
+  // this will set the CPU to an empty string which tells the target to
+  // pick a basic default.
+  if (MCPU == "native")
+    return std::string(sys::getHostCPUName());
+
+  return MCPU;
+}
+
+std::string llvm::codegen::getFeaturesStr() {
+  SubtargetFeatures Features;
+
+  // If user asked for the 'native' CPU, we need to autodetect features.
+  // This is necessary for x86 where the CPU might not support all the
+  // features the autodetected CPU name lists in the target. For example,
+  // not all Sandybridge processors support AVX.
+  if (MCPU == "native") {
+    StringMap<bool> HostFeatures;
+    if (sys::getHostCPUFeatures(HostFeatures))
+      for (auto &F : HostFeatures)
+        Features.AddFeature(F.first(), F.second);
+  }
+
+  for (unsigned i = 0; i != MAttrs.size(); ++i)
+    Features.AddFeature(MAttrs[i]);
+
+  return Features.getString();
+}
+
+std::vector<std::string> llvm::codegen::getFeatureList() {
+  SubtargetFeatures Features;
+
+  // If user asked for the 'native' CPU, we need to autodetect features.
+  // This is necessary for x86 where the CPU might not support all the
+  // features the autodetected CPU name lists in the target. For example,
+  // not all Sandybridge processors support AVX.
+  if (MCPU == "native") {
+    StringMap<bool> HostFeatures;
+    if (sys::getHostCPUFeatures(HostFeatures))
+      for (auto &F : HostFeatures)
+        Features.AddFeature(F.first(), F.second);
+  }
+
+  for (unsigned i = 0; i != MAttrs.size(); ++i)
+    Features.AddFeature(MAttrs[i]);
+
+  return Features.getFeatures();
+}
+
+void llvm::codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name,
+                                         bool Val) {
+  B.addAttribute(Name, Val ? "true" : "false");
+}
+
+#define HANDLE_BOOL_ATTR(CL, AttrName)                                         \
+  do {                                                                         \
+    if (CL.getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName))             \
+      renderBoolStringAttr(NewAttrs, AttrName, CL);                            \
+  } while (0)
+
+/// Set function attributes of function \p F based on CPU, Features, and command
+/// line flags.
+void llvm::codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
+                                          Function &F) {
+  auto &Ctx = F.getContext();
+  AttributeList Attrs = F.getAttributes();
+  AttrBuilder NewAttrs;
+
+  if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
+    NewAttrs.addAttribute("target-cpu", CPU);
+  if (!Features.empty()) {
+    // Append the command line features to any that are already on the function.
+    StringRef OldFeatures =
+        F.getFnAttribute("target-features").getValueAsString();
+    if (OldFeatures.empty())
+      NewAttrs.addAttribute("target-features", Features);
+    else {
+      SmallString<256> Appended(OldFeatures);
+      Appended.push_back(',');
+      Appended.append(Features);
+      NewAttrs.addAttribute("target-features", Appended);
+    }
+  }
+  if (FramePointerUsage.getNumOccurrences() > 0 &&
+      !F.hasFnAttribute("frame-pointer")) {
+    if (FramePointerUsage == llvm::FramePointer::All)
+      NewAttrs.addAttribute("frame-pointer", "all");
+    else if (FramePointerUsage == llvm::FramePointer::NonLeaf)
+      NewAttrs.addAttribute("frame-pointer", "non-leaf");
+    else if (FramePointerUsage == llvm::FramePointer::None)
+      NewAttrs.addAttribute("frame-pointer", "none");
+  }
+  if (DisableTailCalls.getNumOccurrences() > 0)
+    NewAttrs.addAttribute("disable-tail-calls", toStringRef(DisableTailCalls));
+  if (StackRealign)
+    NewAttrs.addAttribute("stackrealign");
+
+  HANDLE_BOOL_ATTR(EnableUnsafeFPMath, "unsafe-fp-math");
+  HANDLE_BOOL_ATTR(EnableNoInfsFPMath, "no-infs-fp-math");
+  HANDLE_BOOL_ATTR(EnableNoNaNsFPMath, "no-nans-fp-math");
+  HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMath, "no-signed-zeros-fp-math");
+
+  if (TrapFuncName.getNumOccurrences() > 0)
+    for (auto &B : F)
+      for (auto &I : B)
+        if (auto *Call = dyn_cast<CallInst>(&I))
+          if (const auto *F = Call->getCalledFunction())
+            if (F->getIntrinsicID() == Intrinsic::debugtrap ||
+                F->getIntrinsicID() == Intrinsic::trap)
+              Call->addAttribute(
+                  llvm::AttributeList::FunctionIndex,
+                  Attribute::get(Ctx, "trap-func-name", TrapFuncName));
+
+  // Let NewAttrs override Attrs.
+  F.setAttributes(
+      Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
+}
+
+/// Set function attributes of functions in Module M based on CPU,
+/// Features, and command line flags.
+void llvm::codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
+                                          Module &M) {
+  for (Function &F : M)
+    setFunctionAttributes(CPU, Features, F);
+}
Index: llvm/lib/CodeGen/CommandFlags/CMakeLists.txt
===================================================================
--- /dev/null
+++ llvm/lib/CodeGen/CommandFlags/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_llvm_library(LLVMCodeGenCommandFlags
+    CommandFlags.cpp
+
+    LINK_COMPONENTS
+
+    Core
+    Support
+    MC
+
+    LINK_LIBS
+
+    LLVMMCCommandFlags
+)
Index: llvm/lib/CodeGen/CMakeLists.txt
===================================================================
--- llvm/lib/CodeGen/CMakeLists.txt
+++ llvm/lib/CodeGen/CMakeLists.txt
@@ -188,3 +188,4 @@
 add_subdirectory(AsmPrinter)
 add_subdirectory(MIRParser)
 add_subdirectory(GlobalISel)
+add_subdirectory(CommandFlags)
Index: llvm/include/llvm/MC/MCTargetOptionsCommandFlags.inc
===================================================================
--- llvm/include/llvm/MC/MCTargetOptionsCommandFlags.inc
+++ /dev/null
@@ -1,65 +0,0 @@
-//===-- MCTargetOptionsCommandFlags.h --------------------------*- C++ -*-===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains machine code-specific flags that are shared between
-// different command line tools.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
-#define LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
-
-#include "llvm/MC/MCTargetOptions.h"
-#include "llvm/Support/CommandLine.h"
-using namespace llvm;
-
-static cl::opt<bool> RelaxAll("mc-relax-all",
-                       cl::desc("When used with filetype=obj, "
-                                "relax all fixups in the emitted object file"));
-
-static cl::opt<bool> IncrementalLinkerCompatible(
-    "incremental-linker-compatible",
-    cl::desc(
-        "When used with filetype=obj, "
-        "emit an object file which can be used with an incremental linker"));
-
-static cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
-                          cl::init(0));
-
-static cl::opt<bool> ShowMCInst("asm-show-inst",
-                         cl::desc("Emit internal instruction representation to "
-                                  "assembly file"));
-
-static cl::opt<bool> FatalWarnings("fatal-warnings",
-                            cl::desc("Treat warnings as errors"));
-
-static cl::opt<bool> NoWarn("no-warn", cl::desc("Suppress all warnings"));
-static cl::alias NoWarnW("W", cl::desc("Alias for --no-warn"), cl::aliasopt(NoWarn));
-
-static cl::opt<bool> NoDeprecatedWarn("no-deprecated-warn",
-                               cl::desc("Suppress all deprecated warnings"));
-
-static cl::opt<std::string>
-ABIName("target-abi", cl::Hidden,
-        cl::desc("The name of the ABI to be targeted from the backend."),
-        cl::init(""));
-
-static MCTargetOptions InitMCTargetOptionsFromFlags() {
-  MCTargetOptions Options;
-  Options.MCRelaxAll = RelaxAll;
-  Options.MCIncrementalLinkerCompatible = IncrementalLinkerCompatible;
-  Options.DwarfVersion = DwarfVersion;
-  Options.ShowMCInst = ShowMCInst;
-  Options.ABIName = ABIName;
-  Options.MCFatalWarnings = FatalWarnings;
-  Options.MCNoWarn = NoWarn;
-  Options.MCNoDeprecatedWarn = NoDeprecatedWarn;
-  return Options;
-}
-
-#endif
Index: llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
===================================================================
--- /dev/null
+++ llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
@@ -0,0 +1,45 @@
+//===-- MCTargetOptionsCommandFlags.h --------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains machine code-specific flags that are shared between
+// different command line tools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
+#define LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
+
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+
+namespace mc {
+
+bool getRelaxAll();
+
+bool getIncrementalLinkerCompatible();
+
+int getDwarfVersion();
+
+bool getShowMCInst();
+
+bool getFatalWarnings();
+
+bool getNoWarn();
+
+bool getNoDeprecatedWarn();
+
+std::string getABIName();
+
+MCTargetOptions InitMCTargetOptionsFromFlags();
+} // namespace mc
+
+} // namespace llvm
+
+#endif
Index: llvm/include/llvm/CodeGen/CommandFlags.inc
===================================================================
--- llvm/include/llvm/CodeGen/CommandFlags.inc
+++ /dev/null
@@ -1,455 +0,0 @@
-//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains codegen-specific flags that are shared between different
-// command line tools. The tools "llc" and "opt" both use this file to prevent
-// flag duplication.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Module.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
-#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/Support/CodeGen.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
-#include <string>
-using namespace llvm;
-
-static cl::opt<std::string>
-    MArch("march",
-          cl::desc("Architecture to generate code for (see --version)"));
-
-static cl::opt<std::string>
-    MCPU("mcpu",
-         cl::desc("Target a specific cpu type (-mcpu=help for details)"),
-         cl::value_desc("cpu-name"), cl::init(""));
-
-static cl::list<std::string>
-    MAttrs("mattr", cl::CommaSeparated,
-           cl::desc("Target specific attributes (-mattr=help for details)"),
-           cl::value_desc("a1,+a2,-a3,..."));
-
-static cl::opt<Reloc::Model> RelocModel(
-    "relocation-model", cl::desc("Choose relocation model"),
-    cl::values(
-        clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
-        clEnumValN(Reloc::PIC_, "pic",
-                   "Fully relocatable, position independent code"),
-        clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
-                   "Relocatable external references, non-relocatable code"),
-        clEnumValN(Reloc::ROPI, "ropi",
-                   "Code and read-only data relocatable, accessed PC-relative"),
-        clEnumValN(
-            Reloc::RWPI, "rwpi",
-            "Read-write data relocatable, accessed relative to static base"),
-        clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
-                   "Combination of ropi and rwpi")));
-
-LLVM_ATTRIBUTE_UNUSED static Optional<Reloc::Model> getRelocModel() {
-  if (RelocModel.getNumOccurrences()) {
-    Reloc::Model R = RelocModel;
-    return R;
-  }
-  return None;
-}
-
-static cl::opt<ThreadModel::Model> TMModel(
-    "thread-model", cl::desc("Choose threading model"),
-    cl::init(ThreadModel::POSIX),
-    cl::values(clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
-               clEnumValN(ThreadModel::Single, "single",
-                          "Single thread model")));
-
-static cl::opt<llvm::CodeModel::Model> CMModel(
-    "code-model", cl::desc("Choose code model"),
-    cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),
-               clEnumValN(CodeModel::Small, "small", "Small code model"),
-               clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
-               clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
-               clEnumValN(CodeModel::Large, "large", "Large code model")));
-
-LLVM_ATTRIBUTE_UNUSED static Optional<CodeModel::Model> getCodeModel() {
-  if (CMModel.getNumOccurrences()) {
-    CodeModel::Model M = CMModel;
-    return M;
-  }
-  return None;
-}
-
-static cl::opt<llvm::ExceptionHandling> ExceptionModel(
-    "exception-model", cl::desc("exception model"),
-    cl::init(ExceptionHandling::None),
-    cl::values(
-        clEnumValN(ExceptionHandling::None, "default",
-                   "default exception handling model"),
-        clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
-                   "DWARF-like CFI based exception handling"),
-        clEnumValN(ExceptionHandling::SjLj, "sjlj", "SjLj exception handling"),
-        clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
-        clEnumValN(ExceptionHandling::WinEH, "wineh",
-                   "Windows exception model"),
-        clEnumValN(ExceptionHandling::Wasm, "wasm",
-                   "WebAssembly exception handling")));
-
-static cl::opt<CodeGenFileType> FileType(
-    "filetype", cl::init(CGFT_AssemblyFile),
-    cl::desc(
-        "Choose a file type (not all types are supported by all targets):"),
-    cl::values(clEnumValN(CGFT_AssemblyFile, "asm",
-                          "Emit an assembly ('.s') file"),
-               clEnumValN(CGFT_ObjectFile, "obj",
-                          "Emit a native object ('.o') file"),
-               clEnumValN(CGFT_Null, "null",
-                          "Emit nothing, for performance testing")));
-
-static cl::opt<llvm::FramePointer::FP> FramePointerUsage(
-    "frame-pointer", cl::desc("Specify frame pointer elimination optimization"),
-    cl::init(llvm::FramePointer::None),
-    cl::values(
-        clEnumValN(llvm::FramePointer::All, "all",
-                   "Disable frame pointer elimination"),
-        clEnumValN(llvm::FramePointer::NonLeaf, "non-leaf",
-                   "Disable frame pointer elimination for non-leaf frame"),
-        clEnumValN(llvm::FramePointer::None, "none",
-                   "Enable frame pointer elimination")));
-
-static cl::opt<bool> EnableUnsafeFPMath(
-    "enable-unsafe-fp-math",
-    cl::desc("Enable optimizations that may decrease FP precision"),
-    cl::init(false));
-
-static cl::opt<bool> EnableNoInfsFPMath(
-    "enable-no-infs-fp-math",
-    cl::desc("Enable FP math optimizations that assume no +-Infs"),
-    cl::init(false));
-
-static cl::opt<bool> EnableNoNaNsFPMath(
-    "enable-no-nans-fp-math",
-    cl::desc("Enable FP math optimizations that assume no NaNs"),
-    cl::init(false));
-
-static cl::opt<bool> EnableNoSignedZerosFPMath(
-    "enable-no-signed-zeros-fp-math",
-    cl::desc("Enable FP math optimizations that assume "
-             "the sign of 0 is insignificant"),
-    cl::init(false));
-
-static cl::opt<bool>
-    EnableNoTrappingFPMath("enable-no-trapping-fp-math",
-                           cl::desc("Enable setting the FP exceptions build "
-                                    "attribute not to use exceptions"),
-                           cl::init(false));
-
-static cl::opt<llvm::FPDenormal::DenormalMode> DenormalFPMath(
-    "denormal-fp-math",
-    cl::desc("Select which denormal numbers the code is permitted to require"),
-    cl::init(FPDenormal::IEEE),
-    cl::values(clEnumValN(FPDenormal::IEEE, "ieee",
-                          "IEEE 754 denormal numbers"),
-               clEnumValN(FPDenormal::PreserveSign, "preserve-sign",
-                          "the sign of a  flushed-to-zero number is preserved "
-                          "in the sign of 0"),
-               clEnumValN(FPDenormal::PositiveZero, "positive-zero",
-                          "denormals are flushed to positive zero")));
-
-static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
-    "enable-sign-dependent-rounding-fp-math", cl::Hidden,
-    cl::desc("Force codegen to assume rounding mode can change dynamically"),
-    cl::init(false));
-
-static cl::opt<llvm::FloatABI::ABIType> FloatABIForCalls(
-    "float-abi", cl::desc("Choose float ABI type"), cl::init(FloatABI::Default),
-    cl::values(clEnumValN(FloatABI::Default, "default",
-                          "Target default float ABI type"),
-               clEnumValN(FloatABI::Soft, "soft",
-                          "Soft float ABI (implied by -soft-float)"),
-               clEnumValN(FloatABI::Hard, "hard",
-                          "Hard float ABI (uses FP registers)")));
-
-static cl::opt<llvm::FPOpFusion::FPOpFusionMode> FuseFPOps(
-    "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
-    cl::init(FPOpFusion::Standard),
-    cl::values(
-        clEnumValN(FPOpFusion::Fast, "fast", "Fuse FP ops whenever profitable"),
-        clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
-        clEnumValN(FPOpFusion::Strict, "off",
-                   "Only fuse FP ops when the result won't be affected.")));
-
-static cl::opt<bool> DontPlaceZerosInBSS(
-    "nozero-initialized-in-bss",
-    cl::desc("Don't place zero-initialized symbols into bss section"),
-    cl::init(false));
-
-static cl::opt<bool> EnableGuaranteedTailCallOpt(
-    "tailcallopt",
-    cl::desc(
-        "Turn fastcc calls into tail calls by (potentially) changing ABI."),
-    cl::init(false));
-
-static cl::opt<bool> DisableTailCalls("disable-tail-calls",
-                                      cl::desc("Never emit tail calls"),
-                                      cl::init(false));
-
-static cl::opt<bool> StackSymbolOrdering("stack-symbol-ordering",
-                                         cl::desc("Order local stack symbols."),
-                                         cl::init(true));
-
-static cl::opt<unsigned>
-    OverrideStackAlignment("stack-alignment",
-                           cl::desc("Override default stack alignment"),
-                           cl::init(0));
-
-static cl::opt<bool>
-    StackRealign("stackrealign",
-                 cl::desc("Force align the stack to the minimum alignment"),
-                 cl::init(false));
-
-static cl::opt<std::string> TrapFuncName(
-    "trap-func", cl::Hidden,
-    cl::desc("Emit a call to trap function rather than a trap instruction"),
-    cl::init(""));
-
-static cl::opt<bool> UseCtors("use-ctors",
-                              cl::desc("Use .ctors instead of .init_array."),
-                              cl::init(false));
-
-static cl::opt<bool> RelaxELFRelocations(
-    "relax-elf-relocations",
-    cl::desc("Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
-    cl::init(false));
-
-static cl::opt<bool> DataSections("data-sections",
-                                  cl::desc("Emit data into separate sections"),
-                                  cl::init(false));
-
-static cl::opt<bool>
-    FunctionSections("function-sections",
-                     cl::desc("Emit functions into separate sections"),
-                     cl::init(false));
-
-static cl::opt<unsigned> TLSSize("tls-size",
-                                 cl::desc("Bit size of immediate TLS offsets"),
-                                 cl::init(0));
-
-static cl::opt<bool> EmulatedTLS("emulated-tls",
-                                 cl::desc("Use emulated TLS model"),
-                                 cl::init(false));
-
-static cl::opt<bool>
-    UniqueSectionNames("unique-section-names",
-                       cl::desc("Give unique names to every section"),
-                       cl::init(true));
-
-static cl::opt<llvm::EABI>
-    EABIVersion("meabi", cl::desc("Set EABI type (default depends on triple):"),
-                cl::init(EABI::Default),
-                cl::values(clEnumValN(EABI::Default, "default",
-                                      "Triple default EABI version"),
-                           clEnumValN(EABI::EABI4, "4", "EABI version 4"),
-                           clEnumValN(EABI::EABI5, "5", "EABI version 5"),
-                           clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
-
-static cl::opt<DebuggerKind> DebuggerTuningOpt(
-    "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
-    cl::init(DebuggerKind::Default),
-    cl::values(clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
-               clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
-               clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
-
-static cl::opt<bool> EnableStackSizeSection(
-    "stack-size-section",
-    cl::desc("Emit a section containing stack size metadata"), cl::init(false));
-
-static cl::opt<bool>
-    EnableAddrsig("addrsig", cl::desc("Emit an address-significance table"),
-                  cl::init(false));
-
-static cl::opt<bool>
-    EnableDebugEntryValues("debug-entry-values",
-                           cl::desc("Emit debug info about parameter's entry values"),
-                           cl::init(false));
-
-static cl::opt<bool>
-    ForceDwarfFrameSection("force-dwarf-frame-section",
-                           cl::desc("Always emit a debug frame section."),
-                           cl::init(false));
-
-// Common utility function tightly tied to the options listed here. Initializes
-// a TargetOptions object with CodeGen flags and returns it.
-static TargetOptions InitTargetOptionsFromCodeGenFlags() {
-  TargetOptions Options;
-  Options.AllowFPOpFusion = FuseFPOps;
-  Options.UnsafeFPMath = EnableUnsafeFPMath;
-  Options.NoInfsFPMath = EnableNoInfsFPMath;
-  Options.NoNaNsFPMath = EnableNoNaNsFPMath;
-  Options.NoSignedZerosFPMath = EnableNoSignedZerosFPMath;
-  Options.NoTrappingFPMath = EnableNoTrappingFPMath;
-  Options.FPDenormalMode = DenormalFPMath;
-  Options.HonorSignDependentRoundingFPMathOption =
-      EnableHonorSignDependentRoundingFPMath;
-  if (FloatABIForCalls != FloatABI::Default)
-    Options.FloatABIType = FloatABIForCalls;
-  Options.NoZerosInBSS = DontPlaceZerosInBSS;
-  Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
-  Options.StackAlignmentOverride = OverrideStackAlignment;
-  Options.StackSymbolOrdering = StackSymbolOrdering;
-  Options.UseInitArray = !UseCtors;
-  Options.RelaxELFRelocations = RelaxELFRelocations;
-  Options.DataSections = DataSections;
-  Options.FunctionSections = FunctionSections;
-  Options.UniqueSectionNames = UniqueSectionNames;
-  Options.TLSSize = TLSSize;
-  Options.EmulatedTLS = EmulatedTLS;
-  Options.ExplicitEmulatedTLS = EmulatedTLS.getNumOccurrences() > 0;
-  Options.ExceptionModel = ExceptionModel;
-  Options.EmitStackSizeSection = EnableStackSizeSection;
-  Options.EmitAddrsig = EnableAddrsig;
-  Options.EnableDebugEntryValues = EnableDebugEntryValues;
-  Options.ForceDwarfFrameSection = ForceDwarfFrameSection;
-
-  Options.MCOptions = InitMCTargetOptionsFromFlags();
-
-  Options.ThreadModel = TMModel;
-  Options.EABIVersion = EABIVersion;
-  Options.DebuggerTuning = DebuggerTuningOpt;
-
-  return Options;
-}
-
-LLVM_ATTRIBUTE_UNUSED static std::string getCPUStr() {
-  // If user asked for the 'native' CPU, autodetect here. If autodection fails,
-  // this will set the CPU to an empty string which tells the target to
-  // pick a basic default.
-  if (MCPU == "native") return std::string(sys::getHostCPUName());
-
-  return MCPU;
-}
-
-LLVM_ATTRIBUTE_UNUSED static std::string getFeaturesStr() {
-  SubtargetFeatures Features;
-
-  // If user asked for the 'native' CPU, we need to autodetect features.
-  // This is necessary for x86 where the CPU might not support all the
-  // features the autodetected CPU name lists in the target. For example,
-  // not all Sandybridge processors support AVX.
-  if (MCPU == "native") {
-    StringMap<bool> HostFeatures;
-    if (sys::getHostCPUFeatures(HostFeatures))
-      for (auto &F : HostFeatures)
-        Features.AddFeature(F.first(), F.second);
-  }
-
-  for (unsigned i = 0; i != MAttrs.size(); ++i)
-    Features.AddFeature(MAttrs[i]);
-
-  return Features.getString();
-}
-
-LLVM_ATTRIBUTE_UNUSED static std::vector<std::string> getFeatureList() {
-  SubtargetFeatures Features;
-
-  // If user asked for the 'native' CPU, we need to autodetect features.
-  // This is necessary for x86 where the CPU might not support all the
-  // features the autodetected CPU name lists in the target. For example,
-  // not all Sandybridge processors support AVX.
-  if (MCPU == "native") {
-    StringMap<bool> HostFeatures;
-    if (sys::getHostCPUFeatures(HostFeatures))
-      for (auto &F : HostFeatures)
-        Features.AddFeature(F.first(), F.second);
-  }
-
-  for (unsigned i = 0; i != MAttrs.size(); ++i)
-    Features.AddFeature(MAttrs[i]);
-
-  return Features.getFeatures();
-}
-
-static void renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
-  B.addAttribute(Name, Val ? "true" : "false");
-}
-
-#define HANDLE_BOOL_ATTR(CL, AttrName)                              \
-  do {                                                              \
-    if (CL.getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName))  \
-      renderBoolStringAttr(NewAttrs, AttrName, CL);                 \
-  } while (0)
-
-
-/// Set function attributes of function \p F based on CPU, Features, and command
-/// line flags.
-LLVM_ATTRIBUTE_UNUSED static void
-setFunctionAttributes(StringRef CPU, StringRef Features, Function &F) {
-  auto &Ctx = F.getContext();
-  AttributeList Attrs = F.getAttributes();
-  AttrBuilder NewAttrs;
-
-  if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
-    NewAttrs.addAttribute("target-cpu", CPU);
-  if (!Features.empty()) {
-    // Append the command line features to any that are already on the function.
-    StringRef OldFeatures
-      = F.getFnAttribute("target-features").getValueAsString();
-    if (OldFeatures.empty())
-      NewAttrs.addAttribute("target-features", Features);
-    else {
-      SmallString<256> Appended(OldFeatures);
-      Appended.push_back(',');
-      Appended.append(Features);
-      NewAttrs.addAttribute("target-features", Appended);
-    }
-  }
-  if (FramePointerUsage.getNumOccurrences() > 0 &&
-      !F.hasFnAttribute("frame-pointer")) {
-    if (FramePointerUsage == llvm::FramePointer::All)
-      NewAttrs.addAttribute("frame-pointer", "all");
-    else if (FramePointerUsage == llvm::FramePointer::NonLeaf)
-      NewAttrs.addAttribute("frame-pointer", "non-leaf");
-    else if (FramePointerUsage == llvm::FramePointer::None)
-      NewAttrs.addAttribute("frame-pointer", "none");
-  }
-  if (DisableTailCalls.getNumOccurrences() > 0)
-    NewAttrs.addAttribute("disable-tail-calls",
-                          toStringRef(DisableTailCalls));
-  if (StackRealign)
-    NewAttrs.addAttribute("stackrealign");
-
-  HANDLE_BOOL_ATTR(EnableUnsafeFPMath, "unsafe-fp-math");
-  HANDLE_BOOL_ATTR(EnableNoInfsFPMath, "no-infs-fp-math");
-  HANDLE_BOOL_ATTR(EnableNoNaNsFPMath, "no-nans-fp-math");
-  HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMath, "no-signed-zeros-fp-math");
-
-  if (TrapFuncName.getNumOccurrences() > 0)
-    for (auto &B : F)
-      for (auto &I : B)
-        if (auto *Call = dyn_cast<CallInst>(&I))
-          if (const auto *F = Call->getCalledFunction())
-            if (F->getIntrinsicID() == Intrinsic::debugtrap ||
-                F->getIntrinsicID() == Intrinsic::trap)
-              Call->addAttribute(
-                llvm::AttributeList::FunctionIndex,
-                Attribute::get(Ctx, "trap-func-name", TrapFuncName));
-
-  // Let NewAttrs override Attrs.
-  F.setAttributes(
-    Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
-}
-
-/// Set function attributes of functions in Module M based on CPU,
-/// Features, and command line flags.
-LLVM_ATTRIBUTE_UNUSED static void
-setFunctionAttributes(StringRef CPU, StringRef Features, Module &M) {
-  for (Function &F : M)
-    setFunctionAttributes(CPU, Features, F);
-}
Index: llvm/include/llvm/CodeGen/CommandFlags.h
===================================================================
--- /dev/null
+++ llvm/include/llvm/CodeGen/CommandFlags.h
@@ -0,0 +1,124 @@
+//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains codegen-specific flags that are shared between different
+// command line tools. The tools "llc" and "opt" both use this file to prevent
+// flag duplication.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include <string>
+
+namespace llvm {
+
+namespace codegen {
+
+std::string getMArch();
+std::string getMCPU();
+std::vector<std::string> getMAttrs();
+Optional<Reloc::Model> getRelocModel();
+ThreadModel::Model getTMModel();
+
+Optional<CodeModel::Model> getCodeModel();
+
+llvm::ExceptionHandling getExceptionModel();
+
+CodeGenFileType getFileType();
+
+llvm::FramePointer::FP getFramePointerUsage();
+
+bool getEnableUnsafeFPMath();
+
+bool getEnableNoInfsFPMath();
+
+bool getEnableNoNaNsFPMath();
+
+bool getEnableNoSignedZerosFPMath();
+
+bool getEnableNoTrappingFPMath();
+
+llvm::FPDenormal::DenormalMode getDenormalFPMath();
+
+bool getEnableHonorSignDependentRoundingFPMath();
+
+llvm::FloatABI::ABIType getFloatABIForCalls();
+
+llvm::FPOpFusion::FPOpFusionMode getFuseFPOps();
+
+bool getDontPlaceZerosInBSS();
+
+bool getEnableGuaranteedTailCallOpt();
+
+bool getDisableTailCalls();
+
+bool getStackSymbolOrdering();
+
+unsigned getOverrideStackAlignment();
+
+bool getStackRealign();
+
+std::string getTrapFuncName();
+
+bool getUseCtors();
+
+bool getRelaxELFRelocations();
+
+bool getDataSections();
+
+bool getFunctionSections();
+
+unsigned getTLSSize();
+
+bool getEmulatedTLS();
+
+bool getUniqueSectionNames();
+
+llvm::EABI getEABIVersion();
+
+llvm::DebuggerKind getDebuggerTuningOpt();
+
+bool getEnableStackSizeSection();
+
+bool getEnableAddrsig();
+
+bool getEnableDebugEntryValues();
+
+bool getForceDwarfFrameSection();
+
+// Common utility function tightly tied to the options listed here. Initializes
+// a TargetOptions object with CodeGen flags and returns it.
+TargetOptions InitTargetOptionsFromCodeGenFlags();
+
+std::string getCPUStr();
+
+std::string getFeaturesStr();
+
+std::vector<std::string> getFeatureList();
+
+void renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val);
+
+/// Set function attributes of function \p F based on CPU, Features, and command
+/// line flags.
+void setFunctionAttributes(StringRef CPU, StringRef Features, Function &F);
+
+/// Set function attributes of functions in Module M based on CPU,
+/// Features, and command line flags.
+void setFunctionAttributes(StringRef CPU, StringRef Features, Module &M);
+} // namespace codegen
+} // namespace llvm
Index: lld/Common/TargetOptionsCommandFlags.cpp
===================================================================
--- lld/Common/TargetOptionsCommandFlags.cpp
+++ lld/Common/TargetOptionsCommandFlags.cpp
@@ -15,7 +15,7 @@
 
 #include "lld/Common/TargetOptionsCommandFlags.h"
 
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/Target/TargetOptions.h"
 
 // Define an externally visible version of
@@ -23,17 +23,17 @@
 // used without having to include llvm/CodeGen/CommandFlags.inc, which
 // would lead to multiple definitions of the command line flags.
 llvm::TargetOptions lld::initTargetOptionsFromCodeGenFlags() {
-  return ::InitTargetOptionsFromCodeGenFlags();
+  return llvm::codegen::InitTargetOptionsFromCodeGenFlags();
 }
 
 llvm::Optional<llvm::Reloc::Model> lld::getRelocModelFromCMModel() {
-  return getRelocModel();
+  return llvm::codegen::getRelocModel();
 }
 
 llvm::Optional<llvm::CodeModel::Model> lld::getCodeModelFromCMModel() {
-  return getCodeModel();
+  return llvm::codegen::getCodeModel();
 }
 
-std::string lld::getCPUStr() { return ::getCPUStr(); }
+std::string lld::getCPUStr() { return llvm::codegen::getCPUStr(); }
 
-std::vector<std::string> lld::getMAttrs() { return ::MAttrs; }
+std::vector<std::string> lld::getMAttrs() { return llvm::codegen::getMAttrs(); }
Index: lld/Common/CMakeLists.txt
===================================================================
--- lld/Common/CMakeLists.txt
+++ lld/Common/CMakeLists.txt
@@ -56,6 +56,7 @@
 
   LINK_LIBS
   ${LLVM_PTHREAD_LIB}
+  LLVMCodeGenCommandFlags
 
   DEPENDS
   ${tablegen_deps}
Index: clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
===================================================================
--- clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
+++ clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
@@ -19,7 +19,7 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/ExecutionEngine/JITEventListener.h"
@@ -29,9 +29,9 @@
 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
 #include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/LegacyPassNameParser.h"
-#include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/IRReader/IRReader.h"
@@ -42,8 +42,8 @@
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/Transforms/Vectorize.h"
 
 using namespace llvm;
@@ -100,15 +100,18 @@
     ErrorAndExit("Could not parse IR");
 
   Triple ModuleTriple(M->getTargetTriple());
-  const TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  const TargetOptions Options =
+      llvm::codegen::InitTargetOptionsFromCodeGenFlags();
   std::string E;
-  const Target *TheTarget = TargetRegistry::lookupTarget(MArch, ModuleTriple, E);
-  TargetMachine *Machine =
-      TheTarget->createTargetMachine(M->getTargetTriple(), getCPUStr(),
-                                     getFeaturesStr(), Options, getRelocModel(),
-                                     getCodeModel(), OLvl);
+  const Target *TheTarget =
+      TargetRegistry::lookupTarget(llvm::codegen::getMArch(), ModuleTriple, E);
+  TargetMachine *Machine = TheTarget->createTargetMachine(
+      M->getTargetTriple(), llvm::codegen::getCPUStr(),
+      llvm::codegen::getFeaturesStr(), Options, llvm::codegen::getRelocModel(),
+      llvm::codegen::getCodeModel(), OLvl);
   std::unique_ptr<TargetMachine> TM(Machine);
-  setFunctionAttributes(getCPUStr(), getFeaturesStr(), *M);
+  llvm::codegen::setFunctionAttributes(llvm::codegen::getCPUStr(),
+                                       llvm::codegen::getFeaturesStr(), *M);
 
   legacy::PassManager Passes;
   
@@ -154,14 +157,14 @@
 
   std::string ErrorMsg;
   EngineBuilder builder(std::move(M));
-  builder.setMArch(MArch);
-  builder.setMCPU(getCPUStr());
-  builder.setMAttrs(getFeatureList());
+  builder.setMArch(llvm::codegen::getMArch());
+  builder.setMCPU(llvm::codegen::getCPUStr());
+  builder.setMAttrs(llvm::codegen::getFeatureList());
   builder.setErrorStr(&ErrorMsg);
   builder.setEngineKind(EngineKind::JIT);
   builder.setMCJITMemoryManager(std::make_unique<SectionMemoryManager>());
   builder.setOptLevel(OLvl);
-  builder.setTargetOptions(InitTargetOptionsFromCodeGenFlags());
+  builder.setTargetOptions(llvm::codegen::InitTargetOptionsFromCodeGenFlags());
 
   std::unique_ptr<ExecutionEngine> EE(builder.create());
   if (!EE)
Index: clang/tools/clang-fuzzer/handle-llvm/CMakeLists.txt
===================================================================
--- clang/tools/clang-fuzzer/handle-llvm/CMakeLists.txt
+++ clang/tools/clang-fuzzer/handle-llvm/CMakeLists.txt
@@ -27,4 +27,8 @@
 
   DEPENDS
   ${handle_llvm_deps}
+
+  LINK_LIBS
+
+  LLVMCodeGenCommandFlags
   )
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to