1*5ffd83dbSDimitry Andric //===-- CommandFlags.cpp - Command Line Flags Interface ---------*- C++ -*-===// 2*5ffd83dbSDimitry Andric // 3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5ffd83dbSDimitry Andric // 7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 8*5ffd83dbSDimitry Andric // 9*5ffd83dbSDimitry Andric // This file contains codegen-specific flags that are shared between different 10*5ffd83dbSDimitry Andric // command line tools. The tools "llc" and "opt" both use this file to prevent 11*5ffd83dbSDimitry Andric // flag duplication. 12*5ffd83dbSDimitry Andric // 13*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 14*5ffd83dbSDimitry Andric 15*5ffd83dbSDimitry Andric #include "llvm/CodeGen/CommandFlags.h" 16*5ffd83dbSDimitry Andric #include "llvm/IR/Module.h" 17*5ffd83dbSDimitry Andric #include "llvm/MC/SubtargetFeature.h" 18*5ffd83dbSDimitry Andric #include "llvm/Support/CommandLine.h" 19*5ffd83dbSDimitry Andric #include "llvm/Support/Host.h" 20*5ffd83dbSDimitry Andric 21*5ffd83dbSDimitry Andric using namespace llvm; 22*5ffd83dbSDimitry Andric 23*5ffd83dbSDimitry Andric #define CGOPT(TY, NAME) \ 24*5ffd83dbSDimitry Andric static cl::opt<TY> *NAME##View; \ 25*5ffd83dbSDimitry Andric TY codegen::get##NAME() { \ 26*5ffd83dbSDimitry Andric assert(NAME##View && "RegisterCodeGenFlags not created."); \ 27*5ffd83dbSDimitry Andric return *NAME##View; \ 28*5ffd83dbSDimitry Andric } 29*5ffd83dbSDimitry Andric 30*5ffd83dbSDimitry Andric #define CGLIST(TY, NAME) \ 31*5ffd83dbSDimitry Andric static cl::list<TY> *NAME##View; \ 32*5ffd83dbSDimitry Andric std::vector<TY> codegen::get##NAME() { \ 33*5ffd83dbSDimitry Andric assert(NAME##View && "RegisterCodeGenFlags not created."); \ 34*5ffd83dbSDimitry Andric return *NAME##View; \ 35*5ffd83dbSDimitry Andric } 36*5ffd83dbSDimitry Andric 37*5ffd83dbSDimitry Andric #define CGOPT_EXP(TY, NAME) \ 38*5ffd83dbSDimitry Andric CGOPT(TY, NAME) \ 39*5ffd83dbSDimitry Andric Optional<TY> codegen::getExplicit##NAME() { \ 40*5ffd83dbSDimitry Andric if (NAME##View->getNumOccurrences()) { \ 41*5ffd83dbSDimitry Andric TY res = *NAME##View; \ 42*5ffd83dbSDimitry Andric return res; \ 43*5ffd83dbSDimitry Andric } \ 44*5ffd83dbSDimitry Andric return None; \ 45*5ffd83dbSDimitry Andric } 46*5ffd83dbSDimitry Andric 47*5ffd83dbSDimitry Andric CGOPT(std::string, MArch) 48*5ffd83dbSDimitry Andric CGOPT(std::string, MCPU) 49*5ffd83dbSDimitry Andric CGLIST(std::string, MAttrs) 50*5ffd83dbSDimitry Andric CGOPT_EXP(Reloc::Model, RelocModel) 51*5ffd83dbSDimitry Andric CGOPT(ThreadModel::Model, ThreadModel) 52*5ffd83dbSDimitry Andric CGOPT_EXP(CodeModel::Model, CodeModel) 53*5ffd83dbSDimitry Andric CGOPT(ExceptionHandling, ExceptionModel) 54*5ffd83dbSDimitry Andric CGOPT_EXP(CodeGenFileType, FileType) 55*5ffd83dbSDimitry Andric CGOPT(FramePointer::FP, FramePointerUsage) 56*5ffd83dbSDimitry Andric CGOPT(bool, EnableUnsafeFPMath) 57*5ffd83dbSDimitry Andric CGOPT(bool, EnableNoInfsFPMath) 58*5ffd83dbSDimitry Andric CGOPT(bool, EnableNoNaNsFPMath) 59*5ffd83dbSDimitry Andric CGOPT(bool, EnableNoSignedZerosFPMath) 60*5ffd83dbSDimitry Andric CGOPT(bool, EnableNoTrappingFPMath) 61*5ffd83dbSDimitry Andric CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath) 62*5ffd83dbSDimitry Andric CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math) 63*5ffd83dbSDimitry Andric CGOPT(bool, EnableHonorSignDependentRoundingFPMath) 64*5ffd83dbSDimitry Andric CGOPT(FloatABI::ABIType, FloatABIForCalls) 65*5ffd83dbSDimitry Andric CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps) 66*5ffd83dbSDimitry Andric CGOPT(bool, DontPlaceZerosInBSS) 67*5ffd83dbSDimitry Andric CGOPT(bool, EnableGuaranteedTailCallOpt) 68*5ffd83dbSDimitry Andric CGOPT(bool, DisableTailCalls) 69*5ffd83dbSDimitry Andric CGOPT(bool, StackSymbolOrdering) 70*5ffd83dbSDimitry Andric CGOPT(unsigned, OverrideStackAlignment) 71*5ffd83dbSDimitry Andric CGOPT(bool, StackRealign) 72*5ffd83dbSDimitry Andric CGOPT(std::string, TrapFuncName) 73*5ffd83dbSDimitry Andric CGOPT(bool, UseCtors) 74*5ffd83dbSDimitry Andric CGOPT(bool, RelaxELFRelocations) 75*5ffd83dbSDimitry Andric CGOPT_EXP(bool, DataSections) 76*5ffd83dbSDimitry Andric CGOPT_EXP(bool, FunctionSections) 77*5ffd83dbSDimitry Andric CGOPT(std::string, BBSections) 78*5ffd83dbSDimitry Andric CGOPT(unsigned, TLSSize) 79*5ffd83dbSDimitry Andric CGOPT(bool, EmulatedTLS) 80*5ffd83dbSDimitry Andric CGOPT(bool, UniqueSectionNames) 81*5ffd83dbSDimitry Andric CGOPT(bool, UniqueBasicBlockSectionNames) 82*5ffd83dbSDimitry Andric CGOPT(EABI, EABIVersion) 83*5ffd83dbSDimitry Andric CGOPT(DebuggerKind, DebuggerTuningOpt) 84*5ffd83dbSDimitry Andric CGOPT(bool, EnableStackSizeSection) 85*5ffd83dbSDimitry Andric CGOPT(bool, EnableAddrsig) 86*5ffd83dbSDimitry Andric CGOPT(bool, EmitCallSiteInfo) 87*5ffd83dbSDimitry Andric CGOPT(bool, EnableDebugEntryValues) 88*5ffd83dbSDimitry Andric CGOPT(bool, ForceDwarfFrameSection) 89*5ffd83dbSDimitry Andric CGOPT(bool, XRayOmitFunctionIndex) 90*5ffd83dbSDimitry Andric 91*5ffd83dbSDimitry Andric codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() { 92*5ffd83dbSDimitry Andric #define CGBINDOPT(NAME) \ 93*5ffd83dbSDimitry Andric do { \ 94*5ffd83dbSDimitry Andric NAME##View = std::addressof(NAME); \ 95*5ffd83dbSDimitry Andric } while (0) 96*5ffd83dbSDimitry Andric 97*5ffd83dbSDimitry Andric static cl::opt<std::string> MArch( 98*5ffd83dbSDimitry Andric "march", cl::desc("Architecture to generate code for (see --version)")); 99*5ffd83dbSDimitry Andric CGBINDOPT(MArch); 100*5ffd83dbSDimitry Andric 101*5ffd83dbSDimitry Andric static cl::opt<std::string> MCPU( 102*5ffd83dbSDimitry Andric "mcpu", cl::desc("Target a specific cpu type (-mcpu=help for details)"), 103*5ffd83dbSDimitry Andric cl::value_desc("cpu-name"), cl::init("")); 104*5ffd83dbSDimitry Andric CGBINDOPT(MCPU); 105*5ffd83dbSDimitry Andric 106*5ffd83dbSDimitry Andric static cl::list<std::string> MAttrs( 107*5ffd83dbSDimitry Andric "mattr", cl::CommaSeparated, 108*5ffd83dbSDimitry Andric cl::desc("Target specific attributes (-mattr=help for details)"), 109*5ffd83dbSDimitry Andric cl::value_desc("a1,+a2,-a3,...")); 110*5ffd83dbSDimitry Andric CGBINDOPT(MAttrs); 111*5ffd83dbSDimitry Andric 112*5ffd83dbSDimitry Andric static cl::opt<Reloc::Model> RelocModel( 113*5ffd83dbSDimitry Andric "relocation-model", cl::desc("Choose relocation model"), 114*5ffd83dbSDimitry Andric cl::values( 115*5ffd83dbSDimitry Andric clEnumValN(Reloc::Static, "static", "Non-relocatable code"), 116*5ffd83dbSDimitry Andric clEnumValN(Reloc::PIC_, "pic", 117*5ffd83dbSDimitry Andric "Fully relocatable, position independent code"), 118*5ffd83dbSDimitry Andric clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic", 119*5ffd83dbSDimitry Andric "Relocatable external references, non-relocatable code"), 120*5ffd83dbSDimitry Andric clEnumValN( 121*5ffd83dbSDimitry Andric Reloc::ROPI, "ropi", 122*5ffd83dbSDimitry Andric "Code and read-only data relocatable, accessed PC-relative"), 123*5ffd83dbSDimitry Andric clEnumValN( 124*5ffd83dbSDimitry Andric Reloc::RWPI, "rwpi", 125*5ffd83dbSDimitry Andric "Read-write data relocatable, accessed relative to static base"), 126*5ffd83dbSDimitry Andric clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi", 127*5ffd83dbSDimitry Andric "Combination of ropi and rwpi"))); 128*5ffd83dbSDimitry Andric CGBINDOPT(RelocModel); 129*5ffd83dbSDimitry Andric 130*5ffd83dbSDimitry Andric static cl::opt<ThreadModel::Model> ThreadModel( 131*5ffd83dbSDimitry Andric "thread-model", cl::desc("Choose threading model"), 132*5ffd83dbSDimitry Andric cl::init(ThreadModel::POSIX), 133*5ffd83dbSDimitry Andric cl::values( 134*5ffd83dbSDimitry Andric clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"), 135*5ffd83dbSDimitry Andric clEnumValN(ThreadModel::Single, "single", "Single thread model"))); 136*5ffd83dbSDimitry Andric CGBINDOPT(ThreadModel); 137*5ffd83dbSDimitry Andric 138*5ffd83dbSDimitry Andric static cl::opt<CodeModel::Model> CodeModel( 139*5ffd83dbSDimitry Andric "code-model", cl::desc("Choose code model"), 140*5ffd83dbSDimitry Andric cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"), 141*5ffd83dbSDimitry Andric clEnumValN(CodeModel::Small, "small", "Small code model"), 142*5ffd83dbSDimitry Andric clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"), 143*5ffd83dbSDimitry Andric clEnumValN(CodeModel::Medium, "medium", "Medium code model"), 144*5ffd83dbSDimitry Andric clEnumValN(CodeModel::Large, "large", "Large code model"))); 145*5ffd83dbSDimitry Andric CGBINDOPT(CodeModel); 146*5ffd83dbSDimitry Andric 147*5ffd83dbSDimitry Andric static cl::opt<ExceptionHandling> ExceptionModel( 148*5ffd83dbSDimitry Andric "exception-model", cl::desc("exception model"), 149*5ffd83dbSDimitry Andric cl::init(ExceptionHandling::None), 150*5ffd83dbSDimitry Andric cl::values( 151*5ffd83dbSDimitry Andric clEnumValN(ExceptionHandling::None, "default", 152*5ffd83dbSDimitry Andric "default exception handling model"), 153*5ffd83dbSDimitry Andric clEnumValN(ExceptionHandling::DwarfCFI, "dwarf", 154*5ffd83dbSDimitry Andric "DWARF-like CFI based exception handling"), 155*5ffd83dbSDimitry Andric clEnumValN(ExceptionHandling::SjLj, "sjlj", 156*5ffd83dbSDimitry Andric "SjLj exception handling"), 157*5ffd83dbSDimitry Andric clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"), 158*5ffd83dbSDimitry Andric clEnumValN(ExceptionHandling::WinEH, "wineh", 159*5ffd83dbSDimitry Andric "Windows exception model"), 160*5ffd83dbSDimitry Andric clEnumValN(ExceptionHandling::Wasm, "wasm", 161*5ffd83dbSDimitry Andric "WebAssembly exception handling"))); 162*5ffd83dbSDimitry Andric CGBINDOPT(ExceptionModel); 163*5ffd83dbSDimitry Andric 164*5ffd83dbSDimitry Andric static cl::opt<CodeGenFileType> FileType( 165*5ffd83dbSDimitry Andric "filetype", cl::init(CGFT_AssemblyFile), 166*5ffd83dbSDimitry Andric cl::desc( 167*5ffd83dbSDimitry Andric "Choose a file type (not all types are supported by all targets):"), 168*5ffd83dbSDimitry Andric cl::values( 169*5ffd83dbSDimitry Andric clEnumValN(CGFT_AssemblyFile, "asm", "Emit an assembly ('.s') file"), 170*5ffd83dbSDimitry Andric clEnumValN(CGFT_ObjectFile, "obj", 171*5ffd83dbSDimitry Andric "Emit a native object ('.o') file"), 172*5ffd83dbSDimitry Andric clEnumValN(CGFT_Null, "null", 173*5ffd83dbSDimitry Andric "Emit nothing, for performance testing"))); 174*5ffd83dbSDimitry Andric CGBINDOPT(FileType); 175*5ffd83dbSDimitry Andric 176*5ffd83dbSDimitry Andric static cl::opt<FramePointer::FP> FramePointerUsage( 177*5ffd83dbSDimitry Andric "frame-pointer", 178*5ffd83dbSDimitry Andric cl::desc("Specify frame pointer elimination optimization"), 179*5ffd83dbSDimitry Andric cl::init(FramePointer::None), 180*5ffd83dbSDimitry Andric cl::values( 181*5ffd83dbSDimitry Andric clEnumValN(FramePointer::All, "all", 182*5ffd83dbSDimitry Andric "Disable frame pointer elimination"), 183*5ffd83dbSDimitry Andric clEnumValN(FramePointer::NonLeaf, "non-leaf", 184*5ffd83dbSDimitry Andric "Disable frame pointer elimination for non-leaf frame"), 185*5ffd83dbSDimitry Andric clEnumValN(FramePointer::None, "none", 186*5ffd83dbSDimitry Andric "Enable frame pointer elimination"))); 187*5ffd83dbSDimitry Andric CGBINDOPT(FramePointerUsage); 188*5ffd83dbSDimitry Andric 189*5ffd83dbSDimitry Andric static cl::opt<bool> EnableUnsafeFPMath( 190*5ffd83dbSDimitry Andric "enable-unsafe-fp-math", 191*5ffd83dbSDimitry Andric cl::desc("Enable optimizations that may decrease FP precision"), 192*5ffd83dbSDimitry Andric cl::init(false)); 193*5ffd83dbSDimitry Andric CGBINDOPT(EnableUnsafeFPMath); 194*5ffd83dbSDimitry Andric 195*5ffd83dbSDimitry Andric static cl::opt<bool> EnableNoInfsFPMath( 196*5ffd83dbSDimitry Andric "enable-no-infs-fp-math", 197*5ffd83dbSDimitry Andric cl::desc("Enable FP math optimizations that assume no +-Infs"), 198*5ffd83dbSDimitry Andric cl::init(false)); 199*5ffd83dbSDimitry Andric CGBINDOPT(EnableNoInfsFPMath); 200*5ffd83dbSDimitry Andric 201*5ffd83dbSDimitry Andric static cl::opt<bool> EnableNoNaNsFPMath( 202*5ffd83dbSDimitry Andric "enable-no-nans-fp-math", 203*5ffd83dbSDimitry Andric cl::desc("Enable FP math optimizations that assume no NaNs"), 204*5ffd83dbSDimitry Andric cl::init(false)); 205*5ffd83dbSDimitry Andric CGBINDOPT(EnableNoNaNsFPMath); 206*5ffd83dbSDimitry Andric 207*5ffd83dbSDimitry Andric static cl::opt<bool> EnableNoSignedZerosFPMath( 208*5ffd83dbSDimitry Andric "enable-no-signed-zeros-fp-math", 209*5ffd83dbSDimitry Andric cl::desc("Enable FP math optimizations that assume " 210*5ffd83dbSDimitry Andric "the sign of 0 is insignificant"), 211*5ffd83dbSDimitry Andric cl::init(false)); 212*5ffd83dbSDimitry Andric CGBINDOPT(EnableNoSignedZerosFPMath); 213*5ffd83dbSDimitry Andric 214*5ffd83dbSDimitry Andric static cl::opt<bool> EnableNoTrappingFPMath( 215*5ffd83dbSDimitry Andric "enable-no-trapping-fp-math", 216*5ffd83dbSDimitry Andric cl::desc("Enable setting the FP exceptions build " 217*5ffd83dbSDimitry Andric "attribute not to use exceptions"), 218*5ffd83dbSDimitry Andric cl::init(false)); 219*5ffd83dbSDimitry Andric CGBINDOPT(EnableNoTrappingFPMath); 220*5ffd83dbSDimitry Andric 221*5ffd83dbSDimitry Andric static const auto DenormFlagEnumOptions = 222*5ffd83dbSDimitry Andric cl::values(clEnumValN(DenormalMode::IEEE, "ieee", 223*5ffd83dbSDimitry Andric "IEEE 754 denormal numbers"), 224*5ffd83dbSDimitry Andric clEnumValN(DenormalMode::PreserveSign, "preserve-sign", 225*5ffd83dbSDimitry Andric "the sign of a flushed-to-zero number is preserved " 226*5ffd83dbSDimitry Andric "in the sign of 0"), 227*5ffd83dbSDimitry Andric clEnumValN(DenormalMode::PositiveZero, "positive-zero", 228*5ffd83dbSDimitry Andric "denormals are flushed to positive zero")); 229*5ffd83dbSDimitry Andric 230*5ffd83dbSDimitry Andric // FIXME: Doesn't have way to specify separate input and output modes. 231*5ffd83dbSDimitry Andric static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath( 232*5ffd83dbSDimitry Andric "denormal-fp-math", 233*5ffd83dbSDimitry Andric cl::desc("Select which denormal numbers the code is permitted to require"), 234*5ffd83dbSDimitry Andric cl::init(DenormalMode::IEEE), 235*5ffd83dbSDimitry Andric DenormFlagEnumOptions); 236*5ffd83dbSDimitry Andric CGBINDOPT(DenormalFPMath); 237*5ffd83dbSDimitry Andric 238*5ffd83dbSDimitry Andric static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math( 239*5ffd83dbSDimitry Andric "denormal-fp-math-f32", 240*5ffd83dbSDimitry Andric cl::desc("Select which denormal numbers the code is permitted to require for float"), 241*5ffd83dbSDimitry Andric cl::init(DenormalMode::Invalid), 242*5ffd83dbSDimitry Andric DenormFlagEnumOptions); 243*5ffd83dbSDimitry Andric CGBINDOPT(DenormalFP32Math); 244*5ffd83dbSDimitry Andric 245*5ffd83dbSDimitry Andric static cl::opt<bool> EnableHonorSignDependentRoundingFPMath( 246*5ffd83dbSDimitry Andric "enable-sign-dependent-rounding-fp-math", cl::Hidden, 247*5ffd83dbSDimitry Andric cl::desc("Force codegen to assume rounding mode can change dynamically"), 248*5ffd83dbSDimitry Andric cl::init(false)); 249*5ffd83dbSDimitry Andric CGBINDOPT(EnableHonorSignDependentRoundingFPMath); 250*5ffd83dbSDimitry Andric 251*5ffd83dbSDimitry Andric static cl::opt<FloatABI::ABIType> FloatABIForCalls( 252*5ffd83dbSDimitry Andric "float-abi", cl::desc("Choose float ABI type"), 253*5ffd83dbSDimitry Andric cl::init(FloatABI::Default), 254*5ffd83dbSDimitry Andric cl::values(clEnumValN(FloatABI::Default, "default", 255*5ffd83dbSDimitry Andric "Target default float ABI type"), 256*5ffd83dbSDimitry Andric clEnumValN(FloatABI::Soft, "soft", 257*5ffd83dbSDimitry Andric "Soft float ABI (implied by -soft-float)"), 258*5ffd83dbSDimitry Andric clEnumValN(FloatABI::Hard, "hard", 259*5ffd83dbSDimitry Andric "Hard float ABI (uses FP registers)"))); 260*5ffd83dbSDimitry Andric CGBINDOPT(FloatABIForCalls); 261*5ffd83dbSDimitry Andric 262*5ffd83dbSDimitry Andric static cl::opt<FPOpFusion::FPOpFusionMode> FuseFPOps( 263*5ffd83dbSDimitry Andric "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"), 264*5ffd83dbSDimitry Andric cl::init(FPOpFusion::Standard), 265*5ffd83dbSDimitry Andric cl::values( 266*5ffd83dbSDimitry Andric clEnumValN(FPOpFusion::Fast, "fast", 267*5ffd83dbSDimitry Andric "Fuse FP ops whenever profitable"), 268*5ffd83dbSDimitry Andric clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."), 269*5ffd83dbSDimitry Andric clEnumValN(FPOpFusion::Strict, "off", 270*5ffd83dbSDimitry Andric "Only fuse FP ops when the result won't be affected."))); 271*5ffd83dbSDimitry Andric CGBINDOPT(FuseFPOps); 272*5ffd83dbSDimitry Andric 273*5ffd83dbSDimitry Andric static cl::opt<bool> DontPlaceZerosInBSS( 274*5ffd83dbSDimitry Andric "nozero-initialized-in-bss", 275*5ffd83dbSDimitry Andric cl::desc("Don't place zero-initialized symbols into bss section"), 276*5ffd83dbSDimitry Andric cl::init(false)); 277*5ffd83dbSDimitry Andric CGBINDOPT(DontPlaceZerosInBSS); 278*5ffd83dbSDimitry Andric 279*5ffd83dbSDimitry Andric static cl::opt<bool> EnableGuaranteedTailCallOpt( 280*5ffd83dbSDimitry Andric "tailcallopt", 281*5ffd83dbSDimitry Andric cl::desc( 282*5ffd83dbSDimitry Andric "Turn fastcc calls into tail calls by (potentially) changing ABI."), 283*5ffd83dbSDimitry Andric cl::init(false)); 284*5ffd83dbSDimitry Andric CGBINDOPT(EnableGuaranteedTailCallOpt); 285*5ffd83dbSDimitry Andric 286*5ffd83dbSDimitry Andric static cl::opt<bool> DisableTailCalls( 287*5ffd83dbSDimitry Andric "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false)); 288*5ffd83dbSDimitry Andric CGBINDOPT(DisableTailCalls); 289*5ffd83dbSDimitry Andric 290*5ffd83dbSDimitry Andric static cl::opt<bool> StackSymbolOrdering( 291*5ffd83dbSDimitry Andric "stack-symbol-ordering", cl::desc("Order local stack symbols."), 292*5ffd83dbSDimitry Andric cl::init(true)); 293*5ffd83dbSDimitry Andric CGBINDOPT(StackSymbolOrdering); 294*5ffd83dbSDimitry Andric 295*5ffd83dbSDimitry Andric static cl::opt<unsigned> OverrideStackAlignment( 296*5ffd83dbSDimitry Andric "stack-alignment", cl::desc("Override default stack alignment"), 297*5ffd83dbSDimitry Andric cl::init(0)); 298*5ffd83dbSDimitry Andric CGBINDOPT(OverrideStackAlignment); 299*5ffd83dbSDimitry Andric 300*5ffd83dbSDimitry Andric static cl::opt<bool> StackRealign( 301*5ffd83dbSDimitry Andric "stackrealign", 302*5ffd83dbSDimitry Andric cl::desc("Force align the stack to the minimum alignment"), 303*5ffd83dbSDimitry Andric cl::init(false)); 304*5ffd83dbSDimitry Andric CGBINDOPT(StackRealign); 305*5ffd83dbSDimitry Andric 306*5ffd83dbSDimitry Andric static cl::opt<std::string> TrapFuncName( 307*5ffd83dbSDimitry Andric "trap-func", cl::Hidden, 308*5ffd83dbSDimitry Andric cl::desc("Emit a call to trap function rather than a trap instruction"), 309*5ffd83dbSDimitry Andric cl::init("")); 310*5ffd83dbSDimitry Andric CGBINDOPT(TrapFuncName); 311*5ffd83dbSDimitry Andric 312*5ffd83dbSDimitry Andric static cl::opt<bool> UseCtors("use-ctors", 313*5ffd83dbSDimitry Andric cl::desc("Use .ctors instead of .init_array."), 314*5ffd83dbSDimitry Andric cl::init(false)); 315*5ffd83dbSDimitry Andric CGBINDOPT(UseCtors); 316*5ffd83dbSDimitry Andric 317*5ffd83dbSDimitry Andric static cl::opt<bool> RelaxELFRelocations( 318*5ffd83dbSDimitry Andric "relax-elf-relocations", 319*5ffd83dbSDimitry Andric cl::desc( 320*5ffd83dbSDimitry Andric "Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"), 321*5ffd83dbSDimitry Andric cl::init(false)); 322*5ffd83dbSDimitry Andric CGBINDOPT(RelaxELFRelocations); 323*5ffd83dbSDimitry Andric 324*5ffd83dbSDimitry Andric static cl::opt<bool> DataSections( 325*5ffd83dbSDimitry Andric "data-sections", cl::desc("Emit data into separate sections"), 326*5ffd83dbSDimitry Andric cl::init(false)); 327*5ffd83dbSDimitry Andric CGBINDOPT(DataSections); 328*5ffd83dbSDimitry Andric 329*5ffd83dbSDimitry Andric static cl::opt<bool> FunctionSections( 330*5ffd83dbSDimitry Andric "function-sections", cl::desc("Emit functions into separate sections"), 331*5ffd83dbSDimitry Andric cl::init(false)); 332*5ffd83dbSDimitry Andric CGBINDOPT(FunctionSections); 333*5ffd83dbSDimitry Andric 334*5ffd83dbSDimitry Andric static cl::opt<std::string> BBSections( 335*5ffd83dbSDimitry Andric "basicblock-sections", 336*5ffd83dbSDimitry Andric cl::desc("Emit basic blocks into separate sections"), 337*5ffd83dbSDimitry Andric cl::value_desc("all | <function list (file)> | labels | none"), 338*5ffd83dbSDimitry Andric cl::init("none")); 339*5ffd83dbSDimitry Andric CGBINDOPT(BBSections); 340*5ffd83dbSDimitry Andric 341*5ffd83dbSDimitry Andric static cl::opt<unsigned> TLSSize( 342*5ffd83dbSDimitry Andric "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0)); 343*5ffd83dbSDimitry Andric CGBINDOPT(TLSSize); 344*5ffd83dbSDimitry Andric 345*5ffd83dbSDimitry Andric static cl::opt<bool> EmulatedTLS( 346*5ffd83dbSDimitry Andric "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false)); 347*5ffd83dbSDimitry Andric CGBINDOPT(EmulatedTLS); 348*5ffd83dbSDimitry Andric 349*5ffd83dbSDimitry Andric static cl::opt<bool> UniqueSectionNames( 350*5ffd83dbSDimitry Andric "unique-section-names", cl::desc("Give unique names to every section"), 351*5ffd83dbSDimitry Andric cl::init(true)); 352*5ffd83dbSDimitry Andric CGBINDOPT(UniqueSectionNames); 353*5ffd83dbSDimitry Andric 354*5ffd83dbSDimitry Andric static cl::opt<bool> UniqueBasicBlockSectionNames( 355*5ffd83dbSDimitry Andric "unique-bb-section-names", 356*5ffd83dbSDimitry Andric cl::desc("Give unique names to every basic block section"), 357*5ffd83dbSDimitry Andric cl::init(false)); 358*5ffd83dbSDimitry Andric CGBINDOPT(UniqueBasicBlockSectionNames); 359*5ffd83dbSDimitry Andric 360*5ffd83dbSDimitry Andric static cl::opt<EABI> EABIVersion( 361*5ffd83dbSDimitry Andric "meabi", cl::desc("Set EABI type (default depends on triple):"), 362*5ffd83dbSDimitry Andric cl::init(EABI::Default), 363*5ffd83dbSDimitry Andric cl::values( 364*5ffd83dbSDimitry Andric clEnumValN(EABI::Default, "default", "Triple default EABI version"), 365*5ffd83dbSDimitry Andric clEnumValN(EABI::EABI4, "4", "EABI version 4"), 366*5ffd83dbSDimitry Andric clEnumValN(EABI::EABI5, "5", "EABI version 5"), 367*5ffd83dbSDimitry Andric clEnumValN(EABI::GNU, "gnu", "EABI GNU"))); 368*5ffd83dbSDimitry Andric CGBINDOPT(EABIVersion); 369*5ffd83dbSDimitry Andric 370*5ffd83dbSDimitry Andric static cl::opt<DebuggerKind> DebuggerTuningOpt( 371*5ffd83dbSDimitry Andric "debugger-tune", cl::desc("Tune debug info for a particular debugger"), 372*5ffd83dbSDimitry Andric cl::init(DebuggerKind::Default), 373*5ffd83dbSDimitry Andric cl::values( 374*5ffd83dbSDimitry Andric clEnumValN(DebuggerKind::GDB, "gdb", "gdb"), 375*5ffd83dbSDimitry Andric clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"), 376*5ffd83dbSDimitry Andric clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)"))); 377*5ffd83dbSDimitry Andric CGBINDOPT(DebuggerTuningOpt); 378*5ffd83dbSDimitry Andric 379*5ffd83dbSDimitry Andric static cl::opt<bool> EnableStackSizeSection( 380*5ffd83dbSDimitry Andric "stack-size-section", 381*5ffd83dbSDimitry Andric cl::desc("Emit a section containing stack size metadata"), 382*5ffd83dbSDimitry Andric cl::init(false)); 383*5ffd83dbSDimitry Andric CGBINDOPT(EnableStackSizeSection); 384*5ffd83dbSDimitry Andric 385*5ffd83dbSDimitry Andric static cl::opt<bool> EnableAddrsig( 386*5ffd83dbSDimitry Andric "addrsig", cl::desc("Emit an address-significance table"), 387*5ffd83dbSDimitry Andric cl::init(false)); 388*5ffd83dbSDimitry Andric CGBINDOPT(EnableAddrsig); 389*5ffd83dbSDimitry Andric 390*5ffd83dbSDimitry Andric static cl::opt<bool> EmitCallSiteInfo( 391*5ffd83dbSDimitry Andric "emit-call-site-info", 392*5ffd83dbSDimitry Andric cl::desc( 393*5ffd83dbSDimitry Andric "Emit call site debug information, if debug information is enabled."), 394*5ffd83dbSDimitry Andric cl::init(false)); 395*5ffd83dbSDimitry Andric CGBINDOPT(EmitCallSiteInfo); 396*5ffd83dbSDimitry Andric 397*5ffd83dbSDimitry Andric static cl::opt<bool> EnableDebugEntryValues( 398*5ffd83dbSDimitry Andric "debug-entry-values", 399*5ffd83dbSDimitry Andric cl::desc("Enable debug info for the debug entry values."), 400*5ffd83dbSDimitry Andric cl::init(false)); 401*5ffd83dbSDimitry Andric CGBINDOPT(EnableDebugEntryValues); 402*5ffd83dbSDimitry Andric 403*5ffd83dbSDimitry Andric static cl::opt<bool> ForceDwarfFrameSection( 404*5ffd83dbSDimitry Andric "force-dwarf-frame-section", 405*5ffd83dbSDimitry Andric cl::desc("Always emit a debug frame section."), cl::init(false)); 406*5ffd83dbSDimitry Andric CGBINDOPT(ForceDwarfFrameSection); 407*5ffd83dbSDimitry Andric 408*5ffd83dbSDimitry Andric static cl::opt<bool> XRayOmitFunctionIndex( 409*5ffd83dbSDimitry Andric "no-xray-index", cl::desc("Don't emit xray_fn_idx section"), 410*5ffd83dbSDimitry Andric cl::init(false)); 411*5ffd83dbSDimitry Andric CGBINDOPT(XRayOmitFunctionIndex); 412*5ffd83dbSDimitry Andric 413*5ffd83dbSDimitry Andric #undef CGBINDOPT 414*5ffd83dbSDimitry Andric 415*5ffd83dbSDimitry Andric mc::RegisterMCTargetOptionsFlags(); 416*5ffd83dbSDimitry Andric } 417*5ffd83dbSDimitry Andric 418*5ffd83dbSDimitry Andric llvm::BasicBlockSection 419*5ffd83dbSDimitry Andric codegen::getBBSectionsMode(llvm::TargetOptions &Options) { 420*5ffd83dbSDimitry Andric if (getBBSections() == "all") 421*5ffd83dbSDimitry Andric return BasicBlockSection::All; 422*5ffd83dbSDimitry Andric else if (getBBSections() == "labels") 423*5ffd83dbSDimitry Andric return BasicBlockSection::Labels; 424*5ffd83dbSDimitry Andric else if (getBBSections() == "none") 425*5ffd83dbSDimitry Andric return BasicBlockSection::None; 426*5ffd83dbSDimitry Andric else { 427*5ffd83dbSDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = 428*5ffd83dbSDimitry Andric MemoryBuffer::getFile(getBBSections()); 429*5ffd83dbSDimitry Andric if (!MBOrErr) { 430*5ffd83dbSDimitry Andric errs() << "Error loading basic block sections function list file: " 431*5ffd83dbSDimitry Andric << MBOrErr.getError().message() << "\n"; 432*5ffd83dbSDimitry Andric } else { 433*5ffd83dbSDimitry Andric Options.BBSectionsFuncListBuf = std::move(*MBOrErr); 434*5ffd83dbSDimitry Andric } 435*5ffd83dbSDimitry Andric return BasicBlockSection::List; 436*5ffd83dbSDimitry Andric } 437*5ffd83dbSDimitry Andric } 438*5ffd83dbSDimitry Andric 439*5ffd83dbSDimitry Andric // Common utility function tightly tied to the options listed here. Initializes 440*5ffd83dbSDimitry Andric // a TargetOptions object with CodeGen flags and returns it. 441*5ffd83dbSDimitry Andric TargetOptions codegen::InitTargetOptionsFromCodeGenFlags() { 442*5ffd83dbSDimitry Andric TargetOptions Options; 443*5ffd83dbSDimitry Andric Options.AllowFPOpFusion = getFuseFPOps(); 444*5ffd83dbSDimitry Andric Options.UnsafeFPMath = getEnableUnsafeFPMath(); 445*5ffd83dbSDimitry Andric Options.NoInfsFPMath = getEnableNoInfsFPMath(); 446*5ffd83dbSDimitry Andric Options.NoNaNsFPMath = getEnableNoNaNsFPMath(); 447*5ffd83dbSDimitry Andric Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath(); 448*5ffd83dbSDimitry Andric Options.NoTrappingFPMath = getEnableNoTrappingFPMath(); 449*5ffd83dbSDimitry Andric 450*5ffd83dbSDimitry Andric DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); 451*5ffd83dbSDimitry Andric 452*5ffd83dbSDimitry Andric // FIXME: Should have separate input and output flags 453*5ffd83dbSDimitry Andric Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind)); 454*5ffd83dbSDimitry Andric 455*5ffd83dbSDimitry Andric Options.HonorSignDependentRoundingFPMathOption = 456*5ffd83dbSDimitry Andric getEnableHonorSignDependentRoundingFPMath(); 457*5ffd83dbSDimitry Andric if (getFloatABIForCalls() != FloatABI::Default) 458*5ffd83dbSDimitry Andric Options.FloatABIType = getFloatABIForCalls(); 459*5ffd83dbSDimitry Andric Options.NoZerosInBSS = getDontPlaceZerosInBSS(); 460*5ffd83dbSDimitry Andric Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt(); 461*5ffd83dbSDimitry Andric Options.StackAlignmentOverride = getOverrideStackAlignment(); 462*5ffd83dbSDimitry Andric Options.StackSymbolOrdering = getStackSymbolOrdering(); 463*5ffd83dbSDimitry Andric Options.UseInitArray = !getUseCtors(); 464*5ffd83dbSDimitry Andric Options.RelaxELFRelocations = getRelaxELFRelocations(); 465*5ffd83dbSDimitry Andric Options.DataSections = getDataSections(); 466*5ffd83dbSDimitry Andric Options.FunctionSections = getFunctionSections(); 467*5ffd83dbSDimitry Andric Options.BBSections = getBBSectionsMode(Options); 468*5ffd83dbSDimitry Andric Options.UniqueSectionNames = getUniqueSectionNames(); 469*5ffd83dbSDimitry Andric Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames(); 470*5ffd83dbSDimitry Andric Options.TLSSize = getTLSSize(); 471*5ffd83dbSDimitry Andric Options.EmulatedTLS = getEmulatedTLS(); 472*5ffd83dbSDimitry Andric Options.ExplicitEmulatedTLS = EmulatedTLSView->getNumOccurrences() > 0; 473*5ffd83dbSDimitry Andric Options.ExceptionModel = getExceptionModel(); 474*5ffd83dbSDimitry Andric Options.EmitStackSizeSection = getEnableStackSizeSection(); 475*5ffd83dbSDimitry Andric Options.EmitAddrsig = getEnableAddrsig(); 476*5ffd83dbSDimitry Andric Options.EmitCallSiteInfo = getEmitCallSiteInfo(); 477*5ffd83dbSDimitry Andric Options.EnableDebugEntryValues = getEnableDebugEntryValues(); 478*5ffd83dbSDimitry Andric Options.ForceDwarfFrameSection = getForceDwarfFrameSection(); 479*5ffd83dbSDimitry Andric Options.XRayOmitFunctionIndex = getXRayOmitFunctionIndex(); 480*5ffd83dbSDimitry Andric 481*5ffd83dbSDimitry Andric Options.MCOptions = mc::InitMCTargetOptionsFromFlags(); 482*5ffd83dbSDimitry Andric 483*5ffd83dbSDimitry Andric Options.ThreadModel = getThreadModel(); 484*5ffd83dbSDimitry Andric Options.EABIVersion = getEABIVersion(); 485*5ffd83dbSDimitry Andric Options.DebuggerTuning = getDebuggerTuningOpt(); 486*5ffd83dbSDimitry Andric 487*5ffd83dbSDimitry Andric return Options; 488*5ffd83dbSDimitry Andric } 489*5ffd83dbSDimitry Andric 490*5ffd83dbSDimitry Andric std::string codegen::getCPUStr() { 491*5ffd83dbSDimitry Andric // If user asked for the 'native' CPU, autodetect here. If autodection fails, 492*5ffd83dbSDimitry Andric // this will set the CPU to an empty string which tells the target to 493*5ffd83dbSDimitry Andric // pick a basic default. 494*5ffd83dbSDimitry Andric if (getMCPU() == "native") 495*5ffd83dbSDimitry Andric return std::string(sys::getHostCPUName()); 496*5ffd83dbSDimitry Andric 497*5ffd83dbSDimitry Andric return getMCPU(); 498*5ffd83dbSDimitry Andric } 499*5ffd83dbSDimitry Andric 500*5ffd83dbSDimitry Andric std::string codegen::getFeaturesStr() { 501*5ffd83dbSDimitry Andric SubtargetFeatures Features; 502*5ffd83dbSDimitry Andric 503*5ffd83dbSDimitry Andric // If user asked for the 'native' CPU, we need to autodetect features. 504*5ffd83dbSDimitry Andric // This is necessary for x86 where the CPU might not support all the 505*5ffd83dbSDimitry Andric // features the autodetected CPU name lists in the target. For example, 506*5ffd83dbSDimitry Andric // not all Sandybridge processors support AVX. 507*5ffd83dbSDimitry Andric if (getMCPU() == "native") { 508*5ffd83dbSDimitry Andric StringMap<bool> HostFeatures; 509*5ffd83dbSDimitry Andric if (sys::getHostCPUFeatures(HostFeatures)) 510*5ffd83dbSDimitry Andric for (auto &F : HostFeatures) 511*5ffd83dbSDimitry Andric Features.AddFeature(F.first(), F.second); 512*5ffd83dbSDimitry Andric } 513*5ffd83dbSDimitry Andric 514*5ffd83dbSDimitry Andric for (auto const &MAttr : getMAttrs()) 515*5ffd83dbSDimitry Andric Features.AddFeature(MAttr); 516*5ffd83dbSDimitry Andric 517*5ffd83dbSDimitry Andric return Features.getString(); 518*5ffd83dbSDimitry Andric } 519*5ffd83dbSDimitry Andric 520*5ffd83dbSDimitry Andric std::vector<std::string> codegen::getFeatureList() { 521*5ffd83dbSDimitry Andric SubtargetFeatures Features; 522*5ffd83dbSDimitry Andric 523*5ffd83dbSDimitry Andric // If user asked for the 'native' CPU, we need to autodetect features. 524*5ffd83dbSDimitry Andric // This is necessary for x86 where the CPU might not support all the 525*5ffd83dbSDimitry Andric // features the autodetected CPU name lists in the target. For example, 526*5ffd83dbSDimitry Andric // not all Sandybridge processors support AVX. 527*5ffd83dbSDimitry Andric if (getMCPU() == "native") { 528*5ffd83dbSDimitry Andric StringMap<bool> HostFeatures; 529*5ffd83dbSDimitry Andric if (sys::getHostCPUFeatures(HostFeatures)) 530*5ffd83dbSDimitry Andric for (auto &F : HostFeatures) 531*5ffd83dbSDimitry Andric Features.AddFeature(F.first(), F.second); 532*5ffd83dbSDimitry Andric } 533*5ffd83dbSDimitry Andric 534*5ffd83dbSDimitry Andric for (auto const &MAttr : getMAttrs()) 535*5ffd83dbSDimitry Andric Features.AddFeature(MAttr); 536*5ffd83dbSDimitry Andric 537*5ffd83dbSDimitry Andric return Features.getFeatures(); 538*5ffd83dbSDimitry Andric } 539*5ffd83dbSDimitry Andric 540*5ffd83dbSDimitry Andric void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) { 541*5ffd83dbSDimitry Andric B.addAttribute(Name, Val ? "true" : "false"); 542*5ffd83dbSDimitry Andric } 543*5ffd83dbSDimitry Andric 544*5ffd83dbSDimitry Andric #define HANDLE_BOOL_ATTR(CL, AttrName) \ 545*5ffd83dbSDimitry Andric do { \ 546*5ffd83dbSDimitry Andric if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName)) \ 547*5ffd83dbSDimitry Andric renderBoolStringAttr(NewAttrs, AttrName, *CL); \ 548*5ffd83dbSDimitry Andric } while (0) 549*5ffd83dbSDimitry Andric 550*5ffd83dbSDimitry Andric /// Set function attributes of function \p F based on CPU, Features, and command 551*5ffd83dbSDimitry Andric /// line flags. 552*5ffd83dbSDimitry Andric void codegen::setFunctionAttributes(StringRef CPU, StringRef Features, 553*5ffd83dbSDimitry Andric Function &F) { 554*5ffd83dbSDimitry Andric auto &Ctx = F.getContext(); 555*5ffd83dbSDimitry Andric AttributeList Attrs = F.getAttributes(); 556*5ffd83dbSDimitry Andric AttrBuilder NewAttrs; 557*5ffd83dbSDimitry Andric 558*5ffd83dbSDimitry Andric if (!CPU.empty() && !F.hasFnAttribute("target-cpu")) 559*5ffd83dbSDimitry Andric NewAttrs.addAttribute("target-cpu", CPU); 560*5ffd83dbSDimitry Andric if (!Features.empty()) { 561*5ffd83dbSDimitry Andric // Append the command line features to any that are already on the function. 562*5ffd83dbSDimitry Andric StringRef OldFeatures = 563*5ffd83dbSDimitry Andric F.getFnAttribute("target-features").getValueAsString(); 564*5ffd83dbSDimitry Andric if (OldFeatures.empty()) 565*5ffd83dbSDimitry Andric NewAttrs.addAttribute("target-features", Features); 566*5ffd83dbSDimitry Andric else { 567*5ffd83dbSDimitry Andric SmallString<256> Appended(OldFeatures); 568*5ffd83dbSDimitry Andric Appended.push_back(','); 569*5ffd83dbSDimitry Andric Appended.append(Features); 570*5ffd83dbSDimitry Andric NewAttrs.addAttribute("target-features", Appended); 571*5ffd83dbSDimitry Andric } 572*5ffd83dbSDimitry Andric } 573*5ffd83dbSDimitry Andric if (FramePointerUsageView->getNumOccurrences() > 0 && 574*5ffd83dbSDimitry Andric !F.hasFnAttribute("frame-pointer")) { 575*5ffd83dbSDimitry Andric if (getFramePointerUsage() == FramePointer::All) 576*5ffd83dbSDimitry Andric NewAttrs.addAttribute("frame-pointer", "all"); 577*5ffd83dbSDimitry Andric else if (getFramePointerUsage() == FramePointer::NonLeaf) 578*5ffd83dbSDimitry Andric NewAttrs.addAttribute("frame-pointer", "non-leaf"); 579*5ffd83dbSDimitry Andric else if (getFramePointerUsage() == FramePointer::None) 580*5ffd83dbSDimitry Andric NewAttrs.addAttribute("frame-pointer", "none"); 581*5ffd83dbSDimitry Andric } 582*5ffd83dbSDimitry Andric if (DisableTailCallsView->getNumOccurrences() > 0) 583*5ffd83dbSDimitry Andric NewAttrs.addAttribute("disable-tail-calls", 584*5ffd83dbSDimitry Andric toStringRef(getDisableTailCalls())); 585*5ffd83dbSDimitry Andric if (getStackRealign()) 586*5ffd83dbSDimitry Andric NewAttrs.addAttribute("stackrealign"); 587*5ffd83dbSDimitry Andric 588*5ffd83dbSDimitry Andric HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math"); 589*5ffd83dbSDimitry Andric HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math"); 590*5ffd83dbSDimitry Andric HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math"); 591*5ffd83dbSDimitry Andric HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math"); 592*5ffd83dbSDimitry Andric 593*5ffd83dbSDimitry Andric if (DenormalFPMathView->getNumOccurrences() > 0 && 594*5ffd83dbSDimitry Andric !F.hasFnAttribute("denormal-fp-math")) { 595*5ffd83dbSDimitry Andric DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); 596*5ffd83dbSDimitry Andric 597*5ffd83dbSDimitry Andric // FIXME: Command line flag should expose separate input/output modes. 598*5ffd83dbSDimitry Andric NewAttrs.addAttribute("denormal-fp-math", 599*5ffd83dbSDimitry Andric DenormalMode(DenormKind, DenormKind).str()); 600*5ffd83dbSDimitry Andric } 601*5ffd83dbSDimitry Andric 602*5ffd83dbSDimitry Andric if (DenormalFP32MathView->getNumOccurrences() > 0 && 603*5ffd83dbSDimitry Andric !F.hasFnAttribute("denormal-fp-math-f32")) { 604*5ffd83dbSDimitry Andric // FIXME: Command line flag should expose separate input/output modes. 605*5ffd83dbSDimitry Andric DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math(); 606*5ffd83dbSDimitry Andric 607*5ffd83dbSDimitry Andric NewAttrs.addAttribute( 608*5ffd83dbSDimitry Andric "denormal-fp-math-f32", 609*5ffd83dbSDimitry Andric DenormalMode(DenormKind, DenormKind).str()); 610*5ffd83dbSDimitry Andric } 611*5ffd83dbSDimitry Andric 612*5ffd83dbSDimitry Andric if (TrapFuncNameView->getNumOccurrences() > 0) 613*5ffd83dbSDimitry Andric for (auto &B : F) 614*5ffd83dbSDimitry Andric for (auto &I : B) 615*5ffd83dbSDimitry Andric if (auto *Call = dyn_cast<CallInst>(&I)) 616*5ffd83dbSDimitry Andric if (const auto *F = Call->getCalledFunction()) 617*5ffd83dbSDimitry Andric if (F->getIntrinsicID() == Intrinsic::debugtrap || 618*5ffd83dbSDimitry Andric F->getIntrinsicID() == Intrinsic::trap) 619*5ffd83dbSDimitry Andric Call->addAttribute( 620*5ffd83dbSDimitry Andric AttributeList::FunctionIndex, 621*5ffd83dbSDimitry Andric Attribute::get(Ctx, "trap-func-name", getTrapFuncName())); 622*5ffd83dbSDimitry Andric 623*5ffd83dbSDimitry Andric // Let NewAttrs override Attrs. 624*5ffd83dbSDimitry Andric F.setAttributes( 625*5ffd83dbSDimitry Andric Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs)); 626*5ffd83dbSDimitry Andric } 627*5ffd83dbSDimitry Andric 628*5ffd83dbSDimitry Andric /// Set function attributes of functions in Module M based on CPU, 629*5ffd83dbSDimitry Andric /// Features, and command line flags. 630*5ffd83dbSDimitry Andric void codegen::setFunctionAttributes(StringRef CPU, StringRef Features, 631*5ffd83dbSDimitry Andric Module &M) { 632*5ffd83dbSDimitry Andric for (Function &F : M) 633*5ffd83dbSDimitry Andric setFunctionAttributes(CPU, Features, F); 634*5ffd83dbSDimitry Andric } 635