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