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/ADT/StringExtras.h" 17 #include "llvm/IR/Instructions.h" 18 #include "llvm/IR/Intrinsics.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/MC/MCTargetOptionsCommandFlags.h" 21 #include "llvm/MC/TargetRegistry.h" 22 #include "llvm/Support/CommandLine.h" 23 #include "llvm/Support/MemoryBuffer.h" 24 #include "llvm/Target/TargetMachine.h" 25 #include "llvm/TargetParser/Host.h" 26 #include "llvm/TargetParser/SubtargetFeature.h" 27 #include "llvm/TargetParser/Triple.h" 28 #include <optional> 29 30 using namespace llvm; 31 32 #define CGOPT(TY, NAME) \ 33 static cl::opt<TY> *NAME##View; \ 34 TY codegen::get##NAME() { \ 35 assert(NAME##View && "RegisterCodeGenFlags not created."); \ 36 return *NAME##View; \ 37 } 38 39 #define CGLIST(TY, NAME) \ 40 static cl::list<TY> *NAME##View; \ 41 std::vector<TY> codegen::get##NAME() { \ 42 assert(NAME##View && "RegisterCodeGenFlags not created."); \ 43 return *NAME##View; \ 44 } 45 46 // Temporary macro for incremental transition to std::optional. 47 #define CGOPT_EXP(TY, NAME) \ 48 CGOPT(TY, NAME) \ 49 std::optional<TY> codegen::getExplicit##NAME() { \ 50 if (NAME##View->getNumOccurrences()) { \ 51 TY res = *NAME##View; \ 52 return res; \ 53 } \ 54 return std::nullopt; \ 55 } 56 57 CGOPT(std::string, MArch) 58 CGOPT(std::string, MCPU) 59 CGLIST(std::string, MAttrs) 60 CGOPT_EXP(Reloc::Model, RelocModel) 61 CGOPT(ThreadModel::Model, ThreadModel) 62 CGOPT_EXP(CodeModel::Model, CodeModel) 63 CGOPT_EXP(uint64_t, LargeDataThreshold) 64 CGOPT(ExceptionHandling, ExceptionModel) 65 CGOPT_EXP(CodeGenFileType, FileType) 66 CGOPT(FramePointerKind, FramePointerUsage) 67 CGOPT(bool, EnableUnsafeFPMath) 68 CGOPT(bool, EnableNoInfsFPMath) 69 CGOPT(bool, EnableNoNaNsFPMath) 70 CGOPT(bool, EnableNoSignedZerosFPMath) 71 CGOPT(bool, EnableApproxFuncFPMath) 72 CGOPT(bool, EnableNoTrappingFPMath) 73 CGOPT(bool, EnableAIXExtendedAltivecABI) 74 CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath) 75 CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math) 76 CGOPT(bool, EnableHonorSignDependentRoundingFPMath) 77 CGOPT(FloatABI::ABIType, FloatABIForCalls) 78 CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps) 79 CGOPT(SwiftAsyncFramePointerMode, SwiftAsyncFramePointer) 80 CGOPT(bool, DontPlaceZerosInBSS) 81 CGOPT(bool, EnableGuaranteedTailCallOpt) 82 CGOPT(bool, DisableTailCalls) 83 CGOPT(bool, StackSymbolOrdering) 84 CGOPT(bool, StackRealign) 85 CGOPT(std::string, TrapFuncName) 86 CGOPT(bool, UseCtors) 87 CGOPT(bool, DisableIntegratedAS) 88 CGOPT_EXP(bool, DataSections) 89 CGOPT_EXP(bool, FunctionSections) 90 CGOPT(bool, IgnoreXCOFFVisibility) 91 CGOPT(bool, XCOFFTracebackTable) 92 CGOPT(bool, EnableBBAddrMap) 93 CGOPT(std::string, BBSections) 94 CGOPT(unsigned, TLSSize) 95 CGOPT_EXP(bool, EmulatedTLS) 96 CGOPT_EXP(bool, EnableTLSDESC) 97 CGOPT(bool, UniqueSectionNames) 98 CGOPT(bool, UniqueBasicBlockSectionNames) 99 CGOPT(bool, SeparateNamedSections) 100 CGOPT(EABI, EABIVersion) 101 CGOPT(DebuggerKind, DebuggerTuningOpt) 102 CGOPT(bool, EnableStackSizeSection) 103 CGOPT(bool, EnableAddrsig) 104 CGOPT(bool, EmitCallSiteInfo) 105 CGOPT(bool, EnableMachineFunctionSplitter) 106 CGOPT(bool, EnableStaticDataPartitioning) 107 CGOPT(bool, EnableDebugEntryValues) 108 CGOPT(bool, ForceDwarfFrameSection) 109 CGOPT(bool, XRayFunctionIndex) 110 CGOPT(bool, DebugStrictDwarf) 111 CGOPT(unsigned, AlignLoops) 112 CGOPT(bool, JMCInstrument) 113 CGOPT(bool, XCOFFReadOnlyPointers) 114 115 codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() { 116 #define CGBINDOPT(NAME) \ 117 do { \ 118 NAME##View = std::addressof(NAME); \ 119 } while (0) 120 121 static cl::opt<std::string> MArch( 122 "march", cl::desc("Architecture to generate code for (see --version)")); 123 CGBINDOPT(MArch); 124 125 static cl::opt<std::string> MCPU( 126 "mcpu", cl::desc("Target a specific cpu type (-mcpu=help for details)"), 127 cl::value_desc("cpu-name"), cl::init("")); 128 CGBINDOPT(MCPU); 129 130 static cl::list<std::string> MAttrs( 131 "mattr", cl::CommaSeparated, 132 cl::desc("Target specific attributes (-mattr=help for details)"), 133 cl::value_desc("a1,+a2,-a3,...")); 134 CGBINDOPT(MAttrs); 135 136 static cl::opt<Reloc::Model> RelocModel( 137 "relocation-model", cl::desc("Choose relocation model"), 138 cl::values( 139 clEnumValN(Reloc::Static, "static", "Non-relocatable code"), 140 clEnumValN(Reloc::PIC_, "pic", 141 "Fully relocatable, position independent code"), 142 clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic", 143 "Relocatable external references, non-relocatable code"), 144 clEnumValN( 145 Reloc::ROPI, "ropi", 146 "Code and read-only data relocatable, accessed PC-relative"), 147 clEnumValN( 148 Reloc::RWPI, "rwpi", 149 "Read-write data relocatable, accessed relative to static base"), 150 clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi", 151 "Combination of ropi and rwpi"))); 152 CGBINDOPT(RelocModel); 153 154 static cl::opt<ThreadModel::Model> ThreadModel( 155 "thread-model", cl::desc("Choose threading model"), 156 cl::init(ThreadModel::POSIX), 157 cl::values( 158 clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"), 159 clEnumValN(ThreadModel::Single, "single", "Single thread model"))); 160 CGBINDOPT(ThreadModel); 161 162 static cl::opt<CodeModel::Model> CodeModel( 163 "code-model", cl::desc("Choose code model"), 164 cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"), 165 clEnumValN(CodeModel::Small, "small", "Small code model"), 166 clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"), 167 clEnumValN(CodeModel::Medium, "medium", "Medium code model"), 168 clEnumValN(CodeModel::Large, "large", "Large code model"))); 169 CGBINDOPT(CodeModel); 170 171 static cl::opt<uint64_t> LargeDataThreshold( 172 "large-data-threshold", 173 cl::desc("Choose large data threshold for x86_64 medium code model"), 174 cl::init(0)); 175 CGBINDOPT(LargeDataThreshold); 176 177 static cl::opt<ExceptionHandling> ExceptionModel( 178 "exception-model", cl::desc("exception model"), 179 cl::init(ExceptionHandling::None), 180 cl::values( 181 clEnumValN(ExceptionHandling::None, "default", 182 "default exception handling model"), 183 clEnumValN(ExceptionHandling::DwarfCFI, "dwarf", 184 "DWARF-like CFI based exception handling"), 185 clEnumValN(ExceptionHandling::SjLj, "sjlj", 186 "SjLj exception handling"), 187 clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"), 188 clEnumValN(ExceptionHandling::WinEH, "wineh", 189 "Windows exception model"), 190 clEnumValN(ExceptionHandling::Wasm, "wasm", 191 "WebAssembly exception handling"))); 192 CGBINDOPT(ExceptionModel); 193 194 static cl::opt<CodeGenFileType> FileType( 195 "filetype", cl::init(CodeGenFileType::AssemblyFile), 196 cl::desc( 197 "Choose a file type (not all types are supported by all targets):"), 198 cl::values(clEnumValN(CodeGenFileType::AssemblyFile, "asm", 199 "Emit an assembly ('.s') file"), 200 clEnumValN(CodeGenFileType::ObjectFile, "obj", 201 "Emit a native object ('.o') file"), 202 clEnumValN(CodeGenFileType::Null, "null", 203 "Emit nothing, for performance testing"))); 204 CGBINDOPT(FileType); 205 206 static cl::opt<FramePointerKind> FramePointerUsage( 207 "frame-pointer", 208 cl::desc("Specify frame pointer elimination optimization"), 209 cl::init(FramePointerKind::None), 210 cl::values( 211 clEnumValN(FramePointerKind::All, "all", 212 "Disable frame pointer elimination"), 213 clEnumValN(FramePointerKind::NonLeaf, "non-leaf", 214 "Disable frame pointer elimination for non-leaf frame"), 215 clEnumValN(FramePointerKind::Reserved, "reserved", 216 "Enable frame pointer elimination, but reserve the frame " 217 "pointer register"), 218 clEnumValN(FramePointerKind::None, "none", 219 "Enable frame pointer elimination"))); 220 CGBINDOPT(FramePointerUsage); 221 222 static cl::opt<bool> EnableUnsafeFPMath( 223 "enable-unsafe-fp-math", 224 cl::desc("Enable optimizations that may decrease FP precision"), 225 cl::init(false)); 226 CGBINDOPT(EnableUnsafeFPMath); 227 228 static cl::opt<bool> EnableNoInfsFPMath( 229 "enable-no-infs-fp-math", 230 cl::desc("Enable FP math optimizations that assume no +-Infs"), 231 cl::init(false)); 232 CGBINDOPT(EnableNoInfsFPMath); 233 234 static cl::opt<bool> EnableNoNaNsFPMath( 235 "enable-no-nans-fp-math", 236 cl::desc("Enable FP math optimizations that assume no NaNs"), 237 cl::init(false)); 238 CGBINDOPT(EnableNoNaNsFPMath); 239 240 static cl::opt<bool> EnableNoSignedZerosFPMath( 241 "enable-no-signed-zeros-fp-math", 242 cl::desc("Enable FP math optimizations that assume " 243 "the sign of 0 is insignificant"), 244 cl::init(false)); 245 CGBINDOPT(EnableNoSignedZerosFPMath); 246 247 static cl::opt<bool> EnableApproxFuncFPMath( 248 "enable-approx-func-fp-math", 249 cl::desc("Enable FP math optimizations that assume approx func"), 250 cl::init(false)); 251 CGBINDOPT(EnableApproxFuncFPMath); 252 253 static cl::opt<bool> EnableNoTrappingFPMath( 254 "enable-no-trapping-fp-math", 255 cl::desc("Enable setting the FP exceptions build " 256 "attribute not to use exceptions"), 257 cl::init(false)); 258 CGBINDOPT(EnableNoTrappingFPMath); 259 260 static const auto DenormFlagEnumOptions = cl::values( 261 clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"), 262 clEnumValN(DenormalMode::PreserveSign, "preserve-sign", 263 "the sign of a flushed-to-zero number is preserved " 264 "in the sign of 0"), 265 clEnumValN(DenormalMode::PositiveZero, "positive-zero", 266 "denormals are flushed to positive zero"), 267 clEnumValN(DenormalMode::Dynamic, "dynamic", 268 "denormals have unknown treatment")); 269 270 // FIXME: Doesn't have way to specify separate input and output modes. 271 static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath( 272 "denormal-fp-math", 273 cl::desc("Select which denormal numbers the code is permitted to require"), 274 cl::init(DenormalMode::IEEE), 275 DenormFlagEnumOptions); 276 CGBINDOPT(DenormalFPMath); 277 278 static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math( 279 "denormal-fp-math-f32", 280 cl::desc("Select which denormal numbers the code is permitted to require for float"), 281 cl::init(DenormalMode::Invalid), 282 DenormFlagEnumOptions); 283 CGBINDOPT(DenormalFP32Math); 284 285 static cl::opt<bool> EnableHonorSignDependentRoundingFPMath( 286 "enable-sign-dependent-rounding-fp-math", cl::Hidden, 287 cl::desc("Force codegen to assume rounding mode can change dynamically"), 288 cl::init(false)); 289 CGBINDOPT(EnableHonorSignDependentRoundingFPMath); 290 291 static cl::opt<FloatABI::ABIType> FloatABIForCalls( 292 "float-abi", cl::desc("Choose float ABI type"), 293 cl::init(FloatABI::Default), 294 cl::values(clEnumValN(FloatABI::Default, "default", 295 "Target default float ABI type"), 296 clEnumValN(FloatABI::Soft, "soft", 297 "Soft float ABI (implied by -soft-float)"), 298 clEnumValN(FloatABI::Hard, "hard", 299 "Hard float ABI (uses FP registers)"))); 300 CGBINDOPT(FloatABIForCalls); 301 302 static cl::opt<FPOpFusion::FPOpFusionMode> FuseFPOps( 303 "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"), 304 cl::init(FPOpFusion::Standard), 305 cl::values( 306 clEnumValN(FPOpFusion::Fast, "fast", 307 "Fuse FP ops whenever profitable"), 308 clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."), 309 clEnumValN(FPOpFusion::Strict, "off", 310 "Only fuse FP ops when the result won't be affected."))); 311 CGBINDOPT(FuseFPOps); 312 313 static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer( 314 "swift-async-fp", 315 cl::desc("Determine when the Swift async frame pointer should be set"), 316 cl::init(SwiftAsyncFramePointerMode::Always), 317 cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto", 318 "Determine based on deployment target"), 319 clEnumValN(SwiftAsyncFramePointerMode::Always, "always", 320 "Always set the bit"), 321 clEnumValN(SwiftAsyncFramePointerMode::Never, "never", 322 "Never set the bit"))); 323 CGBINDOPT(SwiftAsyncFramePointer); 324 325 static cl::opt<bool> DontPlaceZerosInBSS( 326 "nozero-initialized-in-bss", 327 cl::desc("Don't place zero-initialized symbols into bss section"), 328 cl::init(false)); 329 CGBINDOPT(DontPlaceZerosInBSS); 330 331 static cl::opt<bool> EnableAIXExtendedAltivecABI( 332 "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."), 333 cl::init(false)); 334 CGBINDOPT(EnableAIXExtendedAltivecABI); 335 336 static cl::opt<bool> EnableGuaranteedTailCallOpt( 337 "tailcallopt", 338 cl::desc( 339 "Turn fastcc calls into tail calls by (potentially) changing ABI."), 340 cl::init(false)); 341 CGBINDOPT(EnableGuaranteedTailCallOpt); 342 343 static cl::opt<bool> DisableTailCalls( 344 "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false)); 345 CGBINDOPT(DisableTailCalls); 346 347 static cl::opt<bool> StackSymbolOrdering( 348 "stack-symbol-ordering", cl::desc("Order local stack symbols."), 349 cl::init(true)); 350 CGBINDOPT(StackSymbolOrdering); 351 352 static cl::opt<bool> StackRealign( 353 "stackrealign", 354 cl::desc("Force align the stack to the minimum alignment"), 355 cl::init(false)); 356 CGBINDOPT(StackRealign); 357 358 static cl::opt<std::string> TrapFuncName( 359 "trap-func", cl::Hidden, 360 cl::desc("Emit a call to trap function rather than a trap instruction"), 361 cl::init("")); 362 CGBINDOPT(TrapFuncName); 363 364 static cl::opt<bool> UseCtors("use-ctors", 365 cl::desc("Use .ctors instead of .init_array."), 366 cl::init(false)); 367 CGBINDOPT(UseCtors); 368 369 static cl::opt<bool> DataSections( 370 "data-sections", cl::desc("Emit data into separate sections"), 371 cl::init(false)); 372 CGBINDOPT(DataSections); 373 374 static cl::opt<bool> FunctionSections( 375 "function-sections", cl::desc("Emit functions into separate sections"), 376 cl::init(false)); 377 CGBINDOPT(FunctionSections); 378 379 static cl::opt<bool> IgnoreXCOFFVisibility( 380 "ignore-xcoff-visibility", 381 cl::desc("Not emit the visibility attribute for asm in AIX OS or give " 382 "all symbols 'unspecified' visibility in XCOFF object file"), 383 cl::init(false)); 384 CGBINDOPT(IgnoreXCOFFVisibility); 385 386 static cl::opt<bool> XCOFFTracebackTable( 387 "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"), 388 cl::init(true)); 389 CGBINDOPT(XCOFFTracebackTable); 390 391 static cl::opt<bool> EnableBBAddrMap( 392 "basic-block-address-map", 393 cl::desc("Emit the basic block address map section"), cl::init(false)); 394 CGBINDOPT(EnableBBAddrMap); 395 396 static cl::opt<std::string> BBSections( 397 "basic-block-sections", 398 cl::desc("Emit basic blocks into separate sections"), 399 cl::value_desc("all | <function list (file)> | labels | none"), 400 cl::init("none")); 401 CGBINDOPT(BBSections); 402 403 static cl::opt<unsigned> TLSSize( 404 "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0)); 405 CGBINDOPT(TLSSize); 406 407 static cl::opt<bool> EmulatedTLS( 408 "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false)); 409 CGBINDOPT(EmulatedTLS); 410 411 static cl::opt<bool> EnableTLSDESC( 412 "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"), 413 cl::init(false)); 414 CGBINDOPT(EnableTLSDESC); 415 416 static cl::opt<bool> UniqueSectionNames( 417 "unique-section-names", cl::desc("Give unique names to every section"), 418 cl::init(true)); 419 CGBINDOPT(UniqueSectionNames); 420 421 static cl::opt<bool> UniqueBasicBlockSectionNames( 422 "unique-basic-block-section-names", 423 cl::desc("Give unique names to every basic block section"), 424 cl::init(false)); 425 CGBINDOPT(UniqueBasicBlockSectionNames); 426 427 static cl::opt<bool> SeparateNamedSections( 428 "separate-named-sections", 429 cl::desc("Use separate unique sections for named sections"), 430 cl::init(false)); 431 CGBINDOPT(SeparateNamedSections); 432 433 static cl::opt<EABI> EABIVersion( 434 "meabi", cl::desc("Set EABI type (default depends on triple):"), 435 cl::init(EABI::Default), 436 cl::values( 437 clEnumValN(EABI::Default, "default", "Triple default EABI version"), 438 clEnumValN(EABI::EABI4, "4", "EABI version 4"), 439 clEnumValN(EABI::EABI5, "5", "EABI version 5"), 440 clEnumValN(EABI::GNU, "gnu", "EABI GNU"))); 441 CGBINDOPT(EABIVersion); 442 443 static cl::opt<DebuggerKind> DebuggerTuningOpt( 444 "debugger-tune", cl::desc("Tune debug info for a particular debugger"), 445 cl::init(DebuggerKind::Default), 446 cl::values( 447 clEnumValN(DebuggerKind::GDB, "gdb", "gdb"), 448 clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"), 449 clEnumValN(DebuggerKind::DBX, "dbx", "dbx"), 450 clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)"))); 451 CGBINDOPT(DebuggerTuningOpt); 452 453 static cl::opt<bool> EnableStackSizeSection( 454 "stack-size-section", 455 cl::desc("Emit a section containing stack size metadata"), 456 cl::init(false)); 457 CGBINDOPT(EnableStackSizeSection); 458 459 static cl::opt<bool> EnableAddrsig( 460 "addrsig", cl::desc("Emit an address-significance table"), 461 cl::init(false)); 462 CGBINDOPT(EnableAddrsig); 463 464 static cl::opt<bool> EmitCallSiteInfo( 465 "emit-call-site-info", 466 cl::desc( 467 "Emit call site debug information, if debug information is enabled."), 468 cl::init(false)); 469 CGBINDOPT(EmitCallSiteInfo); 470 471 static cl::opt<bool> EnableDebugEntryValues( 472 "debug-entry-values", 473 cl::desc("Enable debug info for the debug entry values."), 474 cl::init(false)); 475 CGBINDOPT(EnableDebugEntryValues); 476 477 static cl::opt<bool> EnableMachineFunctionSplitter( 478 "split-machine-functions", 479 cl::desc("Split out cold basic blocks from machine functions based on " 480 "profile information"), 481 cl::init(false)); 482 CGBINDOPT(EnableMachineFunctionSplitter); 483 484 static cl::opt<bool> EnableStaticDataPartitioning( 485 "partition-static-data-sections", 486 cl::desc("Partition data sections using profile information."), 487 cl::init(false)); 488 CGBINDOPT(EnableStaticDataPartitioning); 489 490 static cl::opt<bool> ForceDwarfFrameSection( 491 "force-dwarf-frame-section", 492 cl::desc("Always emit a debug frame section."), cl::init(false)); 493 CGBINDOPT(ForceDwarfFrameSection); 494 495 static cl::opt<bool> XRayFunctionIndex("xray-function-index", 496 cl::desc("Emit xray_fn_idx section"), 497 cl::init(true)); 498 CGBINDOPT(XRayFunctionIndex); 499 500 static cl::opt<bool> DebugStrictDwarf( 501 "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false)); 502 CGBINDOPT(DebugStrictDwarf); 503 504 static cl::opt<unsigned> AlignLoops("align-loops", 505 cl::desc("Default alignment for loops")); 506 CGBINDOPT(AlignLoops); 507 508 static cl::opt<bool> JMCInstrument( 509 "enable-jmc-instrument", 510 cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"), 511 cl::init(false)); 512 CGBINDOPT(JMCInstrument); 513 514 static cl::opt<bool> XCOFFReadOnlyPointers( 515 "mxcoff-roptr", 516 cl::desc("When set to true, const objects with relocatable address " 517 "values are put into the RO data section."), 518 cl::init(false)); 519 CGBINDOPT(XCOFFReadOnlyPointers); 520 521 static cl::opt<bool> DisableIntegratedAS( 522 "no-integrated-as", cl::desc("Disable integrated assembler"), 523 cl::init(false)); 524 CGBINDOPT(DisableIntegratedAS); 525 526 #undef CGBINDOPT 527 528 mc::RegisterMCTargetOptionsFlags(); 529 } 530 531 llvm::BasicBlockSection 532 codegen::getBBSectionsMode(llvm::TargetOptions &Options) { 533 if (getBBSections() == "all") 534 return BasicBlockSection::All; 535 else if (getBBSections() == "none") 536 return BasicBlockSection::None; 537 else { 538 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = 539 MemoryBuffer::getFile(getBBSections()); 540 if (!MBOrErr) { 541 errs() << "Error loading basic block sections function list file: " 542 << MBOrErr.getError().message() << "\n"; 543 } else { 544 Options.BBSectionsFuncListBuf = std::move(*MBOrErr); 545 } 546 return BasicBlockSection::List; 547 } 548 } 549 550 // Common utility function tightly tied to the options listed here. Initializes 551 // a TargetOptions object with CodeGen flags and returns it. 552 TargetOptions 553 codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) { 554 TargetOptions Options; 555 Options.AllowFPOpFusion = getFuseFPOps(); 556 Options.UnsafeFPMath = getEnableUnsafeFPMath(); 557 Options.NoInfsFPMath = getEnableNoInfsFPMath(); 558 Options.NoNaNsFPMath = getEnableNoNaNsFPMath(); 559 Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath(); 560 Options.ApproxFuncFPMath = getEnableApproxFuncFPMath(); 561 Options.NoTrappingFPMath = getEnableNoTrappingFPMath(); 562 563 DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); 564 565 // FIXME: Should have separate input and output flags 566 Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind)); 567 568 Options.HonorSignDependentRoundingFPMathOption = 569 getEnableHonorSignDependentRoundingFPMath(); 570 if (getFloatABIForCalls() != FloatABI::Default) 571 Options.FloatABIType = getFloatABIForCalls(); 572 Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI(); 573 Options.NoZerosInBSS = getDontPlaceZerosInBSS(); 574 Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt(); 575 Options.StackSymbolOrdering = getStackSymbolOrdering(); 576 Options.UseInitArray = !getUseCtors(); 577 Options.DisableIntegratedAS = getDisableIntegratedAS(); 578 Options.DataSections = 579 getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections()); 580 Options.FunctionSections = getFunctionSections(); 581 Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility(); 582 Options.XCOFFTracebackTable = getXCOFFTracebackTable(); 583 Options.BBAddrMap = getEnableBBAddrMap(); 584 Options.BBSections = getBBSectionsMode(Options); 585 Options.UniqueSectionNames = getUniqueSectionNames(); 586 Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames(); 587 Options.SeparateNamedSections = getSeparateNamedSections(); 588 Options.TLSSize = getTLSSize(); 589 Options.EmulatedTLS = 590 getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS()); 591 Options.EnableTLSDESC = 592 getExplicitEnableTLSDESC().value_or(TheTriple.hasDefaultTLSDESC()); 593 Options.ExceptionModel = getExceptionModel(); 594 Options.EmitStackSizeSection = getEnableStackSizeSection(); 595 Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter(); 596 Options.EnableStaticDataPartitioning = getEnableStaticDataPartitioning(); 597 Options.EmitAddrsig = getEnableAddrsig(); 598 Options.EmitCallSiteInfo = getEmitCallSiteInfo(); 599 Options.EnableDebugEntryValues = getEnableDebugEntryValues(); 600 Options.ForceDwarfFrameSection = getForceDwarfFrameSection(); 601 Options.XRayFunctionIndex = getXRayFunctionIndex(); 602 Options.DebugStrictDwarf = getDebugStrictDwarf(); 603 Options.LoopAlignment = getAlignLoops(); 604 Options.JMCInstrument = getJMCInstrument(); 605 Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers(); 606 607 Options.MCOptions = mc::InitMCTargetOptionsFromFlags(); 608 609 Options.ThreadModel = getThreadModel(); 610 Options.EABIVersion = getEABIVersion(); 611 Options.DebuggerTuning = getDebuggerTuningOpt(); 612 Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer(); 613 return Options; 614 } 615 616 std::string codegen::getCPUStr() { 617 // If user asked for the 'native' CPU, autodetect here. If autodection fails, 618 // this will set the CPU to an empty string which tells the target to 619 // pick a basic default. 620 if (getMCPU() == "native") 621 return std::string(sys::getHostCPUName()); 622 623 return getMCPU(); 624 } 625 626 std::string codegen::getFeaturesStr() { 627 SubtargetFeatures Features; 628 629 // If user asked for the 'native' CPU, we need to autodetect features. 630 // This is necessary for x86 where the CPU might not support all the 631 // features the autodetected CPU name lists in the target. For example, 632 // not all Sandybridge processors support AVX. 633 if (getMCPU() == "native") 634 for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures()) 635 Features.AddFeature(Feature, IsEnabled); 636 637 for (auto const &MAttr : getMAttrs()) 638 Features.AddFeature(MAttr); 639 640 return Features.getString(); 641 } 642 643 std::vector<std::string> codegen::getFeatureList() { 644 SubtargetFeatures Features; 645 646 // If user asked for the 'native' CPU, we need to autodetect features. 647 // This is necessary for x86 where the CPU might not support all the 648 // features the autodetected CPU name lists in the target. For example, 649 // not all Sandybridge processors support AVX. 650 if (getMCPU() == "native") 651 for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures()) 652 Features.AddFeature(Feature, IsEnabled); 653 654 for (auto const &MAttr : getMAttrs()) 655 Features.AddFeature(MAttr); 656 657 return Features.getFeatures(); 658 } 659 660 void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) { 661 B.addAttribute(Name, Val ? "true" : "false"); 662 } 663 664 #define HANDLE_BOOL_ATTR(CL, AttrName) \ 665 do { \ 666 if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName)) \ 667 renderBoolStringAttr(NewAttrs, AttrName, *CL); \ 668 } while (0) 669 670 /// Set function attributes of function \p F based on CPU, Features, and command 671 /// line flags. 672 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features, 673 Function &F) { 674 auto &Ctx = F.getContext(); 675 AttributeList Attrs = F.getAttributes(); 676 AttrBuilder NewAttrs(Ctx); 677 678 if (!CPU.empty() && !F.hasFnAttribute("target-cpu")) 679 NewAttrs.addAttribute("target-cpu", CPU); 680 if (!Features.empty()) { 681 // Append the command line features to any that are already on the function. 682 StringRef OldFeatures = 683 F.getFnAttribute("target-features").getValueAsString(); 684 if (OldFeatures.empty()) 685 NewAttrs.addAttribute("target-features", Features); 686 else { 687 SmallString<256> Appended(OldFeatures); 688 Appended.push_back(','); 689 Appended.append(Features); 690 NewAttrs.addAttribute("target-features", Appended); 691 } 692 } 693 if (FramePointerUsageView->getNumOccurrences() > 0 && 694 !F.hasFnAttribute("frame-pointer")) { 695 if (getFramePointerUsage() == FramePointerKind::All) 696 NewAttrs.addAttribute("frame-pointer", "all"); 697 else if (getFramePointerUsage() == FramePointerKind::NonLeaf) 698 NewAttrs.addAttribute("frame-pointer", "non-leaf"); 699 else if (getFramePointerUsage() == FramePointerKind::Reserved) 700 NewAttrs.addAttribute("frame-pointer", "reserved"); 701 else if (getFramePointerUsage() == FramePointerKind::None) 702 NewAttrs.addAttribute("frame-pointer", "none"); 703 } 704 if (DisableTailCallsView->getNumOccurrences() > 0) 705 NewAttrs.addAttribute("disable-tail-calls", 706 toStringRef(getDisableTailCalls())); 707 if (getStackRealign()) 708 NewAttrs.addAttribute("stackrealign"); 709 710 HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math"); 711 HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math"); 712 HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math"); 713 HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math"); 714 HANDLE_BOOL_ATTR(EnableApproxFuncFPMathView, "approx-func-fp-math"); 715 716 if (DenormalFPMathView->getNumOccurrences() > 0 && 717 !F.hasFnAttribute("denormal-fp-math")) { 718 DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); 719 720 // FIXME: Command line flag should expose separate input/output modes. 721 NewAttrs.addAttribute("denormal-fp-math", 722 DenormalMode(DenormKind, DenormKind).str()); 723 } 724 725 if (DenormalFP32MathView->getNumOccurrences() > 0 && 726 !F.hasFnAttribute("denormal-fp-math-f32")) { 727 // FIXME: Command line flag should expose separate input/output modes. 728 DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math(); 729 730 NewAttrs.addAttribute( 731 "denormal-fp-math-f32", 732 DenormalMode(DenormKind, DenormKind).str()); 733 } 734 735 if (TrapFuncNameView->getNumOccurrences() > 0) 736 for (auto &B : F) 737 for (auto &I : B) 738 if (auto *Call = dyn_cast<CallInst>(&I)) 739 if (const auto *F = Call->getCalledFunction()) 740 if (F->getIntrinsicID() == Intrinsic::debugtrap || 741 F->getIntrinsicID() == Intrinsic::trap) 742 Call->addFnAttr( 743 Attribute::get(Ctx, "trap-func-name", getTrapFuncName())); 744 745 // Let NewAttrs override Attrs. 746 F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs)); 747 } 748 749 /// Set function attributes of functions in Module M based on CPU, 750 /// Features, and command line flags. 751 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features, 752 Module &M) { 753 for (Function &F : M) 754 setFunctionAttributes(CPU, Features, F); 755 } 756 757 Expected<std::unique_ptr<TargetMachine>> 758 codegen::createTargetMachineForTriple(StringRef TargetTriple, 759 CodeGenOptLevel OptLevel) { 760 Triple TheTriple(TargetTriple); 761 std::string Error; 762 const auto *TheTarget = 763 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); 764 if (!TheTarget) 765 return createStringError(inconvertibleErrorCode(), Error); 766 auto *Target = TheTarget->createTargetMachine( 767 TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(), 768 codegen::InitTargetOptionsFromCodeGenFlags(TheTriple), 769 codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(), 770 OptLevel); 771 if (!Target) 772 return createStringError(inconvertibleErrorCode(), 773 Twine("could not allocate target machine for ") + 774 TargetTriple); 775 return std::unique_ptr<TargetMachine>(Target); 776 } 777