//===-- CommandFlags.cpp - 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"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/TargetParser/Triple.h"
#include <cassert>
#include <memory>
#include <optional>
#include <system_error>

using namespace llvm;

#define CGOPT(TY, NAME)                                                        \
  static cl::opt<TY> *NAME##View;                                              \
  TY codegen::get##NAME() {                                                    \
    assert(NAME##View && "Flag not registered.");                              \
    return *NAME##View;                                                        \
  }

#define CGLIST(TY, NAME)                                                       \
  static cl::list<TY> *NAME##View;                                             \
  std::vector<TY> codegen::get##NAME() {                                       \
    assert(NAME##View && "Flag not registered.");                              \
    return *NAME##View;                                                        \
  }

// Temporary macro for incremental transition to std::optional.
#define CGOPT_EXP(TY, NAME)                                                    \
  CGOPT(TY, NAME)                                                              \
  std::optional<TY> codegen::getExplicit##NAME() {                             \
    if (NAME##View->getNumOccurrences()) {                                     \
      TY res = *NAME##View;                                                    \
      return res;                                                              \
    }                                                                          \
    return std::nullopt;                                                       \
  }

CGOPT(std::string, MArch)
CGOPT(std::string, MCPU)
CGOPT(std::string, MTune)
CGLIST(std::string, MAttrs)
CGOPT_EXP(Reloc::Model, RelocModel)
CGOPT(ThreadModel::Model, ThreadModel)
CGOPT_EXP(CodeModel::Model, CodeModel)
CGOPT_EXP(uint64_t, LargeDataThreshold)
CGOPT(ExceptionHandling, ExceptionModel)
CGOPT_EXP(CodeGenFileType, FileType)
CGOPT(FramePointerKind, FramePointerUsage)
CGOPT(bool, EnableNoTrappingFPMath)
CGOPT(bool, EnableAIXExtendedAltivecABI)
CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath)
CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)
CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
CGOPT(FloatABI::ABIType, FloatABIForCalls)
CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)
CGOPT(SwiftAsyncFramePointerMode, SwiftAsyncFramePointer)
CGOPT(bool, DontPlaceZerosInBSS)
CGOPT(bool, EnableGuaranteedTailCallOpt)
CGOPT(bool, DisableTailCalls)
CGOPT(bool, StackSymbolOrdering)
CGOPT(bool, StackRealign)
CGOPT(std::string, TrapFuncName)
CGOPT(bool, UseCtors)
CGOPT(bool, DisableIntegratedAS)
CGOPT_EXP(bool, DataSections)
CGOPT_EXP(bool, FunctionSections)
CGOPT(bool, IgnoreXCOFFVisibility)
CGOPT(bool, XCOFFTracebackTable)
CGOPT(bool, EnableBBAddrMap)
CGOPT(std::string, BBSections)
CGOPT(unsigned, TLSSize)
CGOPT_EXP(bool, EmulatedTLS)
CGOPT_EXP(bool, EnableTLSDESC)
CGOPT(bool, UniqueSectionNames)
CGOPT(bool, UniqueBasicBlockSectionNames)
CGOPT(bool, SeparateNamedSections)
CGOPT(EABI, EABIVersion)
CGOPT(DebuggerKind, DebuggerTuningOpt)
CGOPT(VectorLibrary, VectorLibrary)
CGOPT(bool, EnableStackSizeSection)
CGOPT(bool, EnableAddrsig)
CGOPT(bool, EnableCallGraphSection)
CGOPT(bool, EmitCallSiteInfo)
CGOPT(bool, EnableMachineFunctionSplitter)
CGOPT(bool, EnableStaticDataPartitioning)
CGOPT(bool, EnableDebugEntryValues)
CGOPT(bool, ForceDwarfFrameSection)
CGOPT(bool, XRayFunctionIndex)
CGOPT(bool, DebugStrictDwarf)
CGOPT(unsigned, AlignLoops)
CGOPT(bool, JMCInstrument)
CGOPT(bool, XCOFFReadOnlyPointers)
CGOPT(codegen::SaveStatsMode, SaveStats)

