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"
21c9157d92SDimitry Andric #include "llvm/MC/TargetRegistry.h"
225ffd83dbSDimitry Andric #include "llvm/Support/CommandLine.h"
23fe6060f1SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
24c9157d92SDimitry Andric #include "llvm/Target/TargetMachine.h"
25fe013be4SDimitry Andric #include "llvm/TargetParser/Host.h"
26fe013be4SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
27fe013be4SDimitry 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 
CGOPT(std::string,MArch)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)
63c9157d92SDimitry 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)
87fe013be4SDimitry Andric CGOPT(bool, DisableIntegratedAS)
885ffd83dbSDimitry Andric CGOPT(bool, RelaxELFRelocations)
895ffd83dbSDimitry Andric CGOPT_EXP(bool, DataSections)
905ffd83dbSDimitry Andric CGOPT_EXP(bool, FunctionSections)
91e8d8bef9SDimitry Andric CGOPT(bool, IgnoreXCOFFVisibility)
92e8d8bef9SDimitry Andric CGOPT(bool, XCOFFTracebackTable)
935ffd83dbSDimitry Andric CGOPT(std::string, BBSections)
945ffd83dbSDimitry Andric CGOPT(unsigned, TLSSize)
95fe013be4SDimitry Andric CGOPT_EXP(bool, EmulatedTLS)
96*a58f00eaSDimitry Andric CGOPT_EXP(bool, EnableTLSDESC)
975ffd83dbSDimitry Andric CGOPT(bool, UniqueSectionNames)
985ffd83dbSDimitry Andric CGOPT(bool, UniqueBasicBlockSectionNames)
995ffd83dbSDimitry Andric CGOPT(EABI, EABIVersion)
1005ffd83dbSDimitry Andric CGOPT(DebuggerKind, DebuggerTuningOpt)
1015ffd83dbSDimitry Andric CGOPT(bool, EnableStackSizeSection)
1025ffd83dbSDimitry Andric CGOPT(bool, EnableAddrsig)
1035ffd83dbSDimitry Andric CGOPT(bool, EmitCallSiteInfo)
104e8d8bef9SDimitry Andric CGOPT(bool, EnableMachineFunctionSplitter)
1055ffd83dbSDimitry Andric CGOPT(bool, EnableDebugEntryValues)
1065ffd83dbSDimitry Andric CGOPT(bool, ForceDwarfFrameSection)
107fe013be4SDimitry Andric CGOPT(bool, XRayFunctionIndex)
108fe6060f1SDimitry Andric CGOPT(bool, DebugStrictDwarf)
109349cc55cSDimitry Andric CGOPT(unsigned, AlignLoops)
11081ad6265SDimitry Andric CGOPT(bool, JMCInstrument)
111fe013be4SDimitry Andric CGOPT(bool, XCOFFReadOnlyPointers)
1125ffd83dbSDimitry Andric 
1135ffd83dbSDimitry Andric codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
1145ffd83dbSDimitry Andric #define CGBINDOPT(NAME)                                                        \
1155ffd83dbSDimitry Andric   do {                                                                         \
1165ffd83dbSDimitry Andric     NAME##View = std::addressof(NAME);                                         \
1175ffd83dbSDimitry Andric   } while (0)
1185ffd83dbSDimitry Andric 
1195ffd83dbSDimitry Andric   static cl::opt<std::string> MArch(
1205ffd83dbSDimitry Andric       "march", cl::desc("Architecture to generate code for (see --version)"));
1215ffd83dbSDimitry Andric   CGBINDOPT(MArch);
1225ffd83dbSDimitry Andric 
1235ffd83dbSDimitry Andric   static cl::opt<std::string> MCPU(
1245ffd83dbSDimitry Andric       "mcpu", cl::desc("Target a specific cpu type (-mcpu=help for details)"),
1255ffd83dbSDimitry Andric       cl::value_desc("cpu-name"), cl::init(""));
1265ffd83dbSDimitry Andric   CGBINDOPT(MCPU);
1275ffd83dbSDimitry Andric 
1285ffd83dbSDimitry Andric   static cl::list<std::string> MAttrs(
1295ffd83dbSDimitry Andric       "mattr", cl::CommaSeparated,
1305ffd83dbSDimitry Andric       cl::desc("Target specific attributes (-mattr=help for details)"),
1315ffd83dbSDimitry Andric       cl::value_desc("a1,+a2,-a3,..."));
1325ffd83dbSDimitry Andric   CGBINDOPT(MAttrs);
1335ffd83dbSDimitry Andric 
1345ffd83dbSDimitry Andric   static cl::opt<Reloc::Model> RelocModel(
1355ffd83dbSDimitry Andric       "relocation-model", cl::desc("Choose relocation model"),
1365ffd83dbSDimitry Andric       cl::values(
1375ffd83dbSDimitry Andric           clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
1385ffd83dbSDimitry Andric           clEnumValN(Reloc::PIC_, "pic",
1395ffd83dbSDimitry Andric                      "Fully relocatable, position independent code"),
1405ffd83dbSDimitry Andric           clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
1415ffd83dbSDimitry Andric                      "Relocatable external references, non-relocatable code"),
1425ffd83dbSDimitry Andric           clEnumValN(
1435ffd83dbSDimitry Andric               Reloc::ROPI, "ropi",
1445ffd83dbSDimitry Andric               "Code and read-only data relocatable, accessed PC-relative"),
1455ffd83dbSDimitry Andric           clEnumValN(
1465ffd83dbSDimitry Andric               Reloc::RWPI, "rwpi",
1475ffd83dbSDimitry Andric               "Read-write data relocatable, accessed relative to static base"),
1485ffd83dbSDimitry Andric           clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
1495ffd83dbSDimitry Andric                      "Combination of ropi and rwpi")));
1505ffd83dbSDimitry Andric   CGBINDOPT(RelocModel);
1515ffd83dbSDimitry Andric 
1525ffd83dbSDimitry Andric   static cl::opt<ThreadModel::Model> ThreadModel(
1535ffd83dbSDimitry Andric       "thread-model", cl::desc("Choose threading model"),
1545ffd83dbSDimitry Andric       cl::init(ThreadModel::POSIX),
1555ffd83dbSDimitry Andric       cl::values(
1565ffd83dbSDimitry Andric           clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
1575ffd83dbSDimitry Andric           clEnumValN(ThreadModel::Single, "single", "Single thread model")));
1585ffd83dbSDimitry Andric   CGBINDOPT(ThreadModel);
1595ffd83dbSDimitry Andric 
1605ffd83dbSDimitry Andric   static cl::opt<CodeModel::Model> CodeModel(
1615ffd83dbSDimitry Andric       "code-model", cl::desc("Choose code model"),
1625ffd83dbSDimitry Andric       cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),
1635ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Small, "small", "Small code model"),
1645ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
1655ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
1665ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Large, "large", "Large code model")));
1675ffd83dbSDimitry Andric   CGBINDOPT(CodeModel);
1685ffd83dbSDimitry Andric 
169c9157d92SDimitry Andric   static cl::opt<uint64_t> LargeDataThreshold(
170c9157d92SDimitry Andric       "large-data-threshold",
171c9157d92SDimitry Andric       cl::desc("Choose large data threshold for x86_64 medium code model"),
172c9157d92SDimitry Andric       cl::init(0));
173c9157d92SDimitry Andric   CGBINDOPT(LargeDataThreshold);
174c9157d92SDimitry Andric 
1755ffd83dbSDimitry Andric   static cl::opt<ExceptionHandling> ExceptionModel(
1765ffd83dbSDimitry Andric       "exception-model", cl::desc("exception model"),
1775ffd83dbSDimitry Andric       cl::init(ExceptionHandling::None),
1785ffd83dbSDimitry Andric       cl::values(
1795ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::None, "default",
1805ffd83dbSDimitry Andric                      "default exception handling model"),
1815ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
1825ffd83dbSDimitry Andric                      "DWARF-like CFI based exception handling"),
1835ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::SjLj, "sjlj",
1845ffd83dbSDimitry Andric                      "SjLj exception handling"),
1855ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
1865ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::WinEH, "wineh",
1875ffd83dbSDimitry Andric                      "Windows exception model"),
1885ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::Wasm, "wasm",
1895ffd83dbSDimitry Andric                      "WebAssembly exception handling")));
1905ffd83dbSDimitry Andric   CGBINDOPT(ExceptionModel);
1915ffd83dbSDimitry Andric 
1925ffd83dbSDimitry Andric   static cl::opt<CodeGenFileType> FileType(
193c9157d92SDimitry Andric       "filetype", cl::init(CodeGenFileType::AssemblyFile),
1945ffd83dbSDimitry Andric       cl::desc(
1955ffd83dbSDimitry Andric           "Choose a file type (not all types are supported by all targets):"),
196c9157d92SDimitry Andric       cl::values(clEnumValN(CodeGenFileType::AssemblyFile, "asm",
197c9157d92SDimitry Andric                             "Emit an assembly ('.s') file"),
198c9157d92SDimitry Andric                  clEnumValN(CodeGenFileType::ObjectFile, "obj",
1995ffd83dbSDimitry Andric                             "Emit a native object ('.o') file"),
200c9157d92SDimitry Andric                  clEnumValN(CodeGenFileType::Null, "null",
2015ffd83dbSDimitry Andric                             "Emit nothing, for performance testing")));
2025ffd83dbSDimitry Andric   CGBINDOPT(FileType);
2035ffd83dbSDimitry Andric 
204fe6060f1SDimitry Andric   static cl::opt<FramePointerKind> FramePointerUsage(
2055ffd83dbSDimitry Andric       "frame-pointer",
2065ffd83dbSDimitry Andric       cl::desc("Specify frame pointer elimination optimization"),
207fe6060f1SDimitry Andric       cl::init(FramePointerKind::None),
2085ffd83dbSDimitry Andric       cl::values(
209fe6060f1SDimitry Andric           clEnumValN(FramePointerKind::All, "all",
2105ffd83dbSDimitry Andric                      "Disable frame pointer elimination"),
211fe6060f1SDimitry Andric           clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
2125ffd83dbSDimitry Andric                      "Disable frame pointer elimination for non-leaf frame"),
213fe6060f1SDimitry Andric           clEnumValN(FramePointerKind::None, "none",
2145ffd83dbSDimitry Andric                      "Enable frame pointer elimination")));
2155ffd83dbSDimitry Andric   CGBINDOPT(FramePointerUsage);
2165ffd83dbSDimitry Andric 
2175ffd83dbSDimitry Andric   static cl::opt<bool> EnableUnsafeFPMath(
2185ffd83dbSDimitry Andric       "enable-unsafe-fp-math",
2195ffd83dbSDimitry Andric       cl::desc("Enable optimizations that may decrease FP precision"),
2205ffd83dbSDimitry Andric       cl::init(false));
2215ffd83dbSDimitry Andric   CGBINDOPT(EnableUnsafeFPMath);
2225ffd83dbSDimitry Andric 
2235ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoInfsFPMath(
2245ffd83dbSDimitry Andric       "enable-no-infs-fp-math",
2255ffd83dbSDimitry Andric       cl::desc("Enable FP math optimizations that assume no +-Infs"),
2265ffd83dbSDimitry Andric       cl::init(false));
2275ffd83dbSDimitry Andric   CGBINDOPT(EnableNoInfsFPMath);
2285ffd83dbSDimitry Andric 
2295ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoNaNsFPMath(
2305ffd83dbSDimitry Andric       "enable-no-nans-fp-math",
2315ffd83dbSDimitry Andric       cl::desc("Enable FP math optimizations that assume no NaNs"),
2325ffd83dbSDimitry Andric       cl::init(false));
2335ffd83dbSDimitry Andric   CGBINDOPT(EnableNoNaNsFPMath);
2345ffd83dbSDimitry Andric 
2355ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoSignedZerosFPMath(
2365ffd83dbSDimitry Andric       "enable-no-signed-zeros-fp-math",
2375ffd83dbSDimitry Andric       cl::desc("Enable FP math optimizations that assume "
2385ffd83dbSDimitry Andric                "the sign of 0 is insignificant"),
2395ffd83dbSDimitry Andric       cl::init(false));
2405ffd83dbSDimitry Andric   CGBINDOPT(EnableNoSignedZerosFPMath);
2415ffd83dbSDimitry Andric 
24281ad6265SDimitry Andric   static cl::opt<bool> EnableApproxFuncFPMath(
24381ad6265SDimitry Andric       "enable-approx-func-fp-math",
24481ad6265SDimitry Andric       cl::desc("Enable FP math optimizations that assume approx func"),
24581ad6265SDimitry Andric       cl::init(false));
24681ad6265SDimitry Andric   CGBINDOPT(EnableApproxFuncFPMath);
24781ad6265SDimitry Andric 
2485ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoTrappingFPMath(
2495ffd83dbSDimitry Andric       "enable-no-trapping-fp-math",
2505ffd83dbSDimitry Andric       cl::desc("Enable setting the FP exceptions build "
2515ffd83dbSDimitry Andric                "attribute not to use exceptions"),
2525ffd83dbSDimitry Andric       cl::init(false));
2535ffd83dbSDimitry Andric   CGBINDOPT(EnableNoTrappingFPMath);
2545ffd83dbSDimitry Andric 
255fe013be4SDimitry Andric   static const auto DenormFlagEnumOptions = cl::values(
256fe013be4SDimitry Andric       clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"),
2575ffd83dbSDimitry Andric       clEnumValN(DenormalMode::PreserveSign, "preserve-sign",
2585ffd83dbSDimitry Andric                  "the sign of a  flushed-to-zero number is preserved "
2595ffd83dbSDimitry Andric                  "in the sign of 0"),
2605ffd83dbSDimitry Andric       clEnumValN(DenormalMode::PositiveZero, "positive-zero",
261fe013be4SDimitry Andric                  "denormals are flushed to positive zero"),
262fe013be4SDimitry Andric       clEnumValN(DenormalMode::Dynamic, "dynamic",
263fe013be4SDimitry Andric                  "denormals have unknown treatment"));
2645ffd83dbSDimitry Andric 
2655ffd83dbSDimitry Andric   // FIXME: Doesn't have way to specify separate input and output modes.
2665ffd83dbSDimitry Andric   static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath(
2675ffd83dbSDimitry Andric     "denormal-fp-math",
2685ffd83dbSDimitry Andric     cl::desc("Select which denormal numbers the code is permitted to require"),
2695ffd83dbSDimitry Andric     cl::init(DenormalMode::IEEE),
2705ffd83dbSDimitry Andric     DenormFlagEnumOptions);
2715ffd83dbSDimitry Andric   CGBINDOPT(DenormalFPMath);
2725ffd83dbSDimitry Andric 
2735ffd83dbSDimitry Andric   static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math(
2745ffd83dbSDimitry Andric     "denormal-fp-math-f32",
2755ffd83dbSDimitry Andric     cl::desc("Select which denormal numbers the code is permitted to require for float"),
2765ffd83dbSDimitry Andric     cl::init(DenormalMode::Invalid),
2775ffd83dbSDimitry Andric     DenormFlagEnumOptions);
2785ffd83dbSDimitry Andric   CGBINDOPT(DenormalFP32Math);
2795ffd83dbSDimitry Andric 
2805ffd83dbSDimitry Andric   static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
2815ffd83dbSDimitry Andric       "enable-sign-dependent-rounding-fp-math", cl::Hidden,
2825ffd83dbSDimitry Andric       cl::desc("Force codegen to assume rounding mode can change dynamically"),
2835ffd83dbSDimitry Andric       cl::init(false));
2845ffd83dbSDimitry Andric   CGBINDOPT(EnableHonorSignDependentRoundingFPMath);
2855ffd83dbSDimitry Andric 
2865ffd83dbSDimitry Andric   static cl::opt<FloatABI::ABIType> FloatABIForCalls(
2875ffd83dbSDimitry Andric       "float-abi", cl::desc("Choose float ABI type"),
2885ffd83dbSDimitry Andric       cl::init(FloatABI::Default),
2895ffd83dbSDimitry Andric       cl::values(clEnumValN(FloatABI::Default, "default",
2905ffd83dbSDimitry Andric                             "Target default float ABI type"),
2915ffd83dbSDimitry Andric                  clEnumValN(FloatABI::Soft, "soft",
2925ffd83dbSDimitry Andric                             "Soft float ABI (implied by -soft-float)"),
2935ffd83dbSDimitry Andric                  clEnumValN(FloatABI::Hard, "hard",
2945ffd83dbSDimitry Andric                             "Hard float ABI (uses FP registers)")));
2955ffd83dbSDimitry Andric   CGBINDOPT(FloatABIForCalls);
2965ffd83dbSDimitry Andric 
2975ffd83dbSDimitry Andric   static cl::opt<FPOpFusion::FPOpFusionMode> FuseFPOps(
2985ffd83dbSDimitry Andric       "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
2995ffd83dbSDimitry Andric       cl::init(FPOpFusion::Standard),
3005ffd83dbSDimitry Andric       cl::values(
3015ffd83dbSDimitry Andric           clEnumValN(FPOpFusion::Fast, "fast",
3025ffd83dbSDimitry Andric                      "Fuse FP ops whenever profitable"),
3035ffd83dbSDimitry Andric           clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
3045ffd83dbSDimitry Andric           clEnumValN(FPOpFusion::Strict, "off",
3055ffd83dbSDimitry Andric                      "Only fuse FP ops when the result won't be affected.")));
3065ffd83dbSDimitry Andric   CGBINDOPT(FuseFPOps);
3075ffd83dbSDimitry Andric 
308349cc55cSDimitry Andric   static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer(
309349cc55cSDimitry Andric       "swift-async-fp",
310349cc55cSDimitry Andric       cl::desc("Determine when the Swift async frame pointer should be set"),
311349cc55cSDimitry Andric       cl::init(SwiftAsyncFramePointerMode::Always),
312349cc55cSDimitry Andric       cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto",
313349cc55cSDimitry Andric                             "Determine based on deployment target"),
314349cc55cSDimitry Andric                  clEnumValN(SwiftAsyncFramePointerMode::Always, "always",
315349cc55cSDimitry Andric                             "Always set the bit"),
316349cc55cSDimitry Andric                  clEnumValN(SwiftAsyncFramePointerMode::Never, "never",
317349cc55cSDimitry Andric                             "Never set the bit")));
318349cc55cSDimitry Andric   CGBINDOPT(SwiftAsyncFramePointer);
319349cc55cSDimitry Andric 
3205ffd83dbSDimitry Andric   static cl::opt<bool> DontPlaceZerosInBSS(
3215ffd83dbSDimitry Andric       "nozero-initialized-in-bss",
3225ffd83dbSDimitry Andric       cl::desc("Don't place zero-initialized symbols into bss section"),
3235ffd83dbSDimitry Andric       cl::init(false));
3245ffd83dbSDimitry Andric   CGBINDOPT(DontPlaceZerosInBSS);
3255ffd83dbSDimitry Andric 
326e8d8bef9SDimitry Andric   static cl::opt<bool> EnableAIXExtendedAltivecABI(
327e8d8bef9SDimitry Andric       "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),
328e8d8bef9SDimitry Andric       cl::init(false));
329e8d8bef9SDimitry Andric   CGBINDOPT(EnableAIXExtendedAltivecABI);
330e8d8bef9SDimitry Andric 
3315ffd83dbSDimitry Andric   static cl::opt<bool> EnableGuaranteedTailCallOpt(
3325ffd83dbSDimitry Andric       "tailcallopt",
3335ffd83dbSDimitry Andric       cl::desc(
3345ffd83dbSDimitry Andric           "Turn fastcc calls into tail calls by (potentially) changing ABI."),
3355ffd83dbSDimitry Andric       cl::init(false));
3365ffd83dbSDimitry Andric   CGBINDOPT(EnableGuaranteedTailCallOpt);
3375ffd83dbSDimitry Andric 
3385ffd83dbSDimitry Andric   static cl::opt<bool> DisableTailCalls(
3395ffd83dbSDimitry Andric       "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false));
3405ffd83dbSDimitry Andric   CGBINDOPT(DisableTailCalls);
3415ffd83dbSDimitry Andric 
3425ffd83dbSDimitry Andric   static cl::opt<bool> StackSymbolOrdering(
3435ffd83dbSDimitry Andric       "stack-symbol-ordering", cl::desc("Order local stack symbols."),
3445ffd83dbSDimitry Andric       cl::init(true));
3455ffd83dbSDimitry Andric   CGBINDOPT(StackSymbolOrdering);
3465ffd83dbSDimitry Andric 
3475ffd83dbSDimitry Andric   static cl::opt<bool> StackRealign(
3485ffd83dbSDimitry Andric       "stackrealign",
3495ffd83dbSDimitry Andric       cl::desc("Force align the stack to the minimum alignment"),
3505ffd83dbSDimitry Andric       cl::init(false));
3515ffd83dbSDimitry Andric   CGBINDOPT(StackRealign);
3525ffd83dbSDimitry Andric 
3535ffd83dbSDimitry Andric   static cl::opt<std::string> TrapFuncName(
3545ffd83dbSDimitry Andric       "trap-func", cl::Hidden,
3555ffd83dbSDimitry Andric       cl::desc("Emit a call to trap function rather than a trap instruction"),
3565ffd83dbSDimitry Andric       cl::init(""));
3575ffd83dbSDimitry Andric   CGBINDOPT(TrapFuncName);
3585ffd83dbSDimitry Andric 
3595ffd83dbSDimitry Andric   static cl::opt<bool> UseCtors("use-ctors",
3605ffd83dbSDimitry Andric                                 cl::desc("Use .ctors instead of .init_array."),
3615ffd83dbSDimitry Andric                                 cl::init(false));
3625ffd83dbSDimitry Andric   CGBINDOPT(UseCtors);
3635ffd83dbSDimitry Andric 
3645ffd83dbSDimitry Andric   static cl::opt<bool> RelaxELFRelocations(
3655ffd83dbSDimitry Andric       "relax-elf-relocations",
3665ffd83dbSDimitry Andric       cl::desc(
3675ffd83dbSDimitry Andric           "Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
368bdd1243dSDimitry Andric       cl::init(true));
3695ffd83dbSDimitry Andric   CGBINDOPT(RelaxELFRelocations);
3705ffd83dbSDimitry Andric 
3715ffd83dbSDimitry Andric   static cl::opt<bool> DataSections(
3725ffd83dbSDimitry Andric       "data-sections", cl::desc("Emit data into separate sections"),
3735ffd83dbSDimitry Andric       cl::init(false));
3745ffd83dbSDimitry Andric   CGBINDOPT(DataSections);
3755ffd83dbSDimitry Andric 
3765ffd83dbSDimitry Andric   static cl::opt<bool> FunctionSections(
3775ffd83dbSDimitry Andric       "function-sections", cl::desc("Emit functions into separate sections"),
3785ffd83dbSDimitry Andric       cl::init(false));
3795ffd83dbSDimitry Andric   CGBINDOPT(FunctionSections);
3805ffd83dbSDimitry Andric 
381e8d8bef9SDimitry Andric   static cl::opt<bool> IgnoreXCOFFVisibility(
382e8d8bef9SDimitry Andric       "ignore-xcoff-visibility",
383e8d8bef9SDimitry Andric       cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
384e8d8bef9SDimitry Andric                "all symbols 'unspecified' visibility in XCOFF object file"),
385e8d8bef9SDimitry Andric       cl::init(false));
386e8d8bef9SDimitry Andric   CGBINDOPT(IgnoreXCOFFVisibility);
387e8d8bef9SDimitry Andric 
388e8d8bef9SDimitry Andric   static cl::opt<bool> XCOFFTracebackTable(
389e8d8bef9SDimitry Andric       "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
390e8d8bef9SDimitry Andric       cl::init(true));
391e8d8bef9SDimitry Andric   CGBINDOPT(XCOFFTracebackTable);
392e8d8bef9SDimitry Andric 
3935ffd83dbSDimitry Andric   static cl::opt<std::string> BBSections(
394e8d8bef9SDimitry Andric       "basic-block-sections",
3955ffd83dbSDimitry Andric       cl::desc("Emit basic blocks into separate sections"),
3965ffd83dbSDimitry Andric       cl::value_desc("all | <function list (file)> | labels | none"),
3975ffd83dbSDimitry Andric       cl::init("none"));
3985ffd83dbSDimitry Andric   CGBINDOPT(BBSections);
3995ffd83dbSDimitry Andric 
4005ffd83dbSDimitry Andric   static cl::opt<unsigned> TLSSize(
4015ffd83dbSDimitry Andric       "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
4025ffd83dbSDimitry Andric   CGBINDOPT(TLSSize);
4035ffd83dbSDimitry Andric 
4045ffd83dbSDimitry Andric   static cl::opt<bool> EmulatedTLS(
4055ffd83dbSDimitry Andric       "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
4065ffd83dbSDimitry Andric   CGBINDOPT(EmulatedTLS);
4075ffd83dbSDimitry Andric 
408*a58f00eaSDimitry Andric   static cl::opt<bool> EnableTLSDESC(
409*a58f00eaSDimitry Andric       "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"),
410*a58f00eaSDimitry Andric       cl::init(false));
411*a58f00eaSDimitry Andric   CGBINDOPT(EnableTLSDESC);
412*a58f00eaSDimitry Andric 
4135ffd83dbSDimitry Andric   static cl::opt<bool> UniqueSectionNames(
4145ffd83dbSDimitry Andric       "unique-section-names", cl::desc("Give unique names to every section"),
4155ffd83dbSDimitry Andric       cl::init(true));
4165ffd83dbSDimitry Andric   CGBINDOPT(UniqueSectionNames);
4175ffd83dbSDimitry Andric 
4185ffd83dbSDimitry Andric   static cl::opt<bool> UniqueBasicBlockSectionNames(
419e8d8bef9SDimitry Andric       "unique-basic-block-section-names",
4205ffd83dbSDimitry Andric       cl::desc("Give unique names to every basic block section"),
4215ffd83dbSDimitry Andric       cl::init(false));
4225ffd83dbSDimitry Andric   CGBINDOPT(UniqueBasicBlockSectionNames);
4235ffd83dbSDimitry Andric 
4245ffd83dbSDimitry Andric   static cl::opt<EABI> EABIVersion(
4255ffd83dbSDimitry Andric       "meabi", cl::desc("Set EABI type (default depends on triple):"),
4265ffd83dbSDimitry Andric       cl::init(EABI::Default),
4275ffd83dbSDimitry Andric       cl::values(
4285ffd83dbSDimitry Andric           clEnumValN(EABI::Default, "default", "Triple default EABI version"),
4295ffd83dbSDimitry Andric           clEnumValN(EABI::EABI4, "4", "EABI version 4"),
4305ffd83dbSDimitry Andric           clEnumValN(EABI::EABI5, "5", "EABI version 5"),
4315ffd83dbSDimitry Andric           clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
4325ffd83dbSDimitry Andric   CGBINDOPT(EABIVersion);
4335ffd83dbSDimitry Andric 
4345ffd83dbSDimitry Andric   static cl::opt<DebuggerKind> DebuggerTuningOpt(
4355ffd83dbSDimitry Andric       "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
4365ffd83dbSDimitry Andric       cl::init(DebuggerKind::Default),
4375ffd83dbSDimitry Andric       cl::values(
4385ffd83dbSDimitry Andric           clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
4395ffd83dbSDimitry Andric           clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
440fe6060f1SDimitry Andric           clEnumValN(DebuggerKind::DBX, "dbx", "dbx"),
4415ffd83dbSDimitry Andric           clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
4425ffd83dbSDimitry Andric   CGBINDOPT(DebuggerTuningOpt);
4435ffd83dbSDimitry Andric 
4445ffd83dbSDimitry Andric   static cl::opt<bool> EnableStackSizeSection(
4455ffd83dbSDimitry Andric       "stack-size-section",
4465ffd83dbSDimitry Andric       cl::desc("Emit a section containing stack size metadata"),
4475ffd83dbSDimitry Andric       cl::init(false));
4485ffd83dbSDimitry Andric   CGBINDOPT(EnableStackSizeSection);
4495ffd83dbSDimitry Andric 
4505ffd83dbSDimitry Andric   static cl::opt<bool> EnableAddrsig(
4515ffd83dbSDimitry Andric       "addrsig", cl::desc("Emit an address-significance table"),
4525ffd83dbSDimitry Andric       cl::init(false));
4535ffd83dbSDimitry Andric   CGBINDOPT(EnableAddrsig);
4545ffd83dbSDimitry Andric 
4555ffd83dbSDimitry Andric   static cl::opt<bool> EmitCallSiteInfo(
4565ffd83dbSDimitry Andric       "emit-call-site-info",
4575ffd83dbSDimitry Andric       cl::desc(
4585ffd83dbSDimitry Andric           "Emit call site debug information, if debug information is enabled."),
4595ffd83dbSDimitry Andric       cl::init(false));
4605ffd83dbSDimitry Andric   CGBINDOPT(EmitCallSiteInfo);
4615ffd83dbSDimitry Andric 
4625ffd83dbSDimitry Andric   static cl::opt<bool> EnableDebugEntryValues(
4635ffd83dbSDimitry Andric       "debug-entry-values",
4645ffd83dbSDimitry Andric       cl::desc("Enable debug info for the debug entry values."),
4655ffd83dbSDimitry Andric       cl::init(false));
4665ffd83dbSDimitry Andric   CGBINDOPT(EnableDebugEntryValues);
4675ffd83dbSDimitry Andric 
468e8d8bef9SDimitry Andric   static cl::opt<bool> EnableMachineFunctionSplitter(
469e8d8bef9SDimitry Andric       "split-machine-functions",
470e8d8bef9SDimitry Andric       cl::desc("Split out cold basic blocks from machine functions based on "
471e8d8bef9SDimitry Andric                "profile information"),
472e8d8bef9SDimitry Andric       cl::init(false));
473e8d8bef9SDimitry Andric   CGBINDOPT(EnableMachineFunctionSplitter);
474e8d8bef9SDimitry Andric 
4755ffd83dbSDimitry Andric   static cl::opt<bool> ForceDwarfFrameSection(
4765ffd83dbSDimitry Andric       "force-dwarf-frame-section",
4775ffd83dbSDimitry Andric       cl::desc("Always emit a debug frame section."), cl::init(false));
4785ffd83dbSDimitry Andric   CGBINDOPT(ForceDwarfFrameSection);
4795ffd83dbSDimitry Andric 
480fe013be4SDimitry Andric   static cl::opt<bool> XRayFunctionIndex("xray-function-index",
481fe013be4SDimitry Andric                                          cl::desc("Emit xray_fn_idx section"),
482fe013be4SDimitry Andric                                          cl::init(true));
483fe013be4SDimitry Andric   CGBINDOPT(XRayFunctionIndex);
4845ffd83dbSDimitry Andric 
485fe6060f1SDimitry Andric   static cl::opt<bool> DebugStrictDwarf(
486fe6060f1SDimitry Andric       "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false));
487fe6060f1SDimitry Andric   CGBINDOPT(DebugStrictDwarf);
488fe6060f1SDimitry Andric 
489349cc55cSDimitry Andric   static cl::opt<unsigned> AlignLoops("align-loops",
490349cc55cSDimitry Andric                                       cl::desc("Default alignment for loops"));
491349cc55cSDimitry Andric   CGBINDOPT(AlignLoops);
492349cc55cSDimitry Andric 
49381ad6265SDimitry Andric   static cl::opt<bool> JMCInstrument(
49481ad6265SDimitry Andric       "enable-jmc-instrument",
49581ad6265SDimitry Andric       cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"),
49681ad6265SDimitry Andric       cl::init(false));
49781ad6265SDimitry Andric   CGBINDOPT(JMCInstrument);
49881ad6265SDimitry Andric 
499fe013be4SDimitry Andric   static cl::opt<bool> XCOFFReadOnlyPointers(
500fe013be4SDimitry Andric       "mxcoff-roptr",
501fe013be4SDimitry Andric       cl::desc("When set to true, const objects with relocatable address "
502fe013be4SDimitry Andric                "values are put into the RO data section."),
503fe013be4SDimitry Andric       cl::init(false));
504fe013be4SDimitry Andric   CGBINDOPT(XCOFFReadOnlyPointers);
505fe013be4SDimitry Andric 
506fe013be4SDimitry Andric   static cl::opt<bool> DisableIntegratedAS(
507fe013be4SDimitry Andric       "no-integrated-as", cl::desc("Disable integrated assembler"),
508fe013be4SDimitry Andric       cl::init(false));
509fe013be4SDimitry Andric   CGBINDOPT(DisableIntegratedAS);
510fe013be4SDimitry Andric 
5115ffd83dbSDimitry Andric #undef CGBINDOPT
5125ffd83dbSDimitry Andric 
5135ffd83dbSDimitry Andric   mc::RegisterMCTargetOptionsFlags();
5145ffd83dbSDimitry Andric }
5155ffd83dbSDimitry Andric 
5165ffd83dbSDimitry Andric llvm::BasicBlockSection
getBBSectionsMode(llvm::TargetOptions & Options)5175ffd83dbSDimitry Andric codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
5185ffd83dbSDimitry Andric   if (getBBSections() == "all")
5195ffd83dbSDimitry Andric     return BasicBlockSection::All;
5205ffd83dbSDimitry Andric   else if (getBBSections() == "labels")
5215ffd83dbSDimitry Andric     return BasicBlockSection::Labels;
5225ffd83dbSDimitry Andric   else if (getBBSections() == "none")
5235ffd83dbSDimitry Andric     return BasicBlockSection::None;
5245ffd83dbSDimitry Andric   else {
5255ffd83dbSDimitry Andric     ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
5265ffd83dbSDimitry Andric         MemoryBuffer::getFile(getBBSections());
5275ffd83dbSDimitry Andric     if (!MBOrErr) {
5285ffd83dbSDimitry Andric       errs() << "Error loading basic block sections function list file: "
5295ffd83dbSDimitry Andric              << MBOrErr.getError().message() << "\n";
5305ffd83dbSDimitry Andric     } else {
5315ffd83dbSDimitry Andric       Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
5325ffd83dbSDimitry Andric     }
5335ffd83dbSDimitry Andric     return BasicBlockSection::List;
5345ffd83dbSDimitry Andric   }
5355ffd83dbSDimitry Andric }
5365ffd83dbSDimitry Andric 
5375ffd83dbSDimitry Andric // Common utility function tightly tied to the options listed here. Initializes
5385ffd83dbSDimitry Andric // a TargetOptions object with CodeGen flags and returns it.
539e8d8bef9SDimitry Andric TargetOptions
InitTargetOptionsFromCodeGenFlags(const Triple & TheTriple)540e8d8bef9SDimitry Andric codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
5415ffd83dbSDimitry Andric   TargetOptions Options;
5425ffd83dbSDimitry Andric   Options.AllowFPOpFusion = getFuseFPOps();
5435ffd83dbSDimitry Andric   Options.UnsafeFPMath = getEnableUnsafeFPMath();
5445ffd83dbSDimitry Andric   Options.NoInfsFPMath = getEnableNoInfsFPMath();
5455ffd83dbSDimitry Andric   Options.NoNaNsFPMath = getEnableNoNaNsFPMath();
5465ffd83dbSDimitry Andric   Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath();
54781ad6265SDimitry Andric   Options.ApproxFuncFPMath = getEnableApproxFuncFPMath();
5485ffd83dbSDimitry Andric   Options.NoTrappingFPMath = getEnableNoTrappingFPMath();
5495ffd83dbSDimitry Andric 
5505ffd83dbSDimitry Andric   DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
5515ffd83dbSDimitry Andric 
5525ffd83dbSDimitry Andric   // FIXME: Should have separate input and output flags
5535ffd83dbSDimitry Andric   Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind));
5545ffd83dbSDimitry Andric 
5555ffd83dbSDimitry Andric   Options.HonorSignDependentRoundingFPMathOption =
5565ffd83dbSDimitry Andric       getEnableHonorSignDependentRoundingFPMath();
5575ffd83dbSDimitry Andric   if (getFloatABIForCalls() != FloatABI::Default)
5585ffd83dbSDimitry Andric     Options.FloatABIType = getFloatABIForCalls();
559e8d8bef9SDimitry Andric   Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();
5605ffd83dbSDimitry Andric   Options.NoZerosInBSS = getDontPlaceZerosInBSS();
5615ffd83dbSDimitry Andric   Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();
5625ffd83dbSDimitry Andric   Options.StackSymbolOrdering = getStackSymbolOrdering();
5635ffd83dbSDimitry Andric   Options.UseInitArray = !getUseCtors();
564fe013be4SDimitry Andric   Options.DisableIntegratedAS = getDisableIntegratedAS();
5655ffd83dbSDimitry Andric   Options.RelaxELFRelocations = getRelaxELFRelocations();
566e8d8bef9SDimitry Andric   Options.DataSections =
56781ad6265SDimitry Andric       getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections());
5685ffd83dbSDimitry Andric   Options.FunctionSections = getFunctionSections();
569e8d8bef9SDimitry Andric   Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
570e8d8bef9SDimitry Andric   Options.XCOFFTracebackTable = getXCOFFTracebackTable();
5715ffd83dbSDimitry Andric   Options.BBSections = getBBSectionsMode(Options);
5725ffd83dbSDimitry Andric   Options.UniqueSectionNames = getUniqueSectionNames();
5735ffd83dbSDimitry Andric   Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
5745ffd83dbSDimitry Andric   Options.TLSSize = getTLSSize();
575fe013be4SDimitry Andric   Options.EmulatedTLS =
576fe013be4SDimitry Andric       getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS());
577*a58f00eaSDimitry Andric   Options.EnableTLSDESC =
578*a58f00eaSDimitry Andric       getExplicitEnableTLSDESC().value_or(TheTriple.hasDefaultTLSDESC());
5795ffd83dbSDimitry Andric   Options.ExceptionModel = getExceptionModel();
5805ffd83dbSDimitry Andric   Options.EmitStackSizeSection = getEnableStackSizeSection();
581e8d8bef9SDimitry Andric   Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
5825ffd83dbSDimitry Andric   Options.EmitAddrsig = getEnableAddrsig();
5835ffd83dbSDimitry Andric   Options.EmitCallSiteInfo = getEmitCallSiteInfo();
5845ffd83dbSDimitry Andric   Options.EnableDebugEntryValues = getEnableDebugEntryValues();
5855ffd83dbSDimitry Andric   Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
586fe013be4SDimitry Andric   Options.XRayFunctionIndex = getXRayFunctionIndex();
587fe6060f1SDimitry Andric   Options.DebugStrictDwarf = getDebugStrictDwarf();
588349cc55cSDimitry Andric   Options.LoopAlignment = getAlignLoops();
58981ad6265SDimitry Andric   Options.JMCInstrument = getJMCInstrument();
590fe013be4SDimitry Andric   Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers();
5915ffd83dbSDimitry Andric 
5925ffd83dbSDimitry Andric   Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
5935ffd83dbSDimitry Andric 
5945ffd83dbSDimitry Andric   Options.ThreadModel = getThreadModel();
5955ffd83dbSDimitry Andric   Options.EABIVersion = getEABIVersion();
5965ffd83dbSDimitry Andric   Options.DebuggerTuning = getDebuggerTuningOpt();
597349cc55cSDimitry Andric   Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer();
5985ffd83dbSDimitry Andric   return Options;
5995ffd83dbSDimitry Andric }
6005ffd83dbSDimitry Andric 
getCPUStr()6015ffd83dbSDimitry Andric std::string codegen::getCPUStr() {
6025ffd83dbSDimitry Andric   // If user asked for the 'native' CPU, autodetect here. If autodection fails,
6035ffd83dbSDimitry Andric   // this will set the CPU to an empty string which tells the target to
6045ffd83dbSDimitry Andric   // pick a basic default.
6055ffd83dbSDimitry Andric   if (getMCPU() == "native")
6065ffd83dbSDimitry Andric     return std::string(sys::getHostCPUName());
6075ffd83dbSDimitry Andric 
6085ffd83dbSDimitry Andric   return getMCPU();
6095ffd83dbSDimitry Andric }
6105ffd83dbSDimitry Andric 
getFeaturesStr()6115ffd83dbSDimitry Andric std::string codegen::getFeaturesStr() {
6125ffd83dbSDimitry Andric   SubtargetFeatures Features;
6135ffd83dbSDimitry Andric 
6145ffd83dbSDimitry Andric   // If user asked for the 'native' CPU, we need to autodetect features.
6155ffd83dbSDimitry Andric   // This is necessary for x86 where the CPU might not support all the
6165ffd83dbSDimitry Andric   // features the autodetected CPU name lists in the target. For example,
6175ffd83dbSDimitry Andric   // not all Sandybridge processors support AVX.
6185ffd83dbSDimitry Andric   if (getMCPU() == "native") {
6195ffd83dbSDimitry Andric     StringMap<bool> HostFeatures;
6205ffd83dbSDimitry Andric     if (sys::getHostCPUFeatures(HostFeatures))
621bdd1243dSDimitry Andric       for (const auto &[Feature, IsEnabled] : HostFeatures)
622bdd1243dSDimitry Andric         Features.AddFeature(Feature, IsEnabled);
6235ffd83dbSDimitry Andric   }
6245ffd83dbSDimitry Andric 
6255ffd83dbSDimitry Andric   for (auto const &MAttr : getMAttrs())
6265ffd83dbSDimitry Andric     Features.AddFeature(MAttr);
6275ffd83dbSDimitry Andric 
6285ffd83dbSDimitry Andric   return Features.getString();
6295ffd83dbSDimitry Andric }
6305ffd83dbSDimitry Andric 
getFeatureList()6315ffd83dbSDimitry Andric std::vector<std::string> codegen::getFeatureList() {
6325ffd83dbSDimitry Andric   SubtargetFeatures Features;
6335ffd83dbSDimitry Andric 
6345ffd83dbSDimitry Andric   // If user asked for the 'native' CPU, we need to autodetect features.
6355ffd83dbSDimitry Andric   // This is necessary for x86 where the CPU might not support all the
6365ffd83dbSDimitry Andric   // features the autodetected CPU name lists in the target. For example,
6375ffd83dbSDimitry Andric   // not all Sandybridge processors support AVX.
6385ffd83dbSDimitry Andric   if (getMCPU() == "native") {
6395ffd83dbSDimitry Andric     StringMap<bool> HostFeatures;
6405ffd83dbSDimitry Andric     if (sys::getHostCPUFeatures(HostFeatures))
641bdd1243dSDimitry Andric       for (const auto &[Feature, IsEnabled] : HostFeatures)
642bdd1243dSDimitry Andric         Features.AddFeature(Feature, IsEnabled);
6435ffd83dbSDimitry Andric   }
6445ffd83dbSDimitry Andric 
6455ffd83dbSDimitry Andric   for (auto const &MAttr : getMAttrs())
6465ffd83dbSDimitry Andric     Features.AddFeature(MAttr);
6475ffd83dbSDimitry Andric 
6485ffd83dbSDimitry Andric   return Features.getFeatures();
6495ffd83dbSDimitry Andric }
6505ffd83dbSDimitry Andric 
renderBoolStringAttr(AttrBuilder & B,StringRef Name,bool Val)6515ffd83dbSDimitry Andric void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
6525ffd83dbSDimitry Andric   B.addAttribute(Name, Val ? "true" : "false");
6535ffd83dbSDimitry Andric }
6545ffd83dbSDimitry Andric 
6555ffd83dbSDimitry Andric #define HANDLE_BOOL_ATTR(CL, AttrName)                                         \
6565ffd83dbSDimitry Andric   do {                                                                         \
6575ffd83dbSDimitry Andric     if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName))            \
6585ffd83dbSDimitry Andric       renderBoolStringAttr(NewAttrs, AttrName, *CL);                           \
6595ffd83dbSDimitry Andric   } while (0)
6605ffd83dbSDimitry Andric 
6615ffd83dbSDimitry Andric /// Set function attributes of function \p F based on CPU, Features, and command
6625ffd83dbSDimitry Andric /// line flags.
setFunctionAttributes(StringRef CPU,StringRef Features,Function & F)6635ffd83dbSDimitry Andric void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
6645ffd83dbSDimitry Andric                                     Function &F) {
6655ffd83dbSDimitry Andric   auto &Ctx = F.getContext();
6665ffd83dbSDimitry Andric   AttributeList Attrs = F.getAttributes();
66704eeddc0SDimitry Andric   AttrBuilder NewAttrs(Ctx);
6685ffd83dbSDimitry Andric 
6695ffd83dbSDimitry Andric   if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
6705ffd83dbSDimitry Andric     NewAttrs.addAttribute("target-cpu", CPU);
6715ffd83dbSDimitry Andric   if (!Features.empty()) {
6725ffd83dbSDimitry Andric     // Append the command line features to any that are already on the function.
6735ffd83dbSDimitry Andric     StringRef OldFeatures =
6745ffd83dbSDimitry Andric         F.getFnAttribute("target-features").getValueAsString();
6755ffd83dbSDimitry Andric     if (OldFeatures.empty())
6765ffd83dbSDimitry Andric       NewAttrs.addAttribute("target-features", Features);
6775ffd83dbSDimitry Andric     else {
6785ffd83dbSDimitry Andric       SmallString<256> Appended(OldFeatures);
6795ffd83dbSDimitry Andric       Appended.push_back(',');
6805ffd83dbSDimitry Andric       Appended.append(Features);
6815ffd83dbSDimitry Andric       NewAttrs.addAttribute("target-features", Appended);
6825ffd83dbSDimitry Andric     }
6835ffd83dbSDimitry Andric   }
6845ffd83dbSDimitry Andric   if (FramePointerUsageView->getNumOccurrences() > 0 &&
6855ffd83dbSDimitry Andric       !F.hasFnAttribute("frame-pointer")) {
686fe6060f1SDimitry Andric     if (getFramePointerUsage() == FramePointerKind::All)
6875ffd83dbSDimitry Andric       NewAttrs.addAttribute("frame-pointer", "all");
688fe6060f1SDimitry Andric     else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
6895ffd83dbSDimitry Andric       NewAttrs.addAttribute("frame-pointer", "non-leaf");
690fe6060f1SDimitry Andric     else if (getFramePointerUsage() == FramePointerKind::None)
6915ffd83dbSDimitry Andric       NewAttrs.addAttribute("frame-pointer", "none");
6925ffd83dbSDimitry Andric   }
6935ffd83dbSDimitry Andric   if (DisableTailCallsView->getNumOccurrences() > 0)
6945ffd83dbSDimitry Andric     NewAttrs.addAttribute("disable-tail-calls",
6955ffd83dbSDimitry Andric                           toStringRef(getDisableTailCalls()));
6965ffd83dbSDimitry Andric   if (getStackRealign())
6975ffd83dbSDimitry Andric     NewAttrs.addAttribute("stackrealign");
6985ffd83dbSDimitry Andric 
6995ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math");
7005ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");
7015ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");
7025ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");
70381ad6265SDimitry Andric   HANDLE_BOOL_ATTR(EnableApproxFuncFPMathView, "approx-func-fp-math");
7045ffd83dbSDimitry Andric 
7055ffd83dbSDimitry Andric   if (DenormalFPMathView->getNumOccurrences() > 0 &&
7065ffd83dbSDimitry Andric       !F.hasFnAttribute("denormal-fp-math")) {
7075ffd83dbSDimitry Andric     DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
7085ffd83dbSDimitry Andric 
7095ffd83dbSDimitry Andric     // FIXME: Command line flag should expose separate input/output modes.
7105ffd83dbSDimitry Andric     NewAttrs.addAttribute("denormal-fp-math",
7115ffd83dbSDimitry Andric                           DenormalMode(DenormKind, DenormKind).str());
7125ffd83dbSDimitry Andric   }
7135ffd83dbSDimitry Andric 
7145ffd83dbSDimitry Andric   if (DenormalFP32MathView->getNumOccurrences() > 0 &&
7155ffd83dbSDimitry Andric       !F.hasFnAttribute("denormal-fp-math-f32")) {
7165ffd83dbSDimitry Andric     // FIXME: Command line flag should expose separate input/output modes.
7175ffd83dbSDimitry Andric     DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math();
7185ffd83dbSDimitry Andric 
7195ffd83dbSDimitry Andric     NewAttrs.addAttribute(
7205ffd83dbSDimitry Andric       "denormal-fp-math-f32",
7215ffd83dbSDimitry Andric       DenormalMode(DenormKind, DenormKind).str());
7225ffd83dbSDimitry Andric   }
7235ffd83dbSDimitry Andric 
7245ffd83dbSDimitry Andric   if (TrapFuncNameView->getNumOccurrences() > 0)
7255ffd83dbSDimitry Andric     for (auto &B : F)
7265ffd83dbSDimitry Andric       for (auto &I : B)
7275ffd83dbSDimitry Andric         if (auto *Call = dyn_cast<CallInst>(&I))
7285ffd83dbSDimitry Andric           if (const auto *F = Call->getCalledFunction())
7295ffd83dbSDimitry Andric             if (F->getIntrinsicID() == Intrinsic::debugtrap ||
7305ffd83dbSDimitry Andric                 F->getIntrinsicID() == Intrinsic::trap)
731349cc55cSDimitry Andric               Call->addFnAttr(
7325ffd83dbSDimitry Andric                   Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));
7335ffd83dbSDimitry Andric 
7345ffd83dbSDimitry Andric   // Let NewAttrs override Attrs.
735349cc55cSDimitry Andric   F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs));
7365ffd83dbSDimitry Andric }
7375ffd83dbSDimitry Andric 
7385ffd83dbSDimitry Andric /// Set function attributes of functions in Module M based on CPU,
7395ffd83dbSDimitry Andric /// Features, and command line flags.
setFunctionAttributes(StringRef CPU,StringRef Features,Module & M)7405ffd83dbSDimitry Andric void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
7415ffd83dbSDimitry Andric                                     Module &M) {
7425ffd83dbSDimitry Andric   for (Function &F : M)
7435ffd83dbSDimitry Andric     setFunctionAttributes(CPU, Features, F);
7445ffd83dbSDimitry Andric }
745c9157d92SDimitry Andric 
746c9157d92SDimitry Andric Expected<std::unique_ptr<TargetMachine>>
createTargetMachineForTriple(StringRef TargetTriple,CodeGenOptLevel OptLevel)747c9157d92SDimitry Andric codegen::createTargetMachineForTriple(StringRef TargetTriple,
748c9157d92SDimitry Andric                                       CodeGenOptLevel OptLevel) {
749c9157d92SDimitry Andric   Triple TheTriple(TargetTriple);
750c9157d92SDimitry Andric   std::string Error;
751c9157d92SDimitry Andric   const auto *TheTarget =
752c9157d92SDimitry Andric       TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
753c9157d92SDimitry Andric   if (!TheTarget)
754c9157d92SDimitry Andric     return createStringError(inconvertibleErrorCode(), Error);
755c9157d92SDimitry Andric   auto *Target = TheTarget->createTargetMachine(
756c9157d92SDimitry Andric       TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(),
757c9157d92SDimitry Andric       codegen::InitTargetOptionsFromCodeGenFlags(TheTriple),
758c9157d92SDimitry Andric       codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(),
759c9157d92SDimitry Andric       OptLevel);
760c9157d92SDimitry Andric   if (!Target)
761c9157d92SDimitry Andric     return createStringError(inconvertibleErrorCode(),
762c9157d92SDimitry Andric                              Twine("could not allocate target machine for ") +
763c9157d92SDimitry Andric                                  TargetTriple);
764c9157d92SDimitry Andric   return std::unique_ptr<TargetMachine>(Target);
765c9157d92SDimitry Andric }
766