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