#define CGBINDOPT(NAME)                                                        \
  do {                                                                         \
    NAME##View = std::addressof(NAME);                                         \
  } while (0)

codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
  static cl::opt<std::string> MArch(
      "march", cl::desc("Architecture to generate code for (see --version)"));
  CGBINDOPT(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(""));
  CGBINDOPT(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,..."));
  CGBINDOPT(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")));
  CGBINDOPT(RelocModel);

  static cl::opt<ThreadModel::Model> ThreadModel(
      "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")));
  CGBINDOPT(ThreadModel);

  static cl::opt<CodeModel::Model> CodeModel(
      "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")));
  CGBINDOPT(CodeModel);

  static cl::opt<uint64_t> LargeDataThreshold(
      "large-data-threshold",
      cl::desc("Choose large data threshold for x86_64 medium code model"),
      cl::init(0));
  CGBINDOPT(LargeDataThreshold);

  static cl::opt<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")));
  CGBINDOPT(ExceptionModel);

  static cl::opt<CodeGenFileType> FileType(
      "filetype", cl::init(CodeGenFileType::AssemblyFile),
      cl::desc(
          "Choose a file type (not all types are supported by all targets):"),
      cl::values(clEnumValN(CodeGenFileType::AssemblyFile, "asm",
                            "Emit an assembly ('.s') file"),
                 clEnumValN(CodeGenFileType::ObjectFile, "obj",
                            "Emit a native object ('.o') file"),
                 clEnumValN(CodeGenFileType::Null, "null",
                            "Emit nothing, for performance testing")));
  CGBINDOPT(FileType);

  static cl::opt<FramePointerKind> FramePointerUsage(
      "frame-pointer",
      cl::desc("Specify frame pointer elimination optimization"),
      cl::init(FramePointerKind::None),
      cl::values(
          clEnumValN(FramePointerKind::All, "all",
                     "Disable frame pointer elimination"),
          clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
                     "Disable frame pointer elimination for non-leaf frame but "
                     "reserve the register in leaf functions"),
          clEnumValN(FramePointerKind::NonLeafNoReserve, "non-leaf-no-reserve",
                     "Disable frame pointer elimination for non-leaf frame"),
          clEnumValN(FramePointerKind::Reserved, "reserved",
                     "Enable frame pointer elimination, but reserve the frame "
                     "pointer register"),
          clEnumValN(FramePointerKind::None, "none",
                     "Enable frame pointer elimination")));
  CGBINDOPT(FramePointerUsage);

  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));
  CGBINDOPT(EnableNoTrappingFPMath);

  static const auto DenormFlagEnumOptions = cl::values(
      clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"),
      clEnumValN(DenormalMode::PreserveSign, "preserve-sign",
                 "the sign of a  flushed-to-zero number is preserved "
                 "in the sign of 0"),
      clEnumValN(DenormalMode::PositiveZero, "positive-zero",
                 "denormals are flushed to positive zero"),
      clEnumValN(DenormalMode::Dynamic, "dynamic",
                 "denormals have unknown treatment"));

  // FIXME: Doesn't have way to specify separate input and output modes.
  static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath(
    "denormal-fp-math",
    cl::desc("Select which denormal numbers the code is permitted to require"),
    cl::init(DenormalMode::IEEE),
    DenormFlagEnumOptions);
  CGBINDOPT(DenormalFPMath);

  static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math(
    "denormal-fp-math-f32",
    cl::desc("Select which denormal numbers the code is permitted to require for float"),
    cl::init(DenormalMode::Invalid),
    DenormFlagEnumOptions);
  CGBINDOPT(DenormalFP32Math);

  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));
  CGBINDOPT(EnableHonorSignDependentRoundingFPMath);

  static cl::opt<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)")));
  CGBINDOPT(FloatABIForCalls);

  static cl::opt<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.")));
  CGBINDOPT(FuseFPOps);

  static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer(
      "swift-async-fp",
      cl::desc("Determine when the Swift async frame pointer should be set"),
      cl::init(SwiftAsyncFramePointerMode::Always),
      cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto",
                            "Determine based on deployment target"),
                 clEnumValN(SwiftAsyncFramePointerMode::Always, "always",
                            "Always set the bit"),
                 clEnumValN(SwiftAsyncFramePointerMode::Never, "never",
                            "Never set the bit")));
  CGBINDOPT(SwiftAsyncFramePointer);

  static cl::opt<bool> DontPlaceZerosInBSS(
      "nozero-initialized-in-bss",
      cl::desc("Don't place zero-initialized symbols into bss section"),
      cl::init(false));
  CGBINDOPT(DontPlaceZerosInBSS);

  static cl::opt<bool> EnableAIXExtendedAltivecABI(
      "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),
      cl::init(false));
  CGBINDOPT(EnableAIXExtendedAltivecABI);

  static cl::opt<bool> EnableGuaranteedTailCallOpt(
      "tailcallopt",
      cl::desc(
          "Turn fastcc calls into tail calls by (potentially) changing ABI."),
      cl::init(false));
  CGBINDOPT(EnableGuaranteedTailCallOpt);

  static cl::opt<bool> DisableTailCalls(
      "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false));
  CGBINDOPT(DisableTailCalls);

  static cl::opt<bool> StackSymbolOrdering(
      "stack-symbol-ordering", cl::desc("Order local stack symbols."),
      cl::init(true));
  CGBINDOPT(StackSymbolOrdering);

  static cl::opt<bool> StackRealign(
      "stackrealign",
      cl::desc("Force align the stack to the minimum alignment"),
      cl::init(false));
  CGBINDOPT(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(""));
  CGBINDOPT(TrapFuncName);

  static cl::opt<bool> UseCtors("use-ctors",
                                cl::desc("Use .ctors instead of .init_array."),
                                cl::init(false));
  CGBINDOPT(UseCtors);

  static cl::opt<bool> DataSections(
      "data-sections", cl::desc("Emit data into separate sections"),
      cl::init(false));
  CGBINDOPT(DataSections);

  static cl::opt<bool> FunctionSections(
      "function-sections", cl::desc("Emit functions into separate sections"),
      cl::init(false));
  CGBINDOPT(FunctionSections);

  static cl::opt<bool> IgnoreXCOFFVisibility(
      "ignore-xcoff-visibility",
      cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
               "all symbols 'unspecified' visibility in XCOFF object file"),
      cl::init(false));
  CGBINDOPT(IgnoreXCOFFVisibility);

  static cl::opt<bool> XCOFFTracebackTable(
      "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
      cl::init(true));
  CGBINDOPT(XCOFFTracebackTable);

  static cl::opt<bool> EnableBBAddrMap(
      "basic-block-address-map",
      cl::desc("Emit the basic block address map section"), cl::init(false));
  CGBINDOPT(EnableBBAddrMap);

  static cl::opt<std::string> BBSections(
      "basic-block-sections",
      cl::desc("Emit basic blocks into separate sections"),
      cl::value_desc("all | <function list (file)> | labels | none"),
      cl::init("none"));
  CGBINDOPT(BBSections);

  static cl::opt<unsigned> TLSSize(
      "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
  CGBINDOPT(TLSSize);

  static cl::opt<bool> EmulatedTLS(
      "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
  CGBINDOPT(EmulatedTLS);

  static cl::opt<bool> EnableTLSDESC(
      "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"),
      cl::init(false));
  CGBINDOPT(EnableTLSDESC);

  static cl::opt<bool> UniqueSectionNames(
      "unique-section-names", cl::desc("Give unique names to every section"),
      cl::init(true));
  CGBINDOPT(UniqueSectionNames);

  static cl::opt<bool> UniqueBasicBlockSectionNames(
      "unique-basic-block-section-names",
      cl::desc("Give unique names to every basic block section"),
      cl::init(false));
  CGBINDOPT(UniqueBasicBlockSectionNames);

  static cl::opt<bool> SeparateNamedSections(
      "separate-named-sections",
      cl::desc("Use separate unique sections for named sections"),
      cl::init(false));
  CGBINDOPT(SeparateNamedSections);

  static cl::opt<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")));
  CGBINDOPT(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::DBX, "dbx", "dbx"),
          clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
  CGBINDOPT(DebuggerTuningOpt);

  static cl::opt<VectorLibrary> VectorLibrary(
      "vector-library", cl::Hidden, cl::desc("Vector functions library"),
      cl::init(VectorLibrary::NoLibrary),
      cl::values(
          clEnumValN(VectorLibrary::NoLibrary, "none",
                     "No vector functions library"),
          clEnumValN(VectorLibrary::Accelerate, "Accelerate",
                     "Accelerate framework"),
          clEnumValN(VectorLibrary::DarwinLibSystemM, "Darwin_libsystem_m",
                     "Darwin libsystem_m"),
          clEnumValN(VectorLibrary::LIBMVEC, "LIBMVEC",
                     "GLIBC Vector Math library"),
          clEnumValN(VectorLibrary::MASSV, "MASSV", "IBM MASS vector library"),
          clEnumValN(VectorLibrary::SVML, "SVML", "Intel SVML library"),
          clEnumValN(VectorLibrary::SLEEFGNUABI, "sleefgnuabi",
                     "SIMD Library for Evaluating Elementary Functions"),
          clEnumValN(VectorLibrary::ArmPL, "ArmPL",
                     "Arm Performance Libraries"),
          clEnumValN(VectorLibrary::AMDLIBM, "AMDLIBM",
                     "AMD vector math library")));
  CGBINDOPT(VectorLibrary);

  static cl::opt<bool> EnableStackSizeSection(
      "stack-size-section",
      cl::desc("Emit a section containing stack size metadata"),
      cl::init(false));
  CGBINDOPT(EnableStackSizeSection);

  static cl::opt<bool> EnableAddrsig(
      "addrsig", cl::desc("Emit an address-significance table"),
      cl::init(false));
  CGBINDOPT(EnableAddrsig);

  static cl::opt<bool> EnableCallGraphSection(
      "call-graph-section", cl::desc("Emit a call graph section"),
      cl::init(false));
  CGBINDOPT(EnableCallGraphSection);

  static cl::opt<bool> EmitCallSiteInfo(
      "emit-call-site-info",
      cl::desc(
          "Emit call site debug information, if debug information is enabled."),
      cl::init(false));
  CGBINDOPT(EmitCallSiteInfo);

  static cl::opt<bool> EnableDebugEntryValues(
      "debug-entry-values",
      cl::desc("Enable debug info for the debug entry values."),
      cl::init(false));
  CGBINDOPT(EnableDebugEntryValues);

  static cl::opt<bool> EnableMachineFunctionSplitter(
      "split-machine-functions",
      cl::desc("Split out cold basic blocks from machine functions based on "
               "profile information"),
      cl::init(false));
  CGBINDOPT(EnableMachineFunctionSplitter);

  static cl::opt<bool> EnableStaticDataPartitioning(
      "partition-static-data-sections",
      cl::desc("Partition data sections using profile information."),
      cl::init(false));
  CGBINDOPT(EnableStaticDataPartitioning);

  static cl::opt<bool> ForceDwarfFrameSection(
      "force-dwarf-frame-section",
      cl::desc("Always emit a debug frame section."), cl::init(false));
  CGBINDOPT(ForceDwarfFrameSection);

  static cl::opt<bool> XRayFunctionIndex("xray-function-index",
                                         cl::desc("Emit xray_fn_idx section"),
                                         cl::init(true));
  CGBINDOPT(XRayFunctionIndex);

  static cl::opt<bool> DebugStrictDwarf(
      "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false));
  CGBINDOPT(DebugStrictDwarf);

  static cl::opt<unsigned> AlignLoops("align-loops",
                                      cl::desc("Default alignment for loops"));
  CGBINDOPT(AlignLoops);

  static cl::opt<bool> JMCInstrument(
      "enable-jmc-instrument",
      cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"),
      cl::init(false));
  CGBINDOPT(JMCInstrument);

  static cl::opt<bool> XCOFFReadOnlyPointers(
      "mxcoff-roptr",
      cl::desc("When set to true, const objects with relocatable address "
               "values are put into the RO data section."),
      cl::init(false));
  CGBINDOPT(XCOFFReadOnlyPointers);

  static cl::opt<bool> DisableIntegratedAS(
      "no-integrated-as", cl::desc("Disable integrated assembler"),
      cl::init(false));
  CGBINDOPT(DisableIntegratedAS);

  mc::RegisterMCTargetOptionsFlags();
}

codegen::RegisterMTuneFlag::RegisterMTuneFlag() {
  static cl::opt<std::string> MTune(
      "mtune",
      cl::desc("Tune for a specific CPU microarchitecture (-mtune=help for "
               "details)"),
      cl::value_desc("tune-cpu-name"), cl::init(""));
  CGBINDOPT(MTune);
}

codegen::RegisterSaveStatsFlag::RegisterSaveStatsFlag() {
  static cl::opt<SaveStatsMode> SaveStats(
      "save-stats",
      cl::desc(
          "Save LLVM statistics to a file in the current directory"
          "(`-save-stats`/`-save-stats=cwd`) or the directory of the output"
          "file (`-save-stats=obj`). (default: cwd)"),
      cl::values(clEnumValN(SaveStatsMode::Cwd, "cwd",
                            "Save to the current working directory"),
                 clEnumValN(SaveStatsMode::Cwd, "", ""),
                 clEnumValN(SaveStatsMode::Obj, "obj",
                            "Save to the output file directory")),
      cl::init(SaveStatsMode::None), cl::ValueOptional);
  CGBINDOPT(SaveStats);
}

llvm::BasicBlockSection
codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
  if (getBBSections() == "all")
    return BasicBlockSection::All;
  else if (getBBSections() == "none")
    return BasicBlockSection::None;
  else {
    ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
        MemoryBuffer::getFile(getBBSections());
    if (!MBOrErr) {
      errs() << "Error loading basic block sections function list file: "
             << MBOrErr.getError().message() << "\n";
    } else {
      Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
    }
    return BasicBlockSection::List;
  }
}

