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