xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/CommandFlags.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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"
165ffd83dbSDimitry Andric #include "llvm/IR/Module.h"
175ffd83dbSDimitry Andric #include "llvm/MC/SubtargetFeature.h"
185ffd83dbSDimitry Andric #include "llvm/Support/CommandLine.h"
195ffd83dbSDimitry Andric #include "llvm/Support/Host.h"
205ffd83dbSDimitry Andric 
215ffd83dbSDimitry Andric using namespace llvm;
225ffd83dbSDimitry Andric 
235ffd83dbSDimitry Andric #define CGOPT(TY, NAME)                                                        \
245ffd83dbSDimitry Andric   static cl::opt<TY> *NAME##View;                                              \
255ffd83dbSDimitry Andric   TY codegen::get##NAME() {                                                    \
265ffd83dbSDimitry Andric     assert(NAME##View && "RegisterCodeGenFlags not created.");                 \
275ffd83dbSDimitry Andric     return *NAME##View;                                                        \
285ffd83dbSDimitry Andric   }
295ffd83dbSDimitry Andric 
305ffd83dbSDimitry Andric #define CGLIST(TY, NAME)                                                       \
315ffd83dbSDimitry Andric   static cl::list<TY> *NAME##View;                                             \
325ffd83dbSDimitry Andric   std::vector<TY> codegen::get##NAME() {                                       \
335ffd83dbSDimitry Andric     assert(NAME##View && "RegisterCodeGenFlags not created.");                 \
345ffd83dbSDimitry Andric     return *NAME##View;                                                        \
355ffd83dbSDimitry Andric   }
365ffd83dbSDimitry Andric 
375ffd83dbSDimitry Andric #define CGOPT_EXP(TY, NAME)                                                    \
385ffd83dbSDimitry Andric   CGOPT(TY, NAME)                                                              \
395ffd83dbSDimitry Andric   Optional<TY> codegen::getExplicit##NAME() {                                  \
405ffd83dbSDimitry Andric     if (NAME##View->getNumOccurrences()) {                                     \
415ffd83dbSDimitry Andric       TY res = *NAME##View;                                                    \
425ffd83dbSDimitry Andric       return res;                                                              \
435ffd83dbSDimitry Andric     }                                                                          \
445ffd83dbSDimitry Andric     return None;                                                               \
455ffd83dbSDimitry Andric   }
465ffd83dbSDimitry Andric 
475ffd83dbSDimitry Andric CGOPT(std::string, MArch)
485ffd83dbSDimitry Andric CGOPT(std::string, MCPU)
495ffd83dbSDimitry Andric CGLIST(std::string, MAttrs)
505ffd83dbSDimitry Andric CGOPT_EXP(Reloc::Model, RelocModel)
515ffd83dbSDimitry Andric CGOPT(ThreadModel::Model, ThreadModel)
525ffd83dbSDimitry Andric CGOPT_EXP(CodeModel::Model, CodeModel)
535ffd83dbSDimitry Andric CGOPT(ExceptionHandling, ExceptionModel)
545ffd83dbSDimitry Andric CGOPT_EXP(CodeGenFileType, FileType)
555ffd83dbSDimitry Andric CGOPT(FramePointer::FP, FramePointerUsage)
565ffd83dbSDimitry Andric CGOPT(bool, EnableUnsafeFPMath)
575ffd83dbSDimitry Andric CGOPT(bool, EnableNoInfsFPMath)
585ffd83dbSDimitry Andric CGOPT(bool, EnableNoNaNsFPMath)
595ffd83dbSDimitry Andric CGOPT(bool, EnableNoSignedZerosFPMath)
605ffd83dbSDimitry Andric CGOPT(bool, EnableNoTrappingFPMath)
61*e8d8bef9SDimitry Andric CGOPT(bool, EnableAIXExtendedAltivecABI)
625ffd83dbSDimitry Andric CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath)
635ffd83dbSDimitry Andric CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)
645ffd83dbSDimitry Andric CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
655ffd83dbSDimitry Andric CGOPT(FloatABI::ABIType, FloatABIForCalls)
665ffd83dbSDimitry Andric CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)
675ffd83dbSDimitry Andric CGOPT(bool, DontPlaceZerosInBSS)
685ffd83dbSDimitry Andric CGOPT(bool, EnableGuaranteedTailCallOpt)
695ffd83dbSDimitry Andric CGOPT(bool, DisableTailCalls)
705ffd83dbSDimitry Andric CGOPT(bool, StackSymbolOrdering)
715ffd83dbSDimitry Andric CGOPT(unsigned, OverrideStackAlignment)
725ffd83dbSDimitry Andric CGOPT(bool, StackRealign)
735ffd83dbSDimitry Andric CGOPT(std::string, TrapFuncName)
745ffd83dbSDimitry Andric CGOPT(bool, UseCtors)
755ffd83dbSDimitry Andric CGOPT(bool, RelaxELFRelocations)
765ffd83dbSDimitry Andric CGOPT_EXP(bool, DataSections)
775ffd83dbSDimitry Andric CGOPT_EXP(bool, FunctionSections)
78*e8d8bef9SDimitry Andric CGOPT(bool, IgnoreXCOFFVisibility)
79*e8d8bef9SDimitry Andric CGOPT(bool, XCOFFTracebackTable)
805ffd83dbSDimitry Andric CGOPT(std::string, BBSections)
81*e8d8bef9SDimitry Andric CGOPT(std::string, StackProtectorGuard)
82*e8d8bef9SDimitry Andric CGOPT(unsigned, StackProtectorGuardOffset)
83*e8d8bef9SDimitry Andric CGOPT(std::string, StackProtectorGuardReg)
845ffd83dbSDimitry Andric CGOPT(unsigned, TLSSize)
855ffd83dbSDimitry Andric CGOPT(bool, EmulatedTLS)
865ffd83dbSDimitry Andric CGOPT(bool, UniqueSectionNames)
875ffd83dbSDimitry Andric CGOPT(bool, UniqueBasicBlockSectionNames)
885ffd83dbSDimitry Andric CGOPT(EABI, EABIVersion)
895ffd83dbSDimitry Andric CGOPT(DebuggerKind, DebuggerTuningOpt)
905ffd83dbSDimitry Andric CGOPT(bool, EnableStackSizeSection)
915ffd83dbSDimitry Andric CGOPT(bool, EnableAddrsig)
925ffd83dbSDimitry Andric CGOPT(bool, EmitCallSiteInfo)
93*e8d8bef9SDimitry Andric CGOPT(bool, EnableMachineFunctionSplitter)
945ffd83dbSDimitry Andric CGOPT(bool, EnableDebugEntryValues)
95*e8d8bef9SDimitry Andric CGOPT(bool, PseudoProbeForProfiling)
96*e8d8bef9SDimitry Andric CGOPT(bool, ValueTrackingVariableLocations)
975ffd83dbSDimitry Andric CGOPT(bool, ForceDwarfFrameSection)
985ffd83dbSDimitry Andric CGOPT(bool, XRayOmitFunctionIndex)
995ffd83dbSDimitry Andric 
1005ffd83dbSDimitry Andric codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
1015ffd83dbSDimitry Andric #define CGBINDOPT(NAME)                                                        \
1025ffd83dbSDimitry Andric   do {                                                                         \
1035ffd83dbSDimitry Andric     NAME##View = std::addressof(NAME);                                         \
1045ffd83dbSDimitry Andric   } while (0)
1055ffd83dbSDimitry Andric 
1065ffd83dbSDimitry Andric   static cl::opt<std::string> MArch(
1075ffd83dbSDimitry Andric       "march", cl::desc("Architecture to generate code for (see --version)"));
1085ffd83dbSDimitry Andric   CGBINDOPT(MArch);
1095ffd83dbSDimitry Andric 
1105ffd83dbSDimitry Andric   static cl::opt<std::string> MCPU(
1115ffd83dbSDimitry Andric       "mcpu", cl::desc("Target a specific cpu type (-mcpu=help for details)"),
1125ffd83dbSDimitry Andric       cl::value_desc("cpu-name"), cl::init(""));
1135ffd83dbSDimitry Andric   CGBINDOPT(MCPU);
1145ffd83dbSDimitry Andric 
1155ffd83dbSDimitry Andric   static cl::list<std::string> MAttrs(
1165ffd83dbSDimitry Andric       "mattr", cl::CommaSeparated,
1175ffd83dbSDimitry Andric       cl::desc("Target specific attributes (-mattr=help for details)"),
1185ffd83dbSDimitry Andric       cl::value_desc("a1,+a2,-a3,..."));
1195ffd83dbSDimitry Andric   CGBINDOPT(MAttrs);
1205ffd83dbSDimitry Andric 
1215ffd83dbSDimitry Andric   static cl::opt<Reloc::Model> RelocModel(
1225ffd83dbSDimitry Andric       "relocation-model", cl::desc("Choose relocation model"),
1235ffd83dbSDimitry Andric       cl::values(
1245ffd83dbSDimitry Andric           clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
1255ffd83dbSDimitry Andric           clEnumValN(Reloc::PIC_, "pic",
1265ffd83dbSDimitry Andric                      "Fully relocatable, position independent code"),
1275ffd83dbSDimitry Andric           clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
1285ffd83dbSDimitry Andric                      "Relocatable external references, non-relocatable code"),
1295ffd83dbSDimitry Andric           clEnumValN(
1305ffd83dbSDimitry Andric               Reloc::ROPI, "ropi",
1315ffd83dbSDimitry Andric               "Code and read-only data relocatable, accessed PC-relative"),
1325ffd83dbSDimitry Andric           clEnumValN(
1335ffd83dbSDimitry Andric               Reloc::RWPI, "rwpi",
1345ffd83dbSDimitry Andric               "Read-write data relocatable, accessed relative to static base"),
1355ffd83dbSDimitry Andric           clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
1365ffd83dbSDimitry Andric                      "Combination of ropi and rwpi")));
1375ffd83dbSDimitry Andric   CGBINDOPT(RelocModel);
1385ffd83dbSDimitry Andric 
1395ffd83dbSDimitry Andric   static cl::opt<ThreadModel::Model> ThreadModel(
1405ffd83dbSDimitry Andric       "thread-model", cl::desc("Choose threading model"),
1415ffd83dbSDimitry Andric       cl::init(ThreadModel::POSIX),
1425ffd83dbSDimitry Andric       cl::values(
1435ffd83dbSDimitry Andric           clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
1445ffd83dbSDimitry Andric           clEnumValN(ThreadModel::Single, "single", "Single thread model")));
1455ffd83dbSDimitry Andric   CGBINDOPT(ThreadModel);
1465ffd83dbSDimitry Andric 
1475ffd83dbSDimitry Andric   static cl::opt<CodeModel::Model> CodeModel(
1485ffd83dbSDimitry Andric       "code-model", cl::desc("Choose code model"),
1495ffd83dbSDimitry Andric       cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),
1505ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Small, "small", "Small code model"),
1515ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
1525ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
1535ffd83dbSDimitry Andric                  clEnumValN(CodeModel::Large, "large", "Large code model")));
1545ffd83dbSDimitry Andric   CGBINDOPT(CodeModel);
1555ffd83dbSDimitry Andric 
1565ffd83dbSDimitry Andric   static cl::opt<ExceptionHandling> ExceptionModel(
1575ffd83dbSDimitry Andric       "exception-model", cl::desc("exception model"),
1585ffd83dbSDimitry Andric       cl::init(ExceptionHandling::None),
1595ffd83dbSDimitry Andric       cl::values(
1605ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::None, "default",
1615ffd83dbSDimitry Andric                      "default exception handling model"),
1625ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
1635ffd83dbSDimitry Andric                      "DWARF-like CFI based exception handling"),
1645ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::SjLj, "sjlj",
1655ffd83dbSDimitry Andric                      "SjLj exception handling"),
1665ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
1675ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::WinEH, "wineh",
1685ffd83dbSDimitry Andric                      "Windows exception model"),
1695ffd83dbSDimitry Andric           clEnumValN(ExceptionHandling::Wasm, "wasm",
1705ffd83dbSDimitry Andric                      "WebAssembly exception handling")));
1715ffd83dbSDimitry Andric   CGBINDOPT(ExceptionModel);
1725ffd83dbSDimitry Andric 
1735ffd83dbSDimitry Andric   static cl::opt<CodeGenFileType> FileType(
1745ffd83dbSDimitry Andric       "filetype", cl::init(CGFT_AssemblyFile),
1755ffd83dbSDimitry Andric       cl::desc(
1765ffd83dbSDimitry Andric           "Choose a file type (not all types are supported by all targets):"),
1775ffd83dbSDimitry Andric       cl::values(
1785ffd83dbSDimitry Andric           clEnumValN(CGFT_AssemblyFile, "asm", "Emit an assembly ('.s') file"),
1795ffd83dbSDimitry Andric           clEnumValN(CGFT_ObjectFile, "obj",
1805ffd83dbSDimitry Andric                      "Emit a native object ('.o') file"),
1815ffd83dbSDimitry Andric           clEnumValN(CGFT_Null, "null",
1825ffd83dbSDimitry Andric                      "Emit nothing, for performance testing")));
1835ffd83dbSDimitry Andric   CGBINDOPT(FileType);
1845ffd83dbSDimitry Andric 
1855ffd83dbSDimitry Andric   static cl::opt<FramePointer::FP> FramePointerUsage(
1865ffd83dbSDimitry Andric       "frame-pointer",
1875ffd83dbSDimitry Andric       cl::desc("Specify frame pointer elimination optimization"),
1885ffd83dbSDimitry Andric       cl::init(FramePointer::None),
1895ffd83dbSDimitry Andric       cl::values(
1905ffd83dbSDimitry Andric           clEnumValN(FramePointer::All, "all",
1915ffd83dbSDimitry Andric                      "Disable frame pointer elimination"),
1925ffd83dbSDimitry Andric           clEnumValN(FramePointer::NonLeaf, "non-leaf",
1935ffd83dbSDimitry Andric                      "Disable frame pointer elimination for non-leaf frame"),
1945ffd83dbSDimitry Andric           clEnumValN(FramePointer::None, "none",
1955ffd83dbSDimitry Andric                      "Enable frame pointer elimination")));
1965ffd83dbSDimitry Andric   CGBINDOPT(FramePointerUsage);
1975ffd83dbSDimitry Andric 
1985ffd83dbSDimitry Andric   static cl::opt<bool> EnableUnsafeFPMath(
1995ffd83dbSDimitry Andric       "enable-unsafe-fp-math",
2005ffd83dbSDimitry Andric       cl::desc("Enable optimizations that may decrease FP precision"),
2015ffd83dbSDimitry Andric       cl::init(false));
2025ffd83dbSDimitry Andric   CGBINDOPT(EnableUnsafeFPMath);
2035ffd83dbSDimitry Andric 
2045ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoInfsFPMath(
2055ffd83dbSDimitry Andric       "enable-no-infs-fp-math",
2065ffd83dbSDimitry Andric       cl::desc("Enable FP math optimizations that assume no +-Infs"),
2075ffd83dbSDimitry Andric       cl::init(false));
2085ffd83dbSDimitry Andric   CGBINDOPT(EnableNoInfsFPMath);
2095ffd83dbSDimitry Andric 
2105ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoNaNsFPMath(
2115ffd83dbSDimitry Andric       "enable-no-nans-fp-math",
2125ffd83dbSDimitry Andric       cl::desc("Enable FP math optimizations that assume no NaNs"),
2135ffd83dbSDimitry Andric       cl::init(false));
2145ffd83dbSDimitry Andric   CGBINDOPT(EnableNoNaNsFPMath);
2155ffd83dbSDimitry Andric 
2165ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoSignedZerosFPMath(
2175ffd83dbSDimitry Andric       "enable-no-signed-zeros-fp-math",
2185ffd83dbSDimitry Andric       cl::desc("Enable FP math optimizations that assume "
2195ffd83dbSDimitry Andric                "the sign of 0 is insignificant"),
2205ffd83dbSDimitry Andric       cl::init(false));
2215ffd83dbSDimitry Andric   CGBINDOPT(EnableNoSignedZerosFPMath);
2225ffd83dbSDimitry Andric 
2235ffd83dbSDimitry Andric   static cl::opt<bool> EnableNoTrappingFPMath(
2245ffd83dbSDimitry Andric       "enable-no-trapping-fp-math",
2255ffd83dbSDimitry Andric       cl::desc("Enable setting the FP exceptions build "
2265ffd83dbSDimitry Andric                "attribute not to use exceptions"),
2275ffd83dbSDimitry Andric       cl::init(false));
2285ffd83dbSDimitry Andric   CGBINDOPT(EnableNoTrappingFPMath);
2295ffd83dbSDimitry Andric 
2305ffd83dbSDimitry Andric   static const auto DenormFlagEnumOptions =
2315ffd83dbSDimitry Andric   cl::values(clEnumValN(DenormalMode::IEEE, "ieee",
2325ffd83dbSDimitry Andric                         "IEEE 754 denormal numbers"),
2335ffd83dbSDimitry Andric              clEnumValN(DenormalMode::PreserveSign, "preserve-sign",
2345ffd83dbSDimitry Andric                         "the sign of a  flushed-to-zero number is preserved "
2355ffd83dbSDimitry Andric                         "in the sign of 0"),
2365ffd83dbSDimitry Andric              clEnumValN(DenormalMode::PositiveZero, "positive-zero",
2375ffd83dbSDimitry Andric                         "denormals are flushed to positive zero"));
2385ffd83dbSDimitry Andric 
2395ffd83dbSDimitry Andric   // FIXME: Doesn't have way to specify separate input and output modes.
2405ffd83dbSDimitry Andric   static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath(
2415ffd83dbSDimitry Andric     "denormal-fp-math",
2425ffd83dbSDimitry Andric     cl::desc("Select which denormal numbers the code is permitted to require"),
2435ffd83dbSDimitry Andric     cl::init(DenormalMode::IEEE),
2445ffd83dbSDimitry Andric     DenormFlagEnumOptions);
2455ffd83dbSDimitry Andric   CGBINDOPT(DenormalFPMath);
2465ffd83dbSDimitry Andric 
2475ffd83dbSDimitry Andric   static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math(
2485ffd83dbSDimitry Andric     "denormal-fp-math-f32",
2495ffd83dbSDimitry Andric     cl::desc("Select which denormal numbers the code is permitted to require for float"),
2505ffd83dbSDimitry Andric     cl::init(DenormalMode::Invalid),
2515ffd83dbSDimitry Andric     DenormFlagEnumOptions);
2525ffd83dbSDimitry Andric   CGBINDOPT(DenormalFP32Math);
2535ffd83dbSDimitry Andric 
2545ffd83dbSDimitry Andric   static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
2555ffd83dbSDimitry Andric       "enable-sign-dependent-rounding-fp-math", cl::Hidden,
2565ffd83dbSDimitry Andric       cl::desc("Force codegen to assume rounding mode can change dynamically"),
2575ffd83dbSDimitry Andric       cl::init(false));
2585ffd83dbSDimitry Andric   CGBINDOPT(EnableHonorSignDependentRoundingFPMath);
2595ffd83dbSDimitry Andric 
2605ffd83dbSDimitry Andric   static cl::opt<FloatABI::ABIType> FloatABIForCalls(
2615ffd83dbSDimitry Andric       "float-abi", cl::desc("Choose float ABI type"),
2625ffd83dbSDimitry Andric       cl::init(FloatABI::Default),
2635ffd83dbSDimitry Andric       cl::values(clEnumValN(FloatABI::Default, "default",
2645ffd83dbSDimitry Andric                             "Target default float ABI type"),
2655ffd83dbSDimitry Andric                  clEnumValN(FloatABI::Soft, "soft",
2665ffd83dbSDimitry Andric                             "Soft float ABI (implied by -soft-float)"),
2675ffd83dbSDimitry Andric                  clEnumValN(FloatABI::Hard, "hard",
2685ffd83dbSDimitry Andric                             "Hard float ABI (uses FP registers)")));
2695ffd83dbSDimitry Andric   CGBINDOPT(FloatABIForCalls);
2705ffd83dbSDimitry Andric 
2715ffd83dbSDimitry Andric   static cl::opt<FPOpFusion::FPOpFusionMode> FuseFPOps(
2725ffd83dbSDimitry Andric       "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
2735ffd83dbSDimitry Andric       cl::init(FPOpFusion::Standard),
2745ffd83dbSDimitry Andric       cl::values(
2755ffd83dbSDimitry Andric           clEnumValN(FPOpFusion::Fast, "fast",
2765ffd83dbSDimitry Andric                      "Fuse FP ops whenever profitable"),
2775ffd83dbSDimitry Andric           clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
2785ffd83dbSDimitry Andric           clEnumValN(FPOpFusion::Strict, "off",
2795ffd83dbSDimitry Andric                      "Only fuse FP ops when the result won't be affected.")));
2805ffd83dbSDimitry Andric   CGBINDOPT(FuseFPOps);
2815ffd83dbSDimitry Andric 
2825ffd83dbSDimitry Andric   static cl::opt<bool> DontPlaceZerosInBSS(
2835ffd83dbSDimitry Andric       "nozero-initialized-in-bss",
2845ffd83dbSDimitry Andric       cl::desc("Don't place zero-initialized symbols into bss section"),
2855ffd83dbSDimitry Andric       cl::init(false));
2865ffd83dbSDimitry Andric   CGBINDOPT(DontPlaceZerosInBSS);
2875ffd83dbSDimitry Andric 
288*e8d8bef9SDimitry Andric   static cl::opt<bool> EnableAIXExtendedAltivecABI(
289*e8d8bef9SDimitry Andric       "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),
290*e8d8bef9SDimitry Andric       cl::init(false));
291*e8d8bef9SDimitry Andric   CGBINDOPT(EnableAIXExtendedAltivecABI);
292*e8d8bef9SDimitry Andric 
2935ffd83dbSDimitry Andric   static cl::opt<bool> EnableGuaranteedTailCallOpt(
2945ffd83dbSDimitry Andric       "tailcallopt",
2955ffd83dbSDimitry Andric       cl::desc(
2965ffd83dbSDimitry Andric           "Turn fastcc calls into tail calls by (potentially) changing ABI."),
2975ffd83dbSDimitry Andric       cl::init(false));
2985ffd83dbSDimitry Andric   CGBINDOPT(EnableGuaranteedTailCallOpt);
2995ffd83dbSDimitry Andric 
3005ffd83dbSDimitry Andric   static cl::opt<bool> DisableTailCalls(
3015ffd83dbSDimitry Andric       "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false));
3025ffd83dbSDimitry Andric   CGBINDOPT(DisableTailCalls);
3035ffd83dbSDimitry Andric 
3045ffd83dbSDimitry Andric   static cl::opt<bool> StackSymbolOrdering(
3055ffd83dbSDimitry Andric       "stack-symbol-ordering", cl::desc("Order local stack symbols."),
3065ffd83dbSDimitry Andric       cl::init(true));
3075ffd83dbSDimitry Andric   CGBINDOPT(StackSymbolOrdering);
3085ffd83dbSDimitry Andric 
3095ffd83dbSDimitry Andric   static cl::opt<unsigned> OverrideStackAlignment(
3105ffd83dbSDimitry Andric       "stack-alignment", cl::desc("Override default stack alignment"),
3115ffd83dbSDimitry Andric       cl::init(0));
3125ffd83dbSDimitry Andric   CGBINDOPT(OverrideStackAlignment);
3135ffd83dbSDimitry Andric 
3145ffd83dbSDimitry Andric   static cl::opt<bool> StackRealign(
3155ffd83dbSDimitry Andric       "stackrealign",
3165ffd83dbSDimitry Andric       cl::desc("Force align the stack to the minimum alignment"),
3175ffd83dbSDimitry Andric       cl::init(false));
3185ffd83dbSDimitry Andric   CGBINDOPT(StackRealign);
3195ffd83dbSDimitry Andric 
3205ffd83dbSDimitry Andric   static cl::opt<std::string> TrapFuncName(
3215ffd83dbSDimitry Andric       "trap-func", cl::Hidden,
3225ffd83dbSDimitry Andric       cl::desc("Emit a call to trap function rather than a trap instruction"),
3235ffd83dbSDimitry Andric       cl::init(""));
3245ffd83dbSDimitry Andric   CGBINDOPT(TrapFuncName);
3255ffd83dbSDimitry Andric 
3265ffd83dbSDimitry Andric   static cl::opt<bool> UseCtors("use-ctors",
3275ffd83dbSDimitry Andric                                 cl::desc("Use .ctors instead of .init_array."),
3285ffd83dbSDimitry Andric                                 cl::init(false));
3295ffd83dbSDimitry Andric   CGBINDOPT(UseCtors);
3305ffd83dbSDimitry Andric 
3315ffd83dbSDimitry Andric   static cl::opt<bool> RelaxELFRelocations(
3325ffd83dbSDimitry Andric       "relax-elf-relocations",
3335ffd83dbSDimitry Andric       cl::desc(
3345ffd83dbSDimitry Andric           "Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
3355ffd83dbSDimitry Andric       cl::init(false));
3365ffd83dbSDimitry Andric   CGBINDOPT(RelaxELFRelocations);
3375ffd83dbSDimitry Andric 
3385ffd83dbSDimitry Andric   static cl::opt<bool> DataSections(
3395ffd83dbSDimitry Andric       "data-sections", cl::desc("Emit data into separate sections"),
3405ffd83dbSDimitry Andric       cl::init(false));
3415ffd83dbSDimitry Andric   CGBINDOPT(DataSections);
3425ffd83dbSDimitry Andric 
3435ffd83dbSDimitry Andric   static cl::opt<bool> FunctionSections(
3445ffd83dbSDimitry Andric       "function-sections", cl::desc("Emit functions into separate sections"),
3455ffd83dbSDimitry Andric       cl::init(false));
3465ffd83dbSDimitry Andric   CGBINDOPT(FunctionSections);
3475ffd83dbSDimitry Andric 
348*e8d8bef9SDimitry Andric   static cl::opt<bool> IgnoreXCOFFVisibility(
349*e8d8bef9SDimitry Andric       "ignore-xcoff-visibility",
350*e8d8bef9SDimitry Andric       cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
351*e8d8bef9SDimitry Andric                "all symbols 'unspecified' visibility in XCOFF object file"),
352*e8d8bef9SDimitry Andric       cl::init(false));
353*e8d8bef9SDimitry Andric   CGBINDOPT(IgnoreXCOFFVisibility);
354*e8d8bef9SDimitry Andric 
355*e8d8bef9SDimitry Andric   static cl::opt<bool> XCOFFTracebackTable(
356*e8d8bef9SDimitry Andric       "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
357*e8d8bef9SDimitry Andric       cl::init(true));
358*e8d8bef9SDimitry Andric   CGBINDOPT(XCOFFTracebackTable);
359*e8d8bef9SDimitry Andric 
3605ffd83dbSDimitry Andric   static cl::opt<std::string> BBSections(
361*e8d8bef9SDimitry Andric       "basic-block-sections",
3625ffd83dbSDimitry Andric       cl::desc("Emit basic blocks into separate sections"),
3635ffd83dbSDimitry Andric       cl::value_desc("all | <function list (file)> | labels | none"),
3645ffd83dbSDimitry Andric       cl::init("none"));
3655ffd83dbSDimitry Andric   CGBINDOPT(BBSections);
3665ffd83dbSDimitry Andric 
367*e8d8bef9SDimitry Andric   static cl::opt<std::string> StackProtectorGuard(
368*e8d8bef9SDimitry Andric       "stack-protector-guard", cl::desc("Stack protector guard mode"),
369*e8d8bef9SDimitry Andric       cl::init("none"));
370*e8d8bef9SDimitry Andric   CGBINDOPT(StackProtectorGuard);
371*e8d8bef9SDimitry Andric 
372*e8d8bef9SDimitry Andric   static cl::opt<std::string> StackProtectorGuardReg(
373*e8d8bef9SDimitry Andric       "stack-protector-guard-reg", cl::desc("Stack protector guard register"),
374*e8d8bef9SDimitry Andric       cl::init("none"));
375*e8d8bef9SDimitry Andric   CGBINDOPT(StackProtectorGuardReg);
376*e8d8bef9SDimitry Andric 
377*e8d8bef9SDimitry Andric   static cl::opt<unsigned> StackProtectorGuardOffset(
378*e8d8bef9SDimitry Andric       "stack-protector-guard-offset", cl::desc("Stack protector guard offset"),
379*e8d8bef9SDimitry Andric       cl::init((unsigned)-1));
380*e8d8bef9SDimitry Andric   CGBINDOPT(StackProtectorGuardOffset);
381*e8d8bef9SDimitry Andric 
3825ffd83dbSDimitry Andric   static cl::opt<unsigned> TLSSize(
3835ffd83dbSDimitry Andric       "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
3845ffd83dbSDimitry Andric   CGBINDOPT(TLSSize);
3855ffd83dbSDimitry Andric 
3865ffd83dbSDimitry Andric   static cl::opt<bool> EmulatedTLS(
3875ffd83dbSDimitry Andric       "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
3885ffd83dbSDimitry Andric   CGBINDOPT(EmulatedTLS);
3895ffd83dbSDimitry Andric 
3905ffd83dbSDimitry Andric   static cl::opt<bool> UniqueSectionNames(
3915ffd83dbSDimitry Andric       "unique-section-names", cl::desc("Give unique names to every section"),
3925ffd83dbSDimitry Andric       cl::init(true));
3935ffd83dbSDimitry Andric   CGBINDOPT(UniqueSectionNames);
3945ffd83dbSDimitry Andric 
3955ffd83dbSDimitry Andric   static cl::opt<bool> UniqueBasicBlockSectionNames(
396*e8d8bef9SDimitry Andric       "unique-basic-block-section-names",
3975ffd83dbSDimitry Andric       cl::desc("Give unique names to every basic block section"),
3985ffd83dbSDimitry Andric       cl::init(false));
3995ffd83dbSDimitry Andric   CGBINDOPT(UniqueBasicBlockSectionNames);
4005ffd83dbSDimitry Andric 
4015ffd83dbSDimitry Andric   static cl::opt<EABI> EABIVersion(
4025ffd83dbSDimitry Andric       "meabi", cl::desc("Set EABI type (default depends on triple):"),
4035ffd83dbSDimitry Andric       cl::init(EABI::Default),
4045ffd83dbSDimitry Andric       cl::values(
4055ffd83dbSDimitry Andric           clEnumValN(EABI::Default, "default", "Triple default EABI version"),
4065ffd83dbSDimitry Andric           clEnumValN(EABI::EABI4, "4", "EABI version 4"),
4075ffd83dbSDimitry Andric           clEnumValN(EABI::EABI5, "5", "EABI version 5"),
4085ffd83dbSDimitry Andric           clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
4095ffd83dbSDimitry Andric   CGBINDOPT(EABIVersion);
4105ffd83dbSDimitry Andric 
4115ffd83dbSDimitry Andric   static cl::opt<DebuggerKind> DebuggerTuningOpt(
4125ffd83dbSDimitry Andric       "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
4135ffd83dbSDimitry Andric       cl::init(DebuggerKind::Default),
4145ffd83dbSDimitry Andric       cl::values(
4155ffd83dbSDimitry Andric           clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
4165ffd83dbSDimitry Andric           clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
4175ffd83dbSDimitry Andric           clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
4185ffd83dbSDimitry Andric   CGBINDOPT(DebuggerTuningOpt);
4195ffd83dbSDimitry Andric 
4205ffd83dbSDimitry Andric   static cl::opt<bool> EnableStackSizeSection(
4215ffd83dbSDimitry Andric       "stack-size-section",
4225ffd83dbSDimitry Andric       cl::desc("Emit a section containing stack size metadata"),
4235ffd83dbSDimitry Andric       cl::init(false));
4245ffd83dbSDimitry Andric   CGBINDOPT(EnableStackSizeSection);
4255ffd83dbSDimitry Andric 
4265ffd83dbSDimitry Andric   static cl::opt<bool> EnableAddrsig(
4275ffd83dbSDimitry Andric       "addrsig", cl::desc("Emit an address-significance table"),
4285ffd83dbSDimitry Andric       cl::init(false));
4295ffd83dbSDimitry Andric   CGBINDOPT(EnableAddrsig);
4305ffd83dbSDimitry Andric 
4315ffd83dbSDimitry Andric   static cl::opt<bool> EmitCallSiteInfo(
4325ffd83dbSDimitry Andric       "emit-call-site-info",
4335ffd83dbSDimitry Andric       cl::desc(
4345ffd83dbSDimitry Andric           "Emit call site debug information, if debug information is enabled."),
4355ffd83dbSDimitry Andric       cl::init(false));
4365ffd83dbSDimitry Andric   CGBINDOPT(EmitCallSiteInfo);
4375ffd83dbSDimitry Andric 
4385ffd83dbSDimitry Andric   static cl::opt<bool> EnableDebugEntryValues(
4395ffd83dbSDimitry Andric       "debug-entry-values",
4405ffd83dbSDimitry Andric       cl::desc("Enable debug info for the debug entry values."),
4415ffd83dbSDimitry Andric       cl::init(false));
4425ffd83dbSDimitry Andric   CGBINDOPT(EnableDebugEntryValues);
4435ffd83dbSDimitry Andric 
444*e8d8bef9SDimitry Andric   static cl::opt<bool> PseudoProbeForProfiling(
445*e8d8bef9SDimitry Andric       "pseudo-probe-for-profiling", cl::desc("Emit pseudo probes for AutoFDO"),
446*e8d8bef9SDimitry Andric       cl::init(false));
447*e8d8bef9SDimitry Andric   CGBINDOPT(PseudoProbeForProfiling);
448*e8d8bef9SDimitry Andric 
449*e8d8bef9SDimitry Andric   static cl::opt<bool> ValueTrackingVariableLocations(
450*e8d8bef9SDimitry Andric       "experimental-debug-variable-locations",
451*e8d8bef9SDimitry Andric       cl::desc("Use experimental new value-tracking variable locations"),
452*e8d8bef9SDimitry Andric       cl::init(false));
453*e8d8bef9SDimitry Andric   CGBINDOPT(ValueTrackingVariableLocations);
454*e8d8bef9SDimitry Andric 
455*e8d8bef9SDimitry Andric   static cl::opt<bool> EnableMachineFunctionSplitter(
456*e8d8bef9SDimitry Andric       "split-machine-functions",
457*e8d8bef9SDimitry Andric       cl::desc("Split out cold basic blocks from machine functions based on "
458*e8d8bef9SDimitry Andric                "profile information"),
459*e8d8bef9SDimitry Andric       cl::init(false));
460*e8d8bef9SDimitry Andric   CGBINDOPT(EnableMachineFunctionSplitter);
461*e8d8bef9SDimitry Andric 
4625ffd83dbSDimitry Andric   static cl::opt<bool> ForceDwarfFrameSection(
4635ffd83dbSDimitry Andric       "force-dwarf-frame-section",
4645ffd83dbSDimitry Andric       cl::desc("Always emit a debug frame section."), cl::init(false));
4655ffd83dbSDimitry Andric   CGBINDOPT(ForceDwarfFrameSection);
4665ffd83dbSDimitry Andric 
4675ffd83dbSDimitry Andric   static cl::opt<bool> XRayOmitFunctionIndex(
4685ffd83dbSDimitry Andric       "no-xray-index", cl::desc("Don't emit xray_fn_idx section"),
4695ffd83dbSDimitry Andric       cl::init(false));
4705ffd83dbSDimitry Andric   CGBINDOPT(XRayOmitFunctionIndex);
4715ffd83dbSDimitry Andric 
4725ffd83dbSDimitry Andric #undef CGBINDOPT
4735ffd83dbSDimitry Andric 
4745ffd83dbSDimitry Andric   mc::RegisterMCTargetOptionsFlags();
4755ffd83dbSDimitry Andric }
4765ffd83dbSDimitry Andric 
4775ffd83dbSDimitry Andric llvm::BasicBlockSection
4785ffd83dbSDimitry Andric codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
4795ffd83dbSDimitry Andric   if (getBBSections() == "all")
4805ffd83dbSDimitry Andric     return BasicBlockSection::All;
4815ffd83dbSDimitry Andric   else if (getBBSections() == "labels")
4825ffd83dbSDimitry Andric     return BasicBlockSection::Labels;
4835ffd83dbSDimitry Andric   else if (getBBSections() == "none")
4845ffd83dbSDimitry Andric     return BasicBlockSection::None;
4855ffd83dbSDimitry Andric   else {
4865ffd83dbSDimitry Andric     ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
4875ffd83dbSDimitry Andric         MemoryBuffer::getFile(getBBSections());
4885ffd83dbSDimitry Andric     if (!MBOrErr) {
4895ffd83dbSDimitry Andric       errs() << "Error loading basic block sections function list file: "
4905ffd83dbSDimitry Andric              << MBOrErr.getError().message() << "\n";
4915ffd83dbSDimitry Andric     } else {
4925ffd83dbSDimitry Andric       Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
4935ffd83dbSDimitry Andric     }
4945ffd83dbSDimitry Andric     return BasicBlockSection::List;
4955ffd83dbSDimitry Andric   }
4965ffd83dbSDimitry Andric }
4975ffd83dbSDimitry Andric 
498*e8d8bef9SDimitry Andric llvm::StackProtectorGuards
499*e8d8bef9SDimitry Andric codegen::getStackProtectorGuardMode(llvm::TargetOptions &Options) {
500*e8d8bef9SDimitry Andric   if (getStackProtectorGuard() == "tls")
501*e8d8bef9SDimitry Andric     return StackProtectorGuards::TLS;
502*e8d8bef9SDimitry Andric   if (getStackProtectorGuard() == "global")
503*e8d8bef9SDimitry Andric     return StackProtectorGuards::Global;
504*e8d8bef9SDimitry Andric   if (getStackProtectorGuard() != "none") {
505*e8d8bef9SDimitry Andric     ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
506*e8d8bef9SDimitry Andric         MemoryBuffer::getFile(getStackProtectorGuard());
507*e8d8bef9SDimitry Andric     if (!MBOrErr)
508*e8d8bef9SDimitry Andric       errs() << "error illegal stack protector guard mode: "
509*e8d8bef9SDimitry Andric              << MBOrErr.getError().message() << "\n";
510*e8d8bef9SDimitry Andric     else
511*e8d8bef9SDimitry Andric       Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
512*e8d8bef9SDimitry Andric   }
513*e8d8bef9SDimitry Andric   return StackProtectorGuards::None;
514*e8d8bef9SDimitry Andric }
515*e8d8bef9SDimitry Andric 
5165ffd83dbSDimitry Andric // Common utility function tightly tied to the options listed here. Initializes
5175ffd83dbSDimitry Andric // a TargetOptions object with CodeGen flags and returns it.
518*e8d8bef9SDimitry Andric TargetOptions
519*e8d8bef9SDimitry Andric codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
5205ffd83dbSDimitry Andric   TargetOptions Options;
5215ffd83dbSDimitry Andric   Options.AllowFPOpFusion = getFuseFPOps();
5225ffd83dbSDimitry Andric   Options.UnsafeFPMath = getEnableUnsafeFPMath();
5235ffd83dbSDimitry Andric   Options.NoInfsFPMath = getEnableNoInfsFPMath();
5245ffd83dbSDimitry Andric   Options.NoNaNsFPMath = getEnableNoNaNsFPMath();
5255ffd83dbSDimitry Andric   Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath();
5265ffd83dbSDimitry Andric   Options.NoTrappingFPMath = getEnableNoTrappingFPMath();
5275ffd83dbSDimitry Andric 
5285ffd83dbSDimitry Andric   DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
5295ffd83dbSDimitry Andric 
5305ffd83dbSDimitry Andric   // FIXME: Should have separate input and output flags
5315ffd83dbSDimitry Andric   Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind));
5325ffd83dbSDimitry Andric 
5335ffd83dbSDimitry Andric   Options.HonorSignDependentRoundingFPMathOption =
5345ffd83dbSDimitry Andric       getEnableHonorSignDependentRoundingFPMath();
5355ffd83dbSDimitry Andric   if (getFloatABIForCalls() != FloatABI::Default)
5365ffd83dbSDimitry Andric     Options.FloatABIType = getFloatABIForCalls();
537*e8d8bef9SDimitry Andric   Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();
5385ffd83dbSDimitry Andric   Options.NoZerosInBSS = getDontPlaceZerosInBSS();
5395ffd83dbSDimitry Andric   Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();
5405ffd83dbSDimitry Andric   Options.StackAlignmentOverride = getOverrideStackAlignment();
5415ffd83dbSDimitry Andric   Options.StackSymbolOrdering = getStackSymbolOrdering();
5425ffd83dbSDimitry Andric   Options.UseInitArray = !getUseCtors();
5435ffd83dbSDimitry Andric   Options.RelaxELFRelocations = getRelaxELFRelocations();
544*e8d8bef9SDimitry Andric   Options.DataSections =
545*e8d8bef9SDimitry Andric       getExplicitDataSections().getValueOr(TheTriple.hasDefaultDataSections());
5465ffd83dbSDimitry Andric   Options.FunctionSections = getFunctionSections();
547*e8d8bef9SDimitry Andric   Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
548*e8d8bef9SDimitry Andric   Options.XCOFFTracebackTable = getXCOFFTracebackTable();
5495ffd83dbSDimitry Andric   Options.BBSections = getBBSectionsMode(Options);
5505ffd83dbSDimitry Andric   Options.UniqueSectionNames = getUniqueSectionNames();
5515ffd83dbSDimitry Andric   Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
552*e8d8bef9SDimitry Andric   Options.StackProtectorGuard = getStackProtectorGuardMode(Options);
553*e8d8bef9SDimitry Andric   Options.StackProtectorGuardOffset = getStackProtectorGuardOffset();
554*e8d8bef9SDimitry Andric   Options.StackProtectorGuardReg = getStackProtectorGuardReg();
5555ffd83dbSDimitry Andric   Options.TLSSize = getTLSSize();
5565ffd83dbSDimitry Andric   Options.EmulatedTLS = getEmulatedTLS();
5575ffd83dbSDimitry Andric   Options.ExplicitEmulatedTLS = EmulatedTLSView->getNumOccurrences() > 0;
5585ffd83dbSDimitry Andric   Options.ExceptionModel = getExceptionModel();
5595ffd83dbSDimitry Andric   Options.EmitStackSizeSection = getEnableStackSizeSection();
560*e8d8bef9SDimitry Andric   Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
5615ffd83dbSDimitry Andric   Options.EmitAddrsig = getEnableAddrsig();
5625ffd83dbSDimitry Andric   Options.EmitCallSiteInfo = getEmitCallSiteInfo();
5635ffd83dbSDimitry Andric   Options.EnableDebugEntryValues = getEnableDebugEntryValues();
564*e8d8bef9SDimitry Andric   Options.PseudoProbeForProfiling = getPseudoProbeForProfiling();
565*e8d8bef9SDimitry Andric   Options.ValueTrackingVariableLocations = getValueTrackingVariableLocations();
5665ffd83dbSDimitry Andric   Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
5675ffd83dbSDimitry Andric   Options.XRayOmitFunctionIndex = getXRayOmitFunctionIndex();
5685ffd83dbSDimitry Andric 
5695ffd83dbSDimitry Andric   Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
5705ffd83dbSDimitry Andric 
5715ffd83dbSDimitry Andric   Options.ThreadModel = getThreadModel();
5725ffd83dbSDimitry Andric   Options.EABIVersion = getEABIVersion();
5735ffd83dbSDimitry Andric   Options.DebuggerTuning = getDebuggerTuningOpt();
5745ffd83dbSDimitry Andric 
5755ffd83dbSDimitry Andric   return Options;
5765ffd83dbSDimitry Andric }
5775ffd83dbSDimitry Andric 
5785ffd83dbSDimitry Andric std::string codegen::getCPUStr() {
5795ffd83dbSDimitry Andric   // If user asked for the 'native' CPU, autodetect here. If autodection fails,
5805ffd83dbSDimitry Andric   // this will set the CPU to an empty string which tells the target to
5815ffd83dbSDimitry Andric   // pick a basic default.
5825ffd83dbSDimitry Andric   if (getMCPU() == "native")
5835ffd83dbSDimitry Andric     return std::string(sys::getHostCPUName());
5845ffd83dbSDimitry Andric 
5855ffd83dbSDimitry Andric   return getMCPU();
5865ffd83dbSDimitry Andric }
5875ffd83dbSDimitry Andric 
5885ffd83dbSDimitry Andric std::string codegen::getFeaturesStr() {
5895ffd83dbSDimitry Andric   SubtargetFeatures Features;
5905ffd83dbSDimitry Andric 
5915ffd83dbSDimitry Andric   // If user asked for the 'native' CPU, we need to autodetect features.
5925ffd83dbSDimitry Andric   // This is necessary for x86 where the CPU might not support all the
5935ffd83dbSDimitry Andric   // features the autodetected CPU name lists in the target. For example,
5945ffd83dbSDimitry Andric   // not all Sandybridge processors support AVX.
5955ffd83dbSDimitry Andric   if (getMCPU() == "native") {
5965ffd83dbSDimitry Andric     StringMap<bool> HostFeatures;
5975ffd83dbSDimitry Andric     if (sys::getHostCPUFeatures(HostFeatures))
5985ffd83dbSDimitry Andric       for (auto &F : HostFeatures)
5995ffd83dbSDimitry Andric         Features.AddFeature(F.first(), F.second);
6005ffd83dbSDimitry Andric   }
6015ffd83dbSDimitry Andric 
6025ffd83dbSDimitry Andric   for (auto const &MAttr : getMAttrs())
6035ffd83dbSDimitry Andric     Features.AddFeature(MAttr);
6045ffd83dbSDimitry Andric 
6055ffd83dbSDimitry Andric   return Features.getString();
6065ffd83dbSDimitry Andric }
6075ffd83dbSDimitry Andric 
6085ffd83dbSDimitry Andric std::vector<std::string> codegen::getFeatureList() {
6095ffd83dbSDimitry Andric   SubtargetFeatures Features;
6105ffd83dbSDimitry Andric 
6115ffd83dbSDimitry Andric   // If user asked for the 'native' CPU, we need to autodetect features.
6125ffd83dbSDimitry Andric   // This is necessary for x86 where the CPU might not support all the
6135ffd83dbSDimitry Andric   // features the autodetected CPU name lists in the target. For example,
6145ffd83dbSDimitry Andric   // not all Sandybridge processors support AVX.
6155ffd83dbSDimitry Andric   if (getMCPU() == "native") {
6165ffd83dbSDimitry Andric     StringMap<bool> HostFeatures;
6175ffd83dbSDimitry Andric     if (sys::getHostCPUFeatures(HostFeatures))
6185ffd83dbSDimitry Andric       for (auto &F : HostFeatures)
6195ffd83dbSDimitry Andric         Features.AddFeature(F.first(), F.second);
6205ffd83dbSDimitry Andric   }
6215ffd83dbSDimitry Andric 
6225ffd83dbSDimitry Andric   for (auto const &MAttr : getMAttrs())
6235ffd83dbSDimitry Andric     Features.AddFeature(MAttr);
6245ffd83dbSDimitry Andric 
6255ffd83dbSDimitry Andric   return Features.getFeatures();
6265ffd83dbSDimitry Andric }
6275ffd83dbSDimitry Andric 
6285ffd83dbSDimitry Andric void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
6295ffd83dbSDimitry Andric   B.addAttribute(Name, Val ? "true" : "false");
6305ffd83dbSDimitry Andric }
6315ffd83dbSDimitry Andric 
6325ffd83dbSDimitry Andric #define HANDLE_BOOL_ATTR(CL, AttrName)                                         \
6335ffd83dbSDimitry Andric   do {                                                                         \
6345ffd83dbSDimitry Andric     if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName))            \
6355ffd83dbSDimitry Andric       renderBoolStringAttr(NewAttrs, AttrName, *CL);                           \
6365ffd83dbSDimitry Andric   } while (0)
6375ffd83dbSDimitry Andric 
6385ffd83dbSDimitry Andric /// Set function attributes of function \p F based on CPU, Features, and command
6395ffd83dbSDimitry Andric /// line flags.
6405ffd83dbSDimitry Andric void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
6415ffd83dbSDimitry Andric                                     Function &F) {
6425ffd83dbSDimitry Andric   auto &Ctx = F.getContext();
6435ffd83dbSDimitry Andric   AttributeList Attrs = F.getAttributes();
6445ffd83dbSDimitry Andric   AttrBuilder NewAttrs;
6455ffd83dbSDimitry Andric 
6465ffd83dbSDimitry Andric   if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
6475ffd83dbSDimitry Andric     NewAttrs.addAttribute("target-cpu", CPU);
6485ffd83dbSDimitry Andric   if (!Features.empty()) {
6495ffd83dbSDimitry Andric     // Append the command line features to any that are already on the function.
6505ffd83dbSDimitry Andric     StringRef OldFeatures =
6515ffd83dbSDimitry Andric         F.getFnAttribute("target-features").getValueAsString();
6525ffd83dbSDimitry Andric     if (OldFeatures.empty())
6535ffd83dbSDimitry Andric       NewAttrs.addAttribute("target-features", Features);
6545ffd83dbSDimitry Andric     else {
6555ffd83dbSDimitry Andric       SmallString<256> Appended(OldFeatures);
6565ffd83dbSDimitry Andric       Appended.push_back(',');
6575ffd83dbSDimitry Andric       Appended.append(Features);
6585ffd83dbSDimitry Andric       NewAttrs.addAttribute("target-features", Appended);
6595ffd83dbSDimitry Andric     }
6605ffd83dbSDimitry Andric   }
6615ffd83dbSDimitry Andric   if (FramePointerUsageView->getNumOccurrences() > 0 &&
6625ffd83dbSDimitry Andric       !F.hasFnAttribute("frame-pointer")) {
6635ffd83dbSDimitry Andric     if (getFramePointerUsage() == FramePointer::All)
6645ffd83dbSDimitry Andric       NewAttrs.addAttribute("frame-pointer", "all");
6655ffd83dbSDimitry Andric     else if (getFramePointerUsage() == FramePointer::NonLeaf)
6665ffd83dbSDimitry Andric       NewAttrs.addAttribute("frame-pointer", "non-leaf");
6675ffd83dbSDimitry Andric     else if (getFramePointerUsage() == FramePointer::None)
6685ffd83dbSDimitry Andric       NewAttrs.addAttribute("frame-pointer", "none");
6695ffd83dbSDimitry Andric   }
6705ffd83dbSDimitry Andric   if (DisableTailCallsView->getNumOccurrences() > 0)
6715ffd83dbSDimitry Andric     NewAttrs.addAttribute("disable-tail-calls",
6725ffd83dbSDimitry Andric                           toStringRef(getDisableTailCalls()));
6735ffd83dbSDimitry Andric   if (getStackRealign())
6745ffd83dbSDimitry Andric     NewAttrs.addAttribute("stackrealign");
6755ffd83dbSDimitry Andric 
6765ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math");
6775ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");
6785ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");
6795ffd83dbSDimitry Andric   HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");
6805ffd83dbSDimitry Andric 
6815ffd83dbSDimitry Andric   if (DenormalFPMathView->getNumOccurrences() > 0 &&
6825ffd83dbSDimitry Andric       !F.hasFnAttribute("denormal-fp-math")) {
6835ffd83dbSDimitry Andric     DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
6845ffd83dbSDimitry Andric 
6855ffd83dbSDimitry Andric     // FIXME: Command line flag should expose separate input/output modes.
6865ffd83dbSDimitry Andric     NewAttrs.addAttribute("denormal-fp-math",
6875ffd83dbSDimitry Andric                           DenormalMode(DenormKind, DenormKind).str());
6885ffd83dbSDimitry Andric   }
6895ffd83dbSDimitry Andric 
6905ffd83dbSDimitry Andric   if (DenormalFP32MathView->getNumOccurrences() > 0 &&
6915ffd83dbSDimitry Andric       !F.hasFnAttribute("denormal-fp-math-f32")) {
6925ffd83dbSDimitry Andric     // FIXME: Command line flag should expose separate input/output modes.
6935ffd83dbSDimitry Andric     DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math();
6945ffd83dbSDimitry Andric 
6955ffd83dbSDimitry Andric     NewAttrs.addAttribute(
6965ffd83dbSDimitry Andric       "denormal-fp-math-f32",
6975ffd83dbSDimitry Andric       DenormalMode(DenormKind, DenormKind).str());
6985ffd83dbSDimitry Andric   }
6995ffd83dbSDimitry Andric 
7005ffd83dbSDimitry Andric   if (TrapFuncNameView->getNumOccurrences() > 0)
7015ffd83dbSDimitry Andric     for (auto &B : F)
7025ffd83dbSDimitry Andric       for (auto &I : B)
7035ffd83dbSDimitry Andric         if (auto *Call = dyn_cast<CallInst>(&I))
7045ffd83dbSDimitry Andric           if (const auto *F = Call->getCalledFunction())
7055ffd83dbSDimitry Andric             if (F->getIntrinsicID() == Intrinsic::debugtrap ||
7065ffd83dbSDimitry Andric                 F->getIntrinsicID() == Intrinsic::trap)
7075ffd83dbSDimitry Andric               Call->addAttribute(
7085ffd83dbSDimitry Andric                   AttributeList::FunctionIndex,
7095ffd83dbSDimitry Andric                   Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));
7105ffd83dbSDimitry Andric 
7115ffd83dbSDimitry Andric   // Let NewAttrs override Attrs.
7125ffd83dbSDimitry Andric   F.setAttributes(
7135ffd83dbSDimitry Andric       Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
7145ffd83dbSDimitry Andric }
7155ffd83dbSDimitry Andric 
7165ffd83dbSDimitry Andric /// Set function attributes of functions in Module M based on CPU,
7175ffd83dbSDimitry Andric /// Features, and command line flags.
7185ffd83dbSDimitry Andric void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
7195ffd83dbSDimitry Andric                                     Module &M) {
7205ffd83dbSDimitry Andric   for (Function &F : M)
7215ffd83dbSDimitry Andric     setFunctionAttributes(CPU, Features, F);
7225ffd83dbSDimitry Andric }
723