// Common utility function tightly tied to the options listed here. Initializes
// a TargetOptions object with CodeGen flags and returns it.
TargetOptions
codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
  TargetOptions Options;
  Options.AllowFPOpFusion = getFuseFPOps();
  Options.NoTrappingFPMath = getEnableNoTrappingFPMath();

  Options.HonorSignDependentRoundingFPMathOption =
      getEnableHonorSignDependentRoundingFPMath();
  if (getFloatABIForCalls() != FloatABI::Default)
    Options.FloatABIType = getFloatABIForCalls();
  Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();
  Options.NoZerosInBSS = getDontPlaceZerosInBSS();
  Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();
  Options.StackSymbolOrdering = getStackSymbolOrdering();
  Options.UseInitArray = !getUseCtors();
  Options.DisableIntegratedAS = getDisableIntegratedAS();
  Options.DataSections =
      getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections());
  Options.FunctionSections = getFunctionSections();
  Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
  Options.XCOFFTracebackTable = getXCOFFTracebackTable();
  Options.BBAddrMap = getEnableBBAddrMap();
  Options.BBSections = getBBSectionsMode(Options);
  Options.UniqueSectionNames = getUniqueSectionNames();
  Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
  Options.SeparateNamedSections = getSeparateNamedSections();
  Options.TLSSize = getTLSSize();
  Options.EmulatedTLS =
      getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS());
  Options.EnableTLSDESC =
      getExplicitEnableTLSDESC().value_or(TheTriple.hasDefaultTLSDESC());
  Options.ExceptionModel = getExceptionModel();
  Options.VecLib = getVectorLibrary();
  Options.EmitStackSizeSection = getEnableStackSizeSection();
  Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
  Options.EnableStaticDataPartitioning = getEnableStaticDataPartitioning();
  Options.EmitAddrsig = getEnableAddrsig();
  Options.EmitCallGraphSection = getEnableCallGraphSection();
  Options.EmitCallSiteInfo = getEmitCallSiteInfo();
  Options.EnableDebugEntryValues = getEnableDebugEntryValues();
  Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
  Options.XRayFunctionIndex = getXRayFunctionIndex();
  Options.DebugStrictDwarf = getDebugStrictDwarf();
  Options.LoopAlignment = getAlignLoops();
  Options.JMCInstrument = getJMCInstrument();
  Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers();

  Options.MCOptions = mc::InitMCTargetOptionsFromFlags();

  Options.ThreadModel = getThreadModel();
  Options.EABIVersion = getEABIVersion();
  Options.DebuggerTuning = getDebuggerTuningOpt();
  Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer();
  return Options;
}

