xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/CommandFlags.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15ffd83dbSDimitry Andric //===-- CommandFlags.cpp - Command Line Flags Interface ---------*- C++ -*-===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric //
95ffd83dbSDimitry Andric // This file contains codegen-specific flags that are shared between different
105ffd83dbSDimitry Andric // command line tools. The tools "llc" and "opt" both use this file to prevent
115ffd83dbSDimitry Andric // flag duplication.
125ffd83dbSDimitry Andric //
135ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
145ffd83dbSDimitry Andric 
155ffd83dbSDimitry Andric #include "llvm/CodeGen/CommandFlags.h"
1681ad6265SDimitry Andric #include "llvm/ADT/StringExtras.h"
1781ad6265SDimitry Andric #include "llvm/IR/Instructions.h"
1881ad6265SDimitry Andric #include "llvm/IR/Intrinsics.h"
195ffd83dbSDimitry Andric #include "llvm/IR/Module.h"
2081ad6265SDimitry Andric #include "llvm/MC/MCTargetOptionsCommandFlags.h"
215f757f3fSDimitry Andric #include "llvm/MC/TargetRegistry.h"
225ffd83dbSDimitry Andric #include "llvm/Support/CommandLine.h"
23fe6060f1SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
245f757f3fSDimitry Andric #include "llvm/Target/TargetMachine.h"
2506c3fb27SDimitry Andric #include "llvm/TargetParser/Host.h"
2606c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
2706c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
28bdd1243dSDimitry Andric #include <optional>
295ffd83dbSDimitry Andric 
305ffd83dbSDimitry Andric using namespace llvm;
315ffd83dbSDimitry Andric 
325ffd83dbSDimitry Andric #define CGOPT(TY, NAME)                                                        \
335ffd83dbSDimitry Andric   static cl::opt<TY> *NAME##View;                                              \
345ffd83dbSDimitry Andric   TY codegen::get##NAME() {                                                    \
355ffd83dbSDimitry Andric     assert(NAME##View && "RegisterCodeGenFlags not created.");                 \
365ffd83dbSDimitry Andric     return *NAME##View;                                                        \
375ffd83dbSDimitry Andric   }
385ffd83dbSDimitry Andric 
395ffd83dbSDimitry Andric #define CGLIST(TY, NAME)                                                       \
405ffd83dbSDimitry Andric   static cl::list<TY> *NAME##View;                                             \
415ffd83dbSDimitry Andric   std::vector<TY> codegen::get##NAME() {                                       \
425ffd83dbSDimitry Andric     assert(NAME##View && "RegisterCodeGenFlags not created.");                 \
435ffd83dbSDimitry Andric     return *NAME##View;                                                        \
445ffd83dbSDimitry Andric   }
455ffd83dbSDimitry Andric 
46bdd1243dSDimitry Andric // Temporary macro for incremental transition to std::optional.
475ffd83dbSDimitry Andric #define CGOPT_EXP(TY, NAME)                                                    \
485ffd83dbSDimitry Andric   CGOPT(TY, NAME)                                                              \
49bdd1243dSDimitry Andric   std::optional<TY> codegen::getExplicit##NAME() {                             \
505ffd83dbSDimitry Andric     if (NAME##View->getNumOccurrences()) {                                     \
515ffd83dbSDimitry Andric       TY res = *NAME##View;                                                    \
525ffd83dbSDimitry Andric       return res;                                                              \
535ffd83dbSDimitry Andric     }                                                                          \
54bdd1243dSDimitry Andric     return std::nullopt;                                                       \
555ffd83dbSDimitry Andric   }
565ffd83dbSDimitry Andric 
575ffd83dbSDimitry Andric CGOPT(std::string, MArch)
585ffd83dbSDimitry Andric CGOPT(std::string, MCPU)
595ffd83dbSDimitry Andric CGLIST(std::string, MAttrs)
605ffd83dbSDimitry Andric CGOPT_EXP(Reloc::Model, RelocModel)
615ffd83dbSDimitry Andric CGOPT(ThreadModel::Model, ThreadModel)
625ffd83dbSDimitry Andric CGOPT_EXP(CodeModel::Model, CodeModel)
635f757f3fSDimitry Andric CGOPT_EXP(uint64_t, LargeDataThreshold)
645ffd83dbSDimitry Andric CGOPT(ExceptionHandling, ExceptionModel)
655ffd83dbSDimitry Andric CGOPT_EXP(CodeGenFileType, FileType)
66fe6060f1SDimitry Andric CGOPT(FramePointerKind, FramePointerUsage)
675ffd83dbSDimitry Andric CGOPT(bool, EnableUnsafeFPMath)
685ffd83dbSDimitry Andric CGOPT(bool, EnableNoInfsFPMath)
695ffd83dbSDimitry Andric CGOPT(bool, EnableNoNaNsFPMath)
705ffd83dbSDimitry Andric CGOPT(bool, EnableNoSignedZerosFPMath)
7181ad6265SDimitry Andric CGOPT(bool, EnableApproxFuncFPMath)
725ffd83dbSDimitry Andric CGOPT(bool, EnableNoTrappingFPMath)
73e8d8bef9SDimitry Andric CGOPT(bool, EnableAIXExtendedAltivecABI)
745ffd83dbSDimitry Andric CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath)
755ffd83dbSDimitry Andric CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)
765ffd83dbSDimitry Andric CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
775ffd83dbSDimitry Andric CGOPT(FloatABI::ABIType, FloatABIForCalls)
785ffd83dbSDimitry Andric CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)
79349cc55cSDimitry Andric CGOPT(SwiftAsyncFramePointerMode, SwiftAsyncFramePointer)
805ffd83dbSDimitry Andric CGOPT(bool, DontPlaceZerosInBSS)
815ffd83dbSDimitry Andric CGOPT(bool, EnableGuaranteedTailCallOpt)
825ffd83dbSDimitry Andric CGOPT(bool, DisableTailCalls)
835ffd83dbSDimitry Andric CGOPT(bool, StackSymbolOrdering)
845ffd83dbSDimitry Andric CGOPT(bool, StackRealign)
855ffd83dbSDimitry Andric CGOPT(std::string, TrapFuncName)
865ffd83dbSDimitry Andric CGOPT(bool, UseCtors)
8706c3fb27SDimitry Andric CGOPT(bool, DisableIntegratedAS)
885ffd83dbSDimitry Andric CGOPT_EXP(bool, DataSections)
895ffd83dbSDimitry Andric CGOPT_EXP(bool, FunctionSections)
90e8d8bef9SDimitry Andric CGOPT(bool, IgnoreXCOFFVisibility)
91e8d8bef9SDimitry Andric CGOPT(bool, XCOFFTracebackTable)
92*0fca6ea1SDimitry Andric CGOPT(bool, EnableBBAddrMap)
935ffd83dbSDimitry Andric CGOPT(std::string, BBSections)
945ffd83dbSDimitry Andric CGOPT(unsigned, TLSSize)
9506c3fb27SDimitry Andric CGOPT_EXP(bool, EmulatedTLS)
967a6dacacSDimitry Andric CGOPT_EXP(bool, EnableTLSDESC)
975ffd83dbSDimitry Andric CGOPT(bool, UniqueSectionNames)
985ffd83dbSDimitry Andric CGOPT(bool, UniqueBasicBlockSectionNames)
99*0fca6ea1SDimitry Andric CGOPT(bool, SeparateNamedSections)
1005ffd83dbSDimitry Andric CGOPT(EABI, EABIVersion)
1015ffd83dbSDimitry Andric CGOPT(DebuggerKind, DebuggerTuningOpt)
1025ffd83dbSDimitry Andric CGOPT(bool, EnableStackSizeSection)
1035ffd83dbSDimitry Andric CGOPT(bool, EnableAddrsig)
1045ffd83dbSDimitry Andric CGOPT(bool, EmitCallSiteInfo)
105e8d8bef9SDimitry Andric CGOPT(bool, EnableMachineFunctionSplitter)
1065ffd83dbSDimitry Andric CGOPT(bool, EnableDebugEntryValues)
1075ffd83dbSDimitry Andric CGOPT(bool, ForceDwarfFrameSection)
10806c3fb27SDimitry Andric CGOPT(bool, XRayFunctionIndex)
109fe6060f1SDimitry Andric CGOPT(bool, DebugStrictDwarf)
110349cc55cSDimitry Andric CGOPT(unsigned, AlignLoops)
11181ad6265SDimitry Andric CGOPT(bool, JMCInstrument)
11206c3fb27SDimitry Andric CGOPT(bool, XCOFFReadOnlyPointers)
1135ffd83dbSDimitry Andric 
1145ffd83dbSDimitry Andric codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
1155ffd83dbSDimitry Andric #define CGBINDOPT(NAME)                                                        \
1165ffd83dbSDimitry Andric   do {                                                                         \
1175ffd83dbSDimitry Andric     NAME##View = std::addressof(NAME);                                         \
1185ffd83dbSDimitry Andric   } while (0)
1195ffd83dbSDimitry Andric 
1205ffd83dbSDimitry Andric   static cl::opt<std::string> MArch(
1215ffd83dbSDimitry Andric       "march", cl::desc("Architecture to generate code for (see --version)"));
1225ffd83dbSDimitry Andric   CGBINDOPT(MArch);
1235ffd83dbSDimitry Andric 
1245ffd83dbSDimitry Andric   static cl::opt<std::string> MCPU(
1255ffd83dbSDimitry Andric       "mcpu", cl::desc("Target a specific cpu type (-mcpu=help for details)"),
1265ffd83dbSDimitry Andric       cl::value_desc("cpu-name"), cl::init(""));
1275ffd83dbSDimitry Andric   CGBINDOPT(MCPU);
1285ffd83dbSDimitry Andric 
1295ffd83dbSDimitry Andric   static cl::list<std::string> MAttrs(
1305ffd83dbSDimitry Andric       "mattr", cl::CommaSeparated,
1315ffd83dbSDimitry Andric       cl::desc("Target specific attributes (-mattr=help for details)"),
1325ffd83dbSDimitry Andric       cl::value_desc("a1,+a2,-a3,..."));
1335ffd83dbSDimitry Andric   CGBINDOPT(MAttrs);
1345ffd83dbSDimitry Andric 
1355ffd83dbSDimitry Andric   static cl::opt<Reloc::Model> RelocModel(
1365ffd83dbSDimitry Andric       "relocation-model", cl::desc("Choose relocation model"),
1375ffd83dbSDimitry Andric       cl::values(
1385ffd83dbSDimitry Andric           clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
1395ffd83dbSDimitry Andric           clEnumValN(Reloc::PIC_, "pic",
1405ffd83dbSDimitry Andric                      "Fully relocatable, position independent code"),
1415ffd83dbSDimitry Andric           clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
1425ffd83dbSDimitry Andric                      "Relocatable external references, non-relocatable code"),
1435ffd83dbSDimitry Andric           clEnumValN(
1445ffd83dbSDimitry Andric               Reloc::ROPI, "ropi",
1455ffd83dbSDimitry Andric               "Code and read-only data relocatable, accessed PC-relative"),
1465ffd83dbSDimitry Andric           clEnumValN(
1475ffd83dbSDimitry Andric               Reloc::RWPI, "rwpi",
1485ffd83dbSDimitry Andric               "Read-write data relocatable, accessed relative to static base"),
1495ffd83dbSDimitry Andric           clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
1505ffd83dbSDimitry Andric                      "Combination of ropi and rwpi")));
1515ffd83dbSDimitry Andric   CGBINDOPT(RelocModel);
1525ffd83dbSDimitry Andric 
1535ffd83dbSDimitry Andric   static cl::opt<ThreadModel::Model> ThreadModel(
1545ffd83dbSDimitry Andric       "thread-model", cl::desc("Choose threading model"),
1555ffd83dbSDimitry Andric       cl::init(ThreadModel::POSIX),
1565ffd83dbSDimitry Andric       cl::values(
1575ffd83dbSDimitry Andric           clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
1585ffd83dbSDimitry Andric           clEnumValN(ThreadModel::Single, "single", "Single thread model")));
1595ffd83dbSDimitry Andric   CGBINDOPT(ThreadModel);
1605ffd83dbSDimitry Andric 
1615ffd83dbSDimitry Andric   static cl::opt<CodeModel::Model> CodeModel(
1625ffd83dbSDimitry Andric       "code-model", cl::desc("Choose code model"),
1635ffd83dbSDimitry Andric       cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),
1645ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Small, "small", "Small code model"),
1655ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
1665ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
1675ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Large, "large", "Large code model")));
1685ffd83dbSDimitry Andric   CGBINDOPT(CodeModel);
1695ffd83dbSDimitry Andric 
1705f757f3fSDimitry Andric   static cl::opt<uint64_t> LargeDataThreshold(
1715f757f3fSDimitry Andric       "large-data-threshold",
1725f757f3fSDimitry Andric       cl::desc("Choose large data threshold for x86_64 medium code model"),
1735f757f3fSDimitry Andric       cl::init(0));
1745f757f3fSDimitry Andric   CGBINDOPT(LargeDataThreshold);
1755f757f3fSDimitry Andric 
1765ffd83dbSDimitry Andric   static cl::opt<ExceptionHandling> ExceptionModel(
1775ffd83dbSDimitry Andric       "exception-model", cl::desc("exception model"),
1785ffd83dbSDimitry Andric       cl::init(ExceptionHandling::None),
1795ffd83dbSDimitry Andric       cl::values(
1805ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::None, "default",
1815ffd83dbSDimitry Andric                      "default exception handling model"),
1825ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
1835ffd83dbSDimitry Andric                      "DWARF-like CFI based exception handling"),
1845ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::SjLj, "sjlj",
1855ffd83dbSDimitry Andric                      "SjLj exception handling"),
1865ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
1875ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::WinEH, "wineh",
1885ffd83dbSDimitry Andric                      "Windows exception model"),
1895ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::Wasm, "wasm",
1905ffd83dbSDimitry Andric                      "WebAssembly exception handling")));
1915ffd83dbSDimitry Andric   CGBINDOPT(ExceptionModel);
1925ffd83dbSDimitry Andric 
1935ffd83dbSDimitry Andric   static cl::opt<CodeGenFileType> FileType(
1945f757f3fSDimitry Andric       "filetype", cl::init(CodeGenFileType::AssemblyFile),
1955ffd83dbSDimitry Andric       cl::desc(
1965ffd83dbSDimitry Andric           "Choose a file type (not all types are supported by all targets):"),
1975f757f3fSDimitry Andric       cl::values(clEnumValN(CodeGenFileType::AssemblyFile, "asm",
1985f757f3fSDimitry Andric                             "Emit an assembly ('.s') file"),
1995f757f3fSDimitry Andric                  clEnumValN(CodeGenFileType::ObjectFile, "obj",
2005ffd83dbSDimitry Andric                             "Emit a native object ('.o') file"),
2015f757f3fSDimitry Andric                  clEnumValN(CodeGenFileType::Null, "null",
2025ffd83dbSDimitry Andric                             "Emit nothing, for performance testing")));
2035ffd83dbSDimitry Andric   CGBINDOPT(FileType);
2045ffd83dbSDimitry Andric 
205fe6060f1SDimitry Andric   static cl::opt<FramePointerKind> FramePointerUsage(
2065ffd83dbSDimitry Andric       "frame-pointer",
2075ffd83dbSDimitry Andric       cl::desc("Specify frame pointer elimination optimization"),
208fe6060f1SDimitry Andric       cl::init(FramePointerKind::None),
2095ffd83dbSDimitry Andric       cl::values(
210fe6060f1SDimitry Andric           clEnumValN(FramePointerKind::All, "all",
2115ffd83dbSDimitry Andric                      "Disable frame pointer elimination"),
212fe6060f1SDimitry Andric           clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
2135ffd83dbSDimitry Andric                      "Disable frame pointer elimination for non-leaf frame"),
214*0fca6ea1SDimitry Andric           clEnumValN(FramePointerKind::Reserved, "reserved",
215*0fca6ea1SDimitry Andric                      "Enable frame pointer elimination, but reserve the frame "
216*0fca6ea1SDimitry Andric                      "pointer register"),
217fe6060f1SDimitry Andric           clEnumValN(FramePointerKind::None, "none",
2185ffd83dbSDimitry Andric                      "Enable frame pointer elimination")));
2195ffd83dbSDimitry Andric   CGBINDOPT(FramePointerUsage);
2205ffd83dbSDimitry Andric 
2215ffd83dbSDimitry Andric   static cl::opt<bool> EnableUnsafeFPMath(
2225ffd83dbSDimitry Andric       "enable-unsafe-fp-math",
2235ffd83dbSDimitry Andric       cl::desc("Enable optimizations that may decrease FP precision"),
2245ffd83dbSDimitry Andric       cl::init(false));
2255ffd83dbSDimitry Andric   CGBINDOPT(EnableUnsafeFPMath);
2265ffd83dbSDimitry Andric 
2275ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoInfsFPMath(
2285ffd83dbSDimitry Andric       "enable-no-infs-fp-math",
2295ffd83dbSDimitry Andric       cl::desc("Enable FP math optimizations that assume no +-Infs"),
2305ffd83dbSDimitry Andric       cl::init(false));
2315ffd83dbSDimitry Andric   CGBINDOPT(EnableNoInfsFPMath);
2325ffd83dbSDimitry Andric 
2335ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoNaNsFPMath(
2345ffd83dbSDimitry Andric       "enable-no-nans-fp-math",
2355ffd83dbSDimitry Andric       cl::desc("Enable FP math optimizations that assume no NaNs"),
2365ffd83dbSDimitry Andric       cl::init(false));
2375ffd83dbSDimitry Andric   CGBINDOPT(EnableNoNaNsFPMath);
2385ffd83dbSDimitry Andric 
2395ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoSignedZerosFPMath(
2405ffd83dbSDimitry Andric       "enable-no-signed-zeros-fp-math",
2415ffd83dbSDimitry Andric       cl::desc("Enable FP math optimizations that assume "
2425ffd83dbSDimitry Andric                "the sign of 0 is insignificant"),
2435ffd83dbSDimitry Andric       cl::init(false));
2445ffd83dbSDimitry Andric   CGBINDOPT(EnableNoSignedZerosFPMath);
2455ffd83dbSDimitry Andric 
24681ad6265SDimitry Andric   static cl::opt<bool> EnableApproxFuncFPMath(
24781ad6265SDimitry Andric       "enable-approx-func-fp-math",
24881ad6265SDimitry Andric       cl::desc("Enable FP math optimizations that assume approx func"),
24981ad6265SDimitry Andric       cl::init(false));
25081ad6265SDimitry Andric   CGBINDOPT(EnableApproxFuncFPMath);
25181ad6265SDimitry Andric 
2525ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoTrappingFPMath(
2535ffd83dbSDimitry Andric       "enable-no-trapping-fp-math",
2545ffd83dbSDimitry Andric       cl::desc("Enable setting the FP exceptions build "
2555ffd83dbSDimitry Andric                "attribute not to use exceptions"),
2565ffd83dbSDimitry Andric       cl::init(false));
2575ffd83dbSDimitry Andric   CGBINDOPT(EnableNoTrappingFPMath);
2585ffd83dbSDimitry Andric 
25906c3fb27SDimitry Andric   static const auto DenormFlagEnumOptions = cl::values(
26006c3fb27SDimitry Andric       clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"),
2615ffd83dbSDimitry Andric       clEnumValN(DenormalMode::PreserveSign, "preserve-sign",
2625ffd83dbSDimitry Andric                  "the sign of a  flushed-to-zero number is preserved "
2635ffd83dbSDimitry Andric                  "in the sign of 0"),
2645ffd83dbSDimitry Andric       clEnumValN(DenormalMode::PositiveZero, "positive-zero",
26506c3fb27SDimitry Andric                  "denormals are flushed to positive zero"),
26606c3fb27SDimitry Andric       clEnumValN(DenormalMode::Dynamic, "dynamic",
26706c3fb27SDimitry Andric                  "denormals have unknown treatment"));
2685ffd83dbSDimitry Andric 
2695ffd83dbSDimitry Andric   // FIXME: Doesn't have way to specify separate input and output modes.
2705ffd83dbSDimitry Andric   static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath(
2715ffd83dbSDimitry Andric     "denormal-fp-math",
2725ffd83dbSDimitry Andric     cl::desc("Select which denormal numbers the code is permitted to require"),
2735ffd83dbSDimitry Andric     cl::init(DenormalMode::IEEE),
2745ffd83dbSDimitry Andric     DenormFlagEnumOptions);
2755ffd83dbSDimitry Andric   CGBINDOPT(DenormalFPMath);
2765ffd83dbSDimitry Andric 
2775ffd83dbSDimitry Andric   static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math(
2785ffd83dbSDimitry Andric     "denormal-fp-math-f32",
2795ffd83dbSDimitry Andric     cl::desc("Select which denormal numbers the code is permitted to require for float"),
2805ffd83dbSDimitry Andric     cl::init(DenormalMode::Invalid),
2815ffd83dbSDimitry Andric     DenormFlagEnumOptions);
2825ffd83dbSDimitry Andric   CGBINDOPT(DenormalFP32Math);
2835ffd83dbSDimitry Andric 
2845ffd83dbSDimitry Andric   static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
2855ffd83dbSDimitry Andric       "enable-sign-dependent-rounding-fp-math", cl::Hidden,
2865ffd83dbSDimitry Andric       cl::desc("Force codegen to assume rounding mode can change dynamically"),
2875ffd83dbSDimitry Andric       cl::init(false));
2885ffd83dbSDimitry Andric   CGBINDOPT(EnableHonorSignDependentRoundingFPMath);
2895ffd83dbSDimitry Andric 
2905ffd83dbSDimitry Andric   static cl::opt<FloatABI::ABIType> FloatABIForCalls(
2915ffd83dbSDimitry Andric       "float-abi", cl::desc("Choose float ABI type"),
2925ffd83dbSDimitry Andric       cl::init(FloatABI::Default),
2935ffd83dbSDimitry Andric       cl::values(clEnumValN(FloatABI::Default, "default",
2945ffd83dbSDimitry Andric                             "Target default float ABI type"),
2955ffd83dbSDimitry Andric                  clEnumValN(FloatABI::Soft, "soft",
2965ffd83dbSDimitry Andric                             "Soft float ABI (implied by -soft-float)"),
2975ffd83dbSDimitry Andric                  clEnumValN(FloatABI::Hard, "hard",
2985ffd83dbSDimitry Andric                             "Hard float ABI (uses FP registers)")));
2995ffd83dbSDimitry Andric   CGBINDOPT(FloatABIForCalls);
3005ffd83dbSDimitry Andric 
3015ffd83dbSDimitry Andric   static cl::opt<FPOpFusion::FPOpFusionMode> FuseFPOps(
3025ffd83dbSDimitry Andric       "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
3035ffd83dbSDimitry Andric       cl::init(FPOpFusion::Standard),
3045ffd83dbSDimitry Andric       cl::values(
3055ffd83dbSDimitry Andric           clEnumValN(FPOpFusion::Fast, "fast",
3065ffd83dbSDimitry Andric                      "Fuse FP ops whenever profitable"),
3075ffd83dbSDimitry Andric           clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
3085ffd83dbSDimitry Andric           clEnumValN(FPOpFusion::Strict, "off",
3095ffd83dbSDimitry Andric                      "Only fuse FP ops when the result won't be affected.")));
3105ffd83dbSDimitry Andric   CGBINDOPT(FuseFPOps);
3115ffd83dbSDimitry Andric 
312349cc55cSDimitry Andric   static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer(
313349cc55cSDimitry Andric       "swift-async-fp",
314349cc55cSDimitry Andric       cl::desc("Determine when the Swift async frame pointer should be set"),
315349cc55cSDimitry Andric       cl::init(SwiftAsyncFramePointerMode::Always),
316349cc55cSDimitry Andric       cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto",
317349cc55cSDimitry Andric                             "Determine based on deployment target"),
318349cc55cSDimitry Andric                  clEnumValN(SwiftAsyncFramePointerMode::Always, "always",
319349cc55cSDimitry Andric                             "Always set the bit"),
320349cc55cSDimitry Andric                  clEnumValN(SwiftAsyncFramePointerMode::Never, "never",
321349cc55cSDimitry Andric                             "Never set the bit")));
322349cc55cSDimitry Andric   CGBINDOPT(SwiftAsyncFramePointer);
323349cc55cSDimitry Andric 
3245ffd83dbSDimitry Andric   static cl::opt<bool> DontPlaceZerosInBSS(
3255ffd83dbSDimitry Andric       "nozero-initialized-in-bss",
3265ffd83dbSDimitry Andric       cl::desc("Don't place zero-initialized symbols into bss section"),
3275ffd83dbSDimitry Andric       cl::init(false));
3285ffd83dbSDimitry Andric   CGBINDOPT(DontPlaceZerosInBSS);
3295ffd83dbSDimitry Andric 
330e8d8bef9SDimitry Andric   static cl::opt<bool> EnableAIXExtendedAltivecABI(
331e8d8bef9SDimitry Andric       "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),
332e8d8bef9SDimitry Andric       cl::init(false));
333e8d8bef9SDimitry Andric   CGBINDOPT(EnableAIXExtendedAltivecABI);
334e8d8bef9SDimitry Andric 
3355ffd83dbSDimitry Andric   static cl::opt<bool> EnableGuaranteedTailCallOpt(
3365ffd83dbSDimitry Andric       "tailcallopt",
3375ffd83dbSDimitry Andric       cl::desc(
3385ffd83dbSDimitry Andric           "Turn fastcc calls into tail calls by (potentially) changing ABI."),
3395ffd83dbSDimitry Andric       cl::init(false));
3405ffd83dbSDimitry Andric   CGBINDOPT(EnableGuaranteedTailCallOpt);
3415ffd83dbSDimitry Andric 
3425ffd83dbSDimitry Andric   static cl::opt<bool> DisableTailCalls(
3435ffd83dbSDimitry Andric       "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false));
3445ffd83dbSDimitry Andric   CGBINDOPT(DisableTailCalls);
3455ffd83dbSDimitry Andric 
3465ffd83dbSDimitry Andric   static cl::opt<bool> StackSymbolOrdering(
3475ffd83dbSDimitry Andric       "stack-symbol-ordering", cl::desc("Order local stack symbols."),
3485ffd83dbSDimitry Andric       cl::init(true));
3495ffd83dbSDimitry Andric   CGBINDOPT(StackSymbolOrdering);
3505ffd83dbSDimitry Andric 
3515ffd83dbSDimitry Andric   static cl::opt<bool> StackRealign(
3525ffd83dbSDimitry Andric       "stackrealign",
3535ffd83dbSDimitry Andric       cl::desc("Force align the stack to the minimum alignment"),
3545ffd83dbSDimitry Andric       cl::init(false));
3555ffd83dbSDimitry Andric   CGBINDOPT(StackRealign);
3565ffd83dbSDimitry Andric 
3575ffd83dbSDimitry Andric   static cl::opt<std::string> TrapFuncName(
3585ffd83dbSDimitry Andric       "trap-func", cl::Hidden,
3595ffd83dbSDimitry Andric       cl::desc("Emit a call to trap function rather than a trap instruction"),
3605ffd83dbSDimitry Andric       cl::init(""));
3615ffd83dbSDimitry Andric   CGBINDOPT(TrapFuncName);
3625ffd83dbSDimitry Andric 
3635ffd83dbSDimitry Andric   static cl::opt<bool> UseCtors("use-ctors",
3645ffd83dbSDimitry Andric                                 cl::desc("Use .ctors instead of .init_array."),
3655ffd83dbSDimitry Andric                                 cl::init(false));
3665ffd83dbSDimitry Andric   CGBINDOPT(UseCtors);
3675ffd83dbSDimitry Andric 
3685ffd83dbSDimitry Andric   static cl::opt<bool> DataSections(
3695ffd83dbSDimitry Andric       "data-sections", cl::desc("Emit data into separate sections"),
3705ffd83dbSDimitry Andric       cl::init(false));
3715ffd83dbSDimitry Andric   CGBINDOPT(DataSections);
3725ffd83dbSDimitry Andric 
3735ffd83dbSDimitry Andric   static cl::opt<bool> FunctionSections(
3745ffd83dbSDimitry Andric       "function-sections", cl::desc("Emit functions into separate sections"),
3755ffd83dbSDimitry Andric       cl::init(false));
3765ffd83dbSDimitry Andric   CGBINDOPT(FunctionSections);
3775ffd83dbSDimitry Andric 
378e8d8bef9SDimitry Andric   static cl::opt<bool> IgnoreXCOFFVisibility(
379e8d8bef9SDimitry Andric       "ignore-xcoff-visibility",
380e8d8bef9SDimitry Andric       cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
381e8d8bef9SDimitry Andric                "all symbols 'unspecified' visibility in XCOFF object file"),
382e8d8bef9SDimitry Andric       cl::init(false));
383e8d8bef9SDimitry Andric   CGBINDOPT(IgnoreXCOFFVisibility);
384e8d8bef9SDimitry Andric 
385e8d8bef9SDimitry Andric   static cl::opt<bool> XCOFFTracebackTable(
386e8d8bef9SDimitry Andric       "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
387e8d8bef9SDimitry Andric       cl::init(true));
388e8d8bef9SDimitry Andric   CGBINDOPT(XCOFFTracebackTable);
389e8d8bef9SDimitry Andric 
390*0fca6ea1SDimitry Andric   static cl::opt<bool> EnableBBAddrMap(
391*0fca6ea1SDimitry Andric       "basic-block-address-map",
392*0fca6ea1SDimitry Andric       cl::desc("Emit the basic block address map section"), cl::init(false));
393*0fca6ea1SDimitry Andric   CGBINDOPT(EnableBBAddrMap);
394*0fca6ea1SDimitry Andric 
3955ffd83dbSDimitry Andric   static cl::opt<std::string> BBSections(
396e8d8bef9SDimitry Andric       "basic-block-sections",
3975ffd83dbSDimitry Andric       cl::desc("Emit basic blocks into separate sections"),
3985ffd83dbSDimitry Andric       cl::value_desc("all | <function list (file)> | labels | none"),
3995ffd83dbSDimitry Andric       cl::init("none"));
4005ffd83dbSDimitry Andric   CGBINDOPT(BBSections);
4015ffd83dbSDimitry Andric 
4025ffd83dbSDimitry Andric   static cl::opt<unsigned> TLSSize(
4035ffd83dbSDimitry Andric       "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
4045ffd83dbSDimitry Andric   CGBINDOPT(TLSSize);
4055ffd83dbSDimitry Andric 
4065ffd83dbSDimitry Andric   static cl::opt<bool> EmulatedTLS(
4075ffd83dbSDimitry Andric       "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
4085ffd83dbSDimitry Andric   CGBINDOPT(EmulatedTLS);
4095ffd83dbSDimitry Andric 
4107a6dacacSDimitry Andric   static cl::opt<bool> EnableTLSDESC(
4117a6dacacSDimitry Andric       "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"),
4127a6dacacSDimitry Andric       cl::init(false));
4137a6dacacSDimitry Andric   CGBINDOPT(EnableTLSDESC);
4147a6dacacSDimitry Andric 
4155ffd83dbSDimitry Andric   static cl::opt<bool> UniqueSectionNames(
4165ffd83dbSDimitry Andric       "unique-section-names", cl::desc("Give unique names to every section"),
4175ffd83dbSDimitry Andric       cl::init(true));
4185ffd83dbSDimitry Andric   CGBINDOPT(UniqueSectionNames);
4195ffd83dbSDimitry Andric 
4205ffd83dbSDimitry Andric   static cl::opt<bool> UniqueBasicBlockSectionNames(
421e8d8bef9SDimitry Andric       "unique-basic-block-section-names",
4225ffd83dbSDimitry Andric       cl::desc("Give unique names to every basic block section"),
4235ffd83dbSDimitry Andric       cl::init(false));
4245ffd83dbSDimitry Andric   CGBINDOPT(UniqueBasicBlockSectionNames);
4255ffd83dbSDimitry Andric 
426*0fca6ea1SDimitry Andric   static cl::opt<bool> SeparateNamedSections(
427*0fca6ea1SDimitry Andric       "separate-named-sections",
428*0fca6ea1SDimitry Andric       cl::desc("Use separate unique sections for named sections"),
429*0fca6ea1SDimitry Andric       cl::init(false));
430*0fca6ea1SDimitry Andric   CGBINDOPT(SeparateNamedSections);
431*0fca6ea1SDimitry Andric 
4325ffd83dbSDimitry Andric   static cl::opt<EABI> EABIVersion(
4335ffd83dbSDimitry Andric       "meabi", cl::desc("Set EABI type (default depends on triple):"),
4345ffd83dbSDimitry Andric       cl::init(EABI::Default),
4355ffd83dbSDimitry Andric       cl::values(
4365ffd83dbSDimitry Andric           clEnumValN(EABI::Default, "default", "Triple default EABI version"),
4375ffd83dbSDimitry Andric           clEnumValN(EABI::EABI4, "4", "EABI version 4"),
4385ffd83dbSDimitry Andric           clEnumValN(EABI::EABI5, "5", "EABI version 5"),
4395ffd83dbSDimitry Andric           clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
4405ffd83dbSDimitry Andric   CGBINDOPT(EABIVersion);
4415ffd83dbSDimitry Andric 
4425ffd83dbSDimitry Andric   static cl::opt<DebuggerKind> DebuggerTuningOpt(
4435ffd83dbSDimitry Andric       "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
4445ffd83dbSDimitry Andric       cl::init(DebuggerKind::Default),
4455ffd83dbSDimitry Andric       cl::values(
4465ffd83dbSDimitry Andric           clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
4475ffd83dbSDimitry Andric           clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
448fe6060f1SDimitry Andric           clEnumValN(DebuggerKind::DBX, "dbx", "dbx"),
4495ffd83dbSDimitry Andric           clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
4505ffd83dbSDimitry Andric   CGBINDOPT(DebuggerTuningOpt);
4515ffd83dbSDimitry Andric 
4525ffd83dbSDimitry Andric   static cl::opt<bool> EnableStackSizeSection(
4535ffd83dbSDimitry Andric       "stack-size-section",
4545ffd83dbSDimitry Andric       cl::desc("Emit a section containing stack size metadata"),
4555ffd83dbSDimitry Andric       cl::init(false));
4565ffd83dbSDimitry Andric   CGBINDOPT(EnableStackSizeSection);
4575ffd83dbSDimitry Andric 
4585ffd83dbSDimitry Andric   static cl::opt<bool> EnableAddrsig(
4595ffd83dbSDimitry Andric       "addrsig", cl::desc("Emit an address-significance table"),
4605ffd83dbSDimitry Andric       cl::init(false));
4615ffd83dbSDimitry Andric   CGBINDOPT(EnableAddrsig);
4625ffd83dbSDimitry Andric 
4635ffd83dbSDimitry Andric   static cl::opt<bool> EmitCallSiteInfo(
4645ffd83dbSDimitry Andric       "emit-call-site-info",
4655ffd83dbSDimitry Andric       cl::desc(
4665ffd83dbSDimitry Andric           "Emit call site debug information, if debug information is enabled."),
4675ffd83dbSDimitry Andric       cl::init(false));
4685ffd83dbSDimitry Andric   CGBINDOPT(EmitCallSiteInfo);
4695ffd83dbSDimitry Andric 
4705ffd83dbSDimitry Andric   static cl::opt<bool> EnableDebugEntryValues(
4715ffd83dbSDimitry Andric       "debug-entry-values",
4725ffd83dbSDimitry Andric       cl::desc("Enable debug info for the debug entry values."),
4735ffd83dbSDimitry Andric       cl::init(false));
4745ffd83dbSDimitry Andric   CGBINDOPT(EnableDebugEntryValues);
4755ffd83dbSDimitry Andric 
476e8d8bef9SDimitry Andric   static cl::opt<bool> EnableMachineFunctionSplitter(
477e8d8bef9SDimitry Andric       "split-machine-functions",
478e8d8bef9SDimitry Andric       cl::desc("Split out cold basic blocks from machine functions based on "
479e8d8bef9SDimitry Andric                "profile information"),
480e8d8bef9SDimitry Andric       cl::init(false));
481e8d8bef9SDimitry Andric   CGBINDOPT(EnableMachineFunctionSplitter);
482e8d8bef9SDimitry Andric 
4835ffd83dbSDimitry Andric   static cl::opt<bool> ForceDwarfFrameSection(
4845ffd83dbSDimitry Andric       "force-dwarf-frame-section",
4855ffd83dbSDimitry Andric       cl::desc("Always emit a debug frame section."), cl::init(false));
4865ffd83dbSDimitry Andric   CGBINDOPT(ForceDwarfFrameSection);
4875ffd83dbSDimitry Andric 
48806c3fb27SDimitry Andric   static cl::opt<bool> XRayFunctionIndex("xray-function-index",
48906c3fb27SDimitry Andric                                          cl::desc("Emit xray_fn_idx section"),
49006c3fb27SDimitry Andric                                          cl::init(true));
49106c3fb27SDimitry Andric   CGBINDOPT(XRayFunctionIndex);
4925ffd83dbSDimitry Andric 
493fe6060f1SDimitry Andric   static cl::opt<bool> DebugStrictDwarf(
494fe6060f1SDimitry Andric       "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false));
495fe6060f1SDimitry Andric   CGBINDOPT(DebugStrictDwarf);
496fe6060f1SDimitry Andric 
497349cc55cSDimitry Andric   static cl::opt<unsigned> AlignLoops("align-loops",
498349cc55cSDimitry Andric                                       cl::desc("Default alignment for loops"));
499349cc55cSDimitry Andric   CGBINDOPT(AlignLoops);
500349cc55cSDimitry Andric 
50181ad6265SDimitry Andric   static cl::opt<bool> JMCInstrument(
50281ad6265SDimitry Andric       "enable-jmc-instrument",
50381ad6265SDimitry Andric       cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"),
50481ad6265SDimitry Andric       cl::init(false));
50581ad6265SDimitry Andric   CGBINDOPT(JMCInstrument);
50681ad6265SDimitry Andric 
50706c3fb27SDimitry Andric   static cl::opt<bool> XCOFFReadOnlyPointers(
50806c3fb27SDimitry Andric       "mxcoff-roptr",
50906c3fb27SDimitry Andric       cl::desc("When set to true, const objects with relocatable address "
51006c3fb27SDimitry Andric                "values are put into the RO data section."),
51106c3fb27SDimitry Andric       cl::init(false));
51206c3fb27SDimitry Andric   CGBINDOPT(XCOFFReadOnlyPointers);
51306c3fb27SDimitry Andric 
51406c3fb27SDimitry Andric   static cl::opt<bool> DisableIntegratedAS(
51506c3fb27SDimitry Andric       "no-integrated-as", cl::desc("Disable integrated assembler"),
51606c3fb27SDimitry Andric       cl::init(false));
51706c3fb27SDimitry Andric   CGBINDOPT(DisableIntegratedAS);
51806c3fb27SDimitry Andric 
5195ffd83dbSDimitry Andric #undef CGBINDOPT
5205ffd83dbSDimitry Andric 
5215ffd83dbSDimitry Andric   mc::RegisterMCTargetOptionsFlags();
5225ffd83dbSDimitry Andric }
5235ffd83dbSDimitry Andric 
5245ffd83dbSDimitry Andric llvm::BasicBlockSection
5255ffd83dbSDimitry Andric codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
5265ffd83dbSDimitry Andric   if (getBBSections() == "all")
5275ffd83dbSDimitry Andric     return BasicBlockSection::All;
5285ffd83dbSDimitry Andric   else if (getBBSections() == "labels")
5295ffd83dbSDimitry Andric     return BasicBlockSection::Labels;
5305ffd83dbSDimitry Andric   else if (getBBSections() == "none")
5315ffd83dbSDimitry Andric     return BasicBlockSection::None;
5325ffd83dbSDimitry Andric   else {
5335ffd83dbSDimitry Andric     ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
5345ffd83dbSDimitry Andric         MemoryBuffer::getFile(getBBSections());
5355ffd83dbSDimitry Andric     if (!MBOrErr) {
5365ffd83dbSDimitry Andric       errs() << "Error loading basic block sections function list file: "
5375ffd83dbSDimitry Andric              << MBOrErr.getError().message() << "\n";
5385ffd83dbSDimitry Andric     } else {
5395ffd83dbSDimitry Andric       Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
5405ffd83dbSDimitry Andric     }
5415ffd83dbSDimitry Andric     return BasicBlockSection::List;
5425ffd83dbSDimitry Andric   }
5435ffd83dbSDimitry Andric }
5445ffd83dbSDimitry Andric 
5455ffd83dbSDimitry Andric // Common utility function tightly tied to the options listed here. Initializes
5465ffd83dbSDimitry Andric // a TargetOptions object with CodeGen flags and returns it.
547e8d8bef9SDimitry Andric TargetOptions
548e8d8bef9SDimitry Andric codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
5495ffd83dbSDimitry Andric   TargetOptions Options;
5505ffd83dbSDimitry Andric   Options.AllowFPOpFusion = getFuseFPOps();
5515ffd83dbSDimitry Andric   Options.UnsafeFPMath = getEnableUnsafeFPMath();
5525ffd83dbSDimitry Andric   Options.NoInfsFPMath = getEnableNoInfsFPMath();
5535ffd83dbSDimitry Andric   Options.NoNaNsFPMath = getEnableNoNaNsFPMath();
5545ffd83dbSDimitry Andric   Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath();
55581ad6265SDimitry Andric   Options.ApproxFuncFPMath = getEnableApproxFuncFPMath();
5565ffd83dbSDimitry Andric   Options.NoTrappingFPMath = getEnableNoTrappingFPMath();
5575ffd83dbSDimitry Andric 
5585ffd83dbSDimitry Andric   DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
5595ffd83dbSDimitry Andric 
5605ffd83dbSDimitry Andric   // FIXME: Should have separate input and output flags
5615ffd83dbSDimitry Andric   Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind));
5625ffd83dbSDimitry Andric 
5635ffd83dbSDimitry Andric   Options.HonorSignDependentRoundingFPMathOption =
5645ffd83dbSDimitry Andric       getEnableHonorSignDependentRoundingFPMath();
5655ffd83dbSDimitry Andric   if (getFloatABIForCalls() != FloatABI::Default)
5665ffd83dbSDimitry Andric     Options.FloatABIType = getFloatABIForCalls();
567e8d8bef9SDimitry Andric   Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();
5685ffd83dbSDimitry Andric   Options.NoZerosInBSS = getDontPlaceZerosInBSS();
5695ffd83dbSDimitry Andric   Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();
5705ffd83dbSDimitry Andric   Options.StackSymbolOrdering = getStackSymbolOrdering();
5715ffd83dbSDimitry Andric   Options.UseInitArray = !getUseCtors();
57206c3fb27SDimitry Andric   Options.DisableIntegratedAS = getDisableIntegratedAS();
573e8d8bef9SDimitry Andric   Options.DataSections =
57481ad6265SDimitry Andric       getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections());
5755ffd83dbSDimitry Andric   Options.FunctionSections = getFunctionSections();
576e8d8bef9SDimitry Andric   Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
577e8d8bef9SDimitry Andric   Options.XCOFFTracebackTable = getXCOFFTracebackTable();
578*0fca6ea1SDimitry Andric   Options.BBAddrMap = getEnableBBAddrMap();
5795ffd83dbSDimitry Andric   Options.BBSections = getBBSectionsMode(Options);
5805ffd83dbSDimitry Andric   Options.UniqueSectionNames = getUniqueSectionNames();
5815ffd83dbSDimitry Andric   Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
582*0fca6ea1SDimitry Andric   Options.SeparateNamedSections = getSeparateNamedSections();
5835ffd83dbSDimitry Andric   Options.TLSSize = getTLSSize();
58406c3fb27SDimitry Andric   Options.EmulatedTLS =
58506c3fb27SDimitry Andric       getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS());
5867a6dacacSDimitry Andric   Options.EnableTLSDESC =
5877a6dacacSDimitry Andric       getExplicitEnableTLSDESC().value_or(TheTriple.hasDefaultTLSDESC());
5885ffd83dbSDimitry Andric   Options.ExceptionModel = getExceptionModel();
5895ffd83dbSDimitry Andric   Options.EmitStackSizeSection = getEnableStackSizeSection();
590e8d8bef9SDimitry Andric   Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
5915ffd83dbSDimitry Andric   Options.EmitAddrsig = getEnableAddrsig();
5925ffd83dbSDimitry Andric   Options.EmitCallSiteInfo = getEmitCallSiteInfo();
5935ffd83dbSDimitry Andric   Options.EnableDebugEntryValues = getEnableDebugEntryValues();
5945ffd83dbSDimitry Andric   Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
59506c3fb27SDimitry Andric   Options.XRayFunctionIndex = getXRayFunctionIndex();
596fe6060f1SDimitry Andric   Options.DebugStrictDwarf = getDebugStrictDwarf();
597349cc55cSDimitry Andric   Options.LoopAlignment = getAlignLoops();
59881ad6265SDimitry Andric   Options.JMCInstrument = getJMCInstrument();
59906c3fb27SDimitry Andric   Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers();
6005ffd83dbSDimitry Andric 
6015ffd83dbSDimitry Andric   Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
6025ffd83dbSDimitry Andric 
6035ffd83dbSDimitry Andric   Options.ThreadModel = getThreadModel();
6045ffd83dbSDimitry Andric   Options.EABIVersion = getEABIVersion();
6055ffd83dbSDimitry Andric   Options.DebuggerTuning = getDebuggerTuningOpt();
606349cc55cSDimitry Andric   Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer();
6075ffd83dbSDimitry Andric   return Options;
6085ffd83dbSDimitry Andric }
6095ffd83dbSDimitry Andric 
6105ffd83dbSDimitry Andric std::string codegen::getCPUStr() {
6115ffd83dbSDimitry Andric   // If user asked for the 'native' CPU, autodetect here. If autodection fails,
6125ffd83dbSDimitry Andric   // this will set the CPU to an empty string which tells the target to
6135ffd83dbSDimitry Andric   // pick a basic default.
6145ffd83dbSDimitry Andric   if (getMCPU() == "native")
6155ffd83dbSDimitry Andric     return std::string(sys::getHostCPUName());
6165ffd83dbSDimitry Andric 
6175ffd83dbSDimitry Andric   return getMCPU();
6185ffd83dbSDimitry Andric }
6195ffd83dbSDimitry Andric 
6205ffd83dbSDimitry Andric std::string codegen::getFeaturesStr() {
6215ffd83dbSDimitry Andric   SubtargetFeatures Features;
6225ffd83dbSDimitry Andric 
6235ffd83dbSDimitry Andric   // If user asked for the 'native' CPU, we need to autodetect features.
6245ffd83dbSDimitry Andric   // This is necessary for x86 where the CPU might not support all the
6255ffd83dbSDimitry Andric   // features the autodetected CPU name lists in the target. For example,
6265ffd83dbSDimitry Andric   // not all Sandybridge processors support AVX.
627*0fca6ea1SDimitry Andric   if (getMCPU() == "native")
628*0fca6ea1SDimitry Andric     for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())
629bdd1243dSDimitry Andric       Features.AddFeature(Feature, IsEnabled);
6305ffd83dbSDimitry Andric 
6315ffd83dbSDimitry Andric   for (auto const &MAttr : getMAttrs())
6325ffd83dbSDimitry Andric     Features.AddFeature(MAttr);
6335ffd83dbSDimitry Andric 
6345ffd83dbSDimitry Andric   return Features.getString();
6355ffd83dbSDimitry Andric }
6365ffd83dbSDimitry Andric 
6375ffd83dbSDimitry Andric std::vector<std::string> codegen::getFeatureList() {
6385ffd83dbSDimitry Andric   SubtargetFeatures Features;
6395ffd83dbSDimitry Andric 
6405ffd83dbSDimitry Andric   // If user asked for the 'native' CPU, we need to autodetect features.
6415ffd83dbSDimitry Andric   // This is necessary for x86 where the CPU might not support all the
6425ffd83dbSDimitry Andric   // features the autodetected CPU name lists in the target. For example,
6435ffd83dbSDimitry Andric   // not all Sandybridge processors support AVX.
644*0fca6ea1SDimitry Andric   if (getMCPU() == "native")
645*0fca6ea1SDimitry Andric     for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())
646bdd1243dSDimitry Andric       Features.AddFeature(Feature, IsEnabled);
6475ffd83dbSDimitry Andric 
6485ffd83dbSDimitry Andric   for (auto const &MAttr : getMAttrs())
6495ffd83dbSDimitry Andric     Features.AddFeature(MAttr);
6505ffd83dbSDimitry Andric 
6515ffd83dbSDimitry Andric   return Features.getFeatures();
6525ffd83dbSDimitry Andric }
6535ffd83dbSDimitry Andric 
6545ffd83dbSDimitry Andric void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
6555ffd83dbSDimitry Andric   B.addAttribute(Name, Val ? "true" : "false");
6565ffd83dbSDimitry Andric }
6575ffd83dbSDimitry Andric 
6585ffd83dbSDimitry Andric #define HANDLE_BOOL_ATTR(CL, AttrName)                                         \
6595ffd83dbSDimitry Andric   do {                                                                         \
6605ffd83dbSDimitry Andric     if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName))            \
6615ffd83dbSDimitry Andric       renderBoolStringAttr(NewAttrs, AttrName, *CL);                           \
6625ffd83dbSDimitry Andric   } while (0)
6635ffd83dbSDimitry Andric 
6645ffd83dbSDimitry Andric /// Set function attributes of function \p F based on CPU, Features, and command
6655ffd83dbSDimitry Andric /// line flags.
6665ffd83dbSDimitry Andric void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
6675ffd83dbSDimitry Andric                                     Function &F) {
6685ffd83dbSDimitry Andric   auto &Ctx = F.getContext();
6695ffd83dbSDimitry Andric   AttributeList Attrs = F.getAttributes();
67004eeddc0SDimitry Andric   AttrBuilder NewAttrs(Ctx);
6715ffd83dbSDimitry Andric 
6725ffd83dbSDimitry Andric   if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
6735ffd83dbSDimitry Andric     NewAttrs.addAttribute("target-cpu", CPU);
6745ffd83dbSDimitry Andric   if (!Features.empty()) {
6755ffd83dbSDimitry Andric     // Append the command line features to any that are already on the function.
6765ffd83dbSDimitry Andric     StringRef OldFeatures =
6775ffd83dbSDimitry Andric         F.getFnAttribute("target-features").getValueAsString();
6785ffd83dbSDimitry Andric     if (OldFeatures.empty())
6795ffd83dbSDimitry Andric       NewAttrs.addAttribute("target-features", Features);
6805ffd83dbSDimitry Andric     else {
6815ffd83dbSDimitry Andric       SmallString<256> Appended(OldFeatures);
6825ffd83dbSDimitry Andric       Appended.push_back(',');
6835ffd83dbSDimitry Andric       Appended.append(Features);
6845ffd83dbSDimitry Andric       NewAttrs.addAttribute("target-features", Appended);
6855ffd83dbSDimitry Andric     }
6865ffd83dbSDimitry Andric   }
6875ffd83dbSDimitry Andric   if (FramePointerUsageView->getNumOccurrences() > 0 &&
6885ffd83dbSDimitry Andric       !F.hasFnAttribute("frame-pointer")) {
689fe6060f1SDimitry Andric     if (getFramePointerUsage() == FramePointerKind::All)
6905ffd83dbSDimitry Andric       NewAttrs.addAttribute("frame-pointer", "all");
691fe6060f1SDimitry Andric     else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
6925ffd83dbSDimitry Andric       NewAttrs.addAttribute("frame-pointer", "non-leaf");
693*0fca6ea1SDimitry Andric     else if (getFramePointerUsage() == FramePointerKind::Reserved)
694*0fca6ea1SDimitry Andric       NewAttrs.addAttribute("frame-pointer", "reserved");
695fe6060f1SDimitry Andric     else if (getFramePointerUsage() == FramePointerKind::None)
6965ffd83dbSDimitry Andric       NewAttrs.addAttribute("frame-pointer", "none");
6975ffd83dbSDimitry Andric   }
6985ffd83dbSDimitry Andric   if (DisableTailCallsView->getNumOccurrences() > 0)
6995ffd83dbSDimitry Andric     NewAttrs.addAttribute("disable-tail-calls",
7005ffd83dbSDimitry Andric                           toStringRef(getDisableTailCalls()));
7015ffd83dbSDimitry Andric   if (getStackRealign())
7025ffd83dbSDimitry Andric     NewAttrs.addAttribute("stackrealign");
7035ffd83dbSDimitry Andric 
7045ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math");
7055ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");
7065ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");
7075ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");
70881ad6265SDimitry Andric   HANDLE_BOOL_ATTR(EnableApproxFuncFPMathView, "approx-func-fp-math");
7095ffd83dbSDimitry Andric 
7105ffd83dbSDimitry Andric   if (DenormalFPMathView->getNumOccurrences() > 0 &&
7115ffd83dbSDimitry Andric       !F.hasFnAttribute("denormal-fp-math")) {
7125ffd83dbSDimitry Andric     DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
7135ffd83dbSDimitry Andric 
7145ffd83dbSDimitry Andric     // FIXME: Command line flag should expose separate input/output modes.
7155ffd83dbSDimitry Andric     NewAttrs.addAttribute("denormal-fp-math",
7165ffd83dbSDimitry Andric                           DenormalMode(DenormKind, DenormKind).str());
7175ffd83dbSDimitry Andric   }
7185ffd83dbSDimitry Andric 
7195ffd83dbSDimitry Andric   if (DenormalFP32MathView->getNumOccurrences() > 0 &&
7205ffd83dbSDimitry Andric       !F.hasFnAttribute("denormal-fp-math-f32")) {
7215ffd83dbSDimitry Andric     // FIXME: Command line flag should expose separate input/output modes.
7225ffd83dbSDimitry Andric     DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math();
7235ffd83dbSDimitry Andric 
7245ffd83dbSDimitry Andric     NewAttrs.addAttribute(
7255ffd83dbSDimitry Andric       "denormal-fp-math-f32",
7265ffd83dbSDimitry Andric       DenormalMode(DenormKind, DenormKind).str());
7275ffd83dbSDimitry Andric   }
7285ffd83dbSDimitry Andric 
7295ffd83dbSDimitry Andric   if (TrapFuncNameView->getNumOccurrences() > 0)
7305ffd83dbSDimitry Andric     for (auto &B : F)
7315ffd83dbSDimitry Andric       for (auto &I : B)
7325ffd83dbSDimitry Andric         if (auto *Call = dyn_cast<CallInst>(&I))
7335ffd83dbSDimitry Andric           if (const auto *F = Call->getCalledFunction())
7345ffd83dbSDimitry Andric             if (F->getIntrinsicID() == Intrinsic::debugtrap ||
7355ffd83dbSDimitry Andric                 F->getIntrinsicID() == Intrinsic::trap)
736349cc55cSDimitry Andric               Call->addFnAttr(
7375ffd83dbSDimitry Andric                   Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));
7385ffd83dbSDimitry Andric 
7395ffd83dbSDimitry Andric   // Let NewAttrs override Attrs.
740349cc55cSDimitry Andric   F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs));
7415ffd83dbSDimitry Andric }
7425ffd83dbSDimitry Andric 
7435ffd83dbSDimitry Andric /// Set function attributes of functions in Module M based on CPU,
7445ffd83dbSDimitry Andric /// Features, and command line flags.
7455ffd83dbSDimitry Andric void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
7465ffd83dbSDimitry Andric                                     Module &M) {
7475ffd83dbSDimitry Andric   for (Function &F : M)
7485ffd83dbSDimitry Andric     setFunctionAttributes(CPU, Features, F);
7495ffd83dbSDimitry Andric }
7505f757f3fSDimitry Andric 
7515f757f3fSDimitry Andric Expected<std::unique_ptr<TargetMachine>>
7525f757f3fSDimitry Andric codegen::createTargetMachineForTriple(StringRef TargetTriple,
7535f757f3fSDimitry Andric                                       CodeGenOptLevel OptLevel) {
7545f757f3fSDimitry Andric   Triple TheTriple(TargetTriple);
7555f757f3fSDimitry Andric   std::string Error;
7565f757f3fSDimitry Andric   const auto *TheTarget =
7575f757f3fSDimitry Andric       TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
7585f757f3fSDimitry Andric   if (!TheTarget)
7595f757f3fSDimitry Andric     return createStringError(inconvertibleErrorCode(), Error);
7605f757f3fSDimitry Andric   auto *Target = TheTarget->createTargetMachine(
7615f757f3fSDimitry Andric       TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(),
7625f757f3fSDimitry Andric       codegen::InitTargetOptionsFromCodeGenFlags(TheTriple),
7635f757f3fSDimitry Andric       codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(),
7645f757f3fSDimitry Andric       OptLevel);
7655f757f3fSDimitry Andric   if (!Target)
7665f757f3fSDimitry Andric     return createStringError(inconvertibleErrorCode(),
7675f757f3fSDimitry Andric                              Twine("could not allocate target machine for ") +
7685f757f3fSDimitry Andric                                  TargetTriple);
7695f757f3fSDimitry Andric   return std::unique_ptr<TargetMachine>(Target);
7705f757f3fSDimitry Andric }
771