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