std::string codegen::getCPUStr() {
  std::string MCPU = getMCPU();

  // If user asked for the 'native' CPU, autodetect here. If auto-detection
  // 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 codegen::getTuneCPUStr() {
  std::string TuneCPU = getMTune();

  // If user asked for the 'native' tune CPU, autodetect here. If auto-detection
  // fails, this will set the tune CPU to an empty string which tells the target
  // to pick a basic default.
  if (TuneCPU == "native")
    return std::string(sys::getHostCPUName());

  return TuneCPU;
}

std::string 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 (getMCPU() == "native")
    for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())
      Features.AddFeature(Feature, IsEnabled);

  for (auto const &MAttr : getMAttrs())
    Features.AddFeature(MAttr);

  return Features.getString();
}

std::vector<std::string> 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 (getMCPU() == "native")
    for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())
      Features.AddFeature(Feature, IsEnabled);

  for (auto const &MAttr : getMAttrs())
    Features.AddFeature(MAttr);

  return Features.getFeatures();
}

void 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)

void codegen::setFunctionAttributes(Function &F, StringRef CPU,
                                    StringRef Features, StringRef TuneCPU) {
  auto &Ctx = F.getContext();
  AttributeList Attrs = F.getAttributes();
  AttrBuilder NewAttrs(Ctx);

  if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
    NewAttrs.addAttribute("target-cpu", CPU);
  if (!TuneCPU.empty() && !F.hasFnAttribute("tune-cpu"))
    NewAttrs.addAttribute("tune-cpu", TuneCPU);
  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 (FramePointerUsageView->getNumOccurrences() > 0 &&
      !F.hasFnAttribute("frame-pointer")) {
    if (getFramePointerUsage() == FramePointerKind::All)
      NewAttrs.addAttribute("frame-pointer", "all");
    else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
      NewAttrs.addAttribute("frame-pointer", "non-leaf");
    else if (getFramePointerUsage() == FramePointerKind::NonLeafNoReserve)
      NewAttrs.addAttribute("frame-pointer", "non-leaf-no-reserve");
    else if (getFramePointerUsage() == FramePointerKind::Reserved)
      NewAttrs.addAttribute("frame-pointer", "reserved");
    else if (getFramePointerUsage() == FramePointerKind::None)
      NewAttrs.addAttribute("frame-pointer", "none");
  }
  if (DisableTailCallsView->getNumOccurrences() > 0)
    NewAttrs.addAttribute("disable-tail-calls",
                          toStringRef(getDisableTailCalls()));
  if (getStackRealign())
    NewAttrs.addAttribute("stackrealign");

  if ((DenormalFPMathView->getNumOccurrences() > 0 ||
       DenormalFP32MathView->getNumOccurrences() > 0) &&
      !F.hasFnAttribute(Attribute::DenormalFPEnv)) {
    DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
    DenormalMode::DenormalModeKind DenormKindF32 = getDenormalFP32Math();

    DenormalFPEnv FPEnv(DenormalMode{DenormKind, DenormKind},
                        DenormalMode{DenormKindF32, DenormKindF32});
    // FIXME: Command line flag should expose separate input/output modes.
    NewAttrs.addDenormalFPEnvAttr(FPEnv);
  }

  if (TrapFuncNameView->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->addFnAttr(
                  Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));

  // Let NewAttrs override Attrs.
  F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs));
}

void codegen::setFunctionAttributes(Module &M, StringRef CPU,
                                    StringRef Features, StringRef TuneCPU) {
  for (Function &F : M)
    setFunctionAttributes(F, CPU, Features, TuneCPU);
}

Expected<std::unique_ptr<TargetMachine>>
codegen::createTargetMachineForTriple(const Triple &TargetTriple,
                                      CodeGenOptLevel OptLevel) {
  // lookupTarget may mutate the triple, so we need a copy.
  Triple TheTriple(TargetTriple);
  std::string Error;
  const auto *TheTarget =
      TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
  if (!TheTarget)
    return createStringError(inconvertibleErrorCode(), Error);
  auto *Target = TheTarget->createTargetMachine(
      TheTriple, codegen::getCPUStr(), codegen::getFeaturesStr(),
      codegen::InitTargetOptionsFromCodeGenFlags(TheTriple),
      codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(),
      OptLevel);
  if (!Target)
    return createStringError(inconvertibleErrorCode(),
                             Twine("could not allocate target machine for ") +
                                 TheTriple.str());
  return std::unique_ptr<TargetMachine>(Target);
}

Expected<std::unique_ptr<TargetMachine>>
codegen::createTargetMachineForTriple(StringRef TargetTriple,
                                      CodeGenOptLevel OptLevel) {
  return createTargetMachineForTriple(Triple(TargetTriple), OptLevel);
}

void codegen::MaybeEnableStatistics() {
  if (getSaveStats() == SaveStatsMode::None)
    return;

  llvm::EnableStatistics(false);
}

int codegen::MaybeSaveStatistics(StringRef OutputFilename, StringRef ToolName) {
  auto SaveStatsValue = getSaveStats();
  if (SaveStatsValue == codegen::SaveStatsMode::None)
    return 0;

  SmallString<128> StatsFilename;
  if (SaveStatsValue == codegen::SaveStatsMode::Obj) {
    StatsFilename = OutputFilename;
    llvm::sys::path::remove_filename(StatsFilename);
  } else {
    assert(SaveStatsValue == codegen::SaveStatsMode::Cwd &&
           "Should have been a valid --save-stats value");
  }

  auto BaseName = llvm::sys::path::filename(OutputFilename);
  llvm::sys::path::append(StatsFilename, BaseName);
  llvm::sys::path::replace_extension(StatsFilename, "stats");

  auto FileFlags = llvm::sys::fs::OF_TextWithCRLF;
  std::error_code EC;
  auto StatsOS =
      std::make_unique<llvm::raw_fd_ostream>(StatsFilename, EC, FileFlags);
  if (EC) {
    WithColor::error(errs(), ToolName)
        << "Unable to open statistics file: " << EC.message() << "\n";
    return 1;
  }

  llvm::PrintStatisticsJSON(*StatsOS);
  return 0;
}
