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, 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> DataSections( 366 "data-sections", cl::desc("Emit data into separate sections"), 367 cl::init(false)); 368 CGBINDOPT(DataSections); 369 370 static cl::opt<bool> FunctionSections( 371 "function-sections", cl::desc("Emit functions into separate sections"), 372 cl::init(false)); 373 CGBINDOPT(FunctionSections); 374 375 static cl::opt<bool> IgnoreXCOFFVisibility( 376 "ignore-xcoff-visibility", 377 cl::desc("Not emit the visibility attribute for asm in AIX OS or give " 378 "all symbols 'unspecified' visibility in XCOFF object file"), 379 cl::init(false)); 380 CGBINDOPT(IgnoreXCOFFVisibility); 381 382 static cl::opt<bool> XCOFFTracebackTable( 383 "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"), 384 cl::init(true)); 385 CGBINDOPT(XCOFFTracebackTable); 386 387 static cl::opt<bool> EnableBBAddrMap( 388 "basic-block-address-map", 389 cl::desc("Emit the basic block address map section"), cl::init(false)); 390 CGBINDOPT(EnableBBAddrMap); 391 392 static cl::opt<std::string> BBSections( 393 "basic-block-sections", 394 cl::desc("Emit basic blocks into separate sections"), 395 cl::value_desc("all | <function list (file)> | labels | none"), 396 cl::init("none")); 397 CGBINDOPT(BBSections); 398 399 static cl::opt<unsigned> TLSSize( 400 "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0)); 401 CGBINDOPT(TLSSize); 402 403 static cl::opt<bool> EmulatedTLS( 404 "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false)); 405 CGBINDOPT(EmulatedTLS); 406 407 static cl::opt<bool> EnableTLSDESC( 408 "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"), 409 cl::init(false)); 410 CGBINDOPT(EnableTLSDESC); 411 412 static cl::opt<bool> UniqueSectionNames( 413 "unique-section-names", cl::desc("Give unique names to every section"), 414 cl::init(true)); 415 CGBINDOPT(UniqueSectionNames); 416 417 static cl::opt<bool> UniqueBasicBlockSectionNames( 418 "unique-basic-block-section-names", 419 cl::desc("Give unique names to every basic block section"), 420 cl::init(false)); 421 CGBINDOPT(UniqueBasicBlockSectionNames); 422 423 static cl::opt<bool> SeparateNamedSections( 424 "separate-named-sections", 425 cl::desc("Use separate unique sections for named sections"), 426 cl::init(false)); 427 CGBINDOPT(SeparateNamedSections); 428 429 static cl::opt<EABI> EABIVersion( 430 "meabi", cl::desc("Set EABI type (default depends on triple):"), 431 cl::init(EABI::Default), 432 cl::values( 433 clEnumValN(EABI::Default, "default", "Triple default EABI version"), 434 clEnumValN(EABI::EABI4, "4", "EABI version 4"), 435 clEnumValN(EABI::EABI5, "5", "EABI version 5"), 436 clEnumValN(EABI::GNU, "gnu", "EABI GNU"))); 437 CGBINDOPT(EABIVersion); 438 439 static cl::opt<DebuggerKind> DebuggerTuningOpt( 440 "debugger-tune", cl::desc("Tune debug info for a particular debugger"), 441 cl::init(DebuggerKind::Default), 442 cl::values( 443 clEnumValN(DebuggerKind::GDB, "gdb", "gdb"), 444 clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"), 445 clEnumValN(DebuggerKind::DBX, "dbx", "dbx"), 446 clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)"))); 447 CGBINDOPT(DebuggerTuningOpt); 448 449 static cl::opt<bool> EnableStackSizeSection( 450 "stack-size-section", 451 cl::desc("Emit a section containing stack size metadata"), 452 cl::init(false)); 453 CGBINDOPT(EnableStackSizeSection); 454 455 static cl::opt<bool> EnableAddrsig( 456 "addrsig", cl::desc("Emit an address-significance table"), 457 cl::init(false)); 458 CGBINDOPT(EnableAddrsig); 459 460 static cl::opt<bool> EmitCallSiteInfo( 461 "emit-call-site-info", 462 cl::desc( 463 "Emit call site debug information, if debug information is enabled."), 464 cl::init(false)); 465 CGBINDOPT(EmitCallSiteInfo); 466 467 static cl::opt<bool> EnableDebugEntryValues( 468 "debug-entry-values", 469 cl::desc("Enable debug info for the debug entry values."), 470 cl::init(false)); 471 CGBINDOPT(EnableDebugEntryValues); 472 473 static cl::opt<bool> EnableMachineFunctionSplitter( 474 "split-machine-functions", 475 cl::desc("Split out cold basic blocks from machine functions based on " 476 "profile information"), 477 cl::init(false)); 478 CGBINDOPT(EnableMachineFunctionSplitter); 479 480 static cl::opt<bool> ForceDwarfFrameSection( 481 "force-dwarf-frame-section", 482 cl::desc("Always emit a debug frame section."), cl::init(false)); 483 CGBINDOPT(ForceDwarfFrameSection); 484 485 static cl::opt<bool> XRayFunctionIndex("xray-function-index", 486 cl::desc("Emit xray_fn_idx section"), 487 cl::init(true)); 488 CGBINDOPT(XRayFunctionIndex); 489 490 static cl::opt<bool> DebugStrictDwarf( 491 "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false)); 492 CGBINDOPT(DebugStrictDwarf); 493 494 static cl::opt<unsigned> AlignLoops("align-loops", 495 cl::desc("Default alignment for loops")); 496 CGBINDOPT(AlignLoops); 497 498 static cl::opt<bool> JMCInstrument( 499 "enable-jmc-instrument", 500 cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"), 501 cl::init(false)); 502 CGBINDOPT(JMCInstrument); 503 504 static cl::opt<bool> XCOFFReadOnlyPointers( 505 "mxcoff-roptr", 506 cl::desc("When set to true, const objects with relocatable address " 507 "values are put into the RO data section."), 508 cl::init(false)); 509 CGBINDOPT(XCOFFReadOnlyPointers); 510 511 static cl::opt<bool> DisableIntegratedAS( 512 "no-integrated-as", cl::desc("Disable integrated assembler"), 513 cl::init(false)); 514 CGBINDOPT(DisableIntegratedAS); 515 516 #undef CGBINDOPT 517 518 mc::RegisterMCTargetOptionsFlags(); 519 } 520 521 llvm::BasicBlockSection 522 codegen::getBBSectionsMode(llvm::TargetOptions &Options) { 523 if (getBBSections() == "all") 524 return BasicBlockSection::All; 525 else if (getBBSections() == "labels") 526 return BasicBlockSection::Labels; 527 else if (getBBSections() == "none") 528 return BasicBlockSection::None; 529 else { 530 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = 531 MemoryBuffer::getFile(getBBSections()); 532 if (!MBOrErr) { 533 errs() << "Error loading basic block sections function list file: " 534 << MBOrErr.getError().message() << "\n"; 535 } else { 536 Options.BBSectionsFuncListBuf = std::move(*MBOrErr); 537 } 538 return BasicBlockSection::List; 539 } 540 } 541 542 // Common utility function tightly tied to the options listed here. Initializes 543 // a TargetOptions object with CodeGen flags and returns it. 544 TargetOptions 545 codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) { 546 TargetOptions Options; 547 Options.AllowFPOpFusion = getFuseFPOps(); 548 Options.UnsafeFPMath = getEnableUnsafeFPMath(); 549 Options.NoInfsFPMath = getEnableNoInfsFPMath(); 550 Options.NoNaNsFPMath = getEnableNoNaNsFPMath(); 551 Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath(); 552 Options.ApproxFuncFPMath = getEnableApproxFuncFPMath(); 553 Options.NoTrappingFPMath = getEnableNoTrappingFPMath(); 554 555 DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); 556 557 // FIXME: Should have separate input and output flags 558 Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind)); 559 560 Options.HonorSignDependentRoundingFPMathOption = 561 getEnableHonorSignDependentRoundingFPMath(); 562 if (getFloatABIForCalls() != FloatABI::Default) 563 Options.FloatABIType = getFloatABIForCalls(); 564 Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI(); 565 Options.NoZerosInBSS = getDontPlaceZerosInBSS(); 566 Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt(); 567 Options.StackSymbolOrdering = getStackSymbolOrdering(); 568 Options.UseInitArray = !getUseCtors(); 569 Options.DisableIntegratedAS = getDisableIntegratedAS(); 570 Options.DataSections = 571 getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections()); 572 Options.FunctionSections = getFunctionSections(); 573 Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility(); 574 Options.XCOFFTracebackTable = getXCOFFTracebackTable(); 575 Options.BBAddrMap = getEnableBBAddrMap(); 576 Options.BBSections = getBBSectionsMode(Options); 577 Options.UniqueSectionNames = getUniqueSectionNames(); 578 Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames(); 579 Options.SeparateNamedSections = getSeparateNamedSections(); 580 Options.TLSSize = getTLSSize(); 581 Options.EmulatedTLS = 582 getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS()); 583 Options.EnableTLSDESC = 584 getExplicitEnableTLSDESC().value_or(TheTriple.hasDefaultTLSDESC()); 585 Options.ExceptionModel = getExceptionModel(); 586 Options.EmitStackSizeSection = getEnableStackSizeSection(); 587 Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter(); 588 Options.EmitAddrsig = getEnableAddrsig(); 589 Options.EmitCallSiteInfo = getEmitCallSiteInfo(); 590 Options.EnableDebugEntryValues = getEnableDebugEntryValues(); 591 Options.ForceDwarfFrameSection = getForceDwarfFrameSection(); 592 Options.XRayFunctionIndex = getXRayFunctionIndex(); 593 Options.DebugStrictDwarf = getDebugStrictDwarf(); 594 Options.LoopAlignment = getAlignLoops(); 595 Options.JMCInstrument = getJMCInstrument(); 596 Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers(); 597 598 Options.MCOptions = mc::InitMCTargetOptionsFromFlags(); 599 600 Options.ThreadModel = getThreadModel(); 601 Options.EABIVersion = getEABIVersion(); 602 Options.DebuggerTuning = getDebuggerTuningOpt(); 603 Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer(); 604 return Options; 605 } 606 607 std::string codegen::getCPUStr() { 608 // If user asked for the 'native' CPU, autodetect here. If autodection fails, 609 // this will set the CPU to an empty string which tells the target to 610 // pick a basic default. 611 if (getMCPU() == "native") 612 return std::string(sys::getHostCPUName()); 613 614 return getMCPU(); 615 } 616 617 std::string codegen::getFeaturesStr() { 618 SubtargetFeatures Features; 619 620 // If user asked for the 'native' CPU, we need to autodetect features. 621 // This is necessary for x86 where the CPU might not support all the 622 // features the autodetected CPU name lists in the target. For example, 623 // not all Sandybridge processors support AVX. 624 if (getMCPU() == "native") { 625 StringMap<bool> HostFeatures; 626 if (sys::getHostCPUFeatures(HostFeatures)) 627 for (const auto &[Feature, IsEnabled] : HostFeatures) 628 Features.AddFeature(Feature, IsEnabled); 629 } 630 631 for (auto const &MAttr : getMAttrs()) 632 Features.AddFeature(MAttr); 633 634 return Features.getString(); 635 } 636 637 std::vector<std::string> codegen::getFeatureList() { 638 SubtargetFeatures Features; 639 640 // If user asked for the 'native' CPU, we need to autodetect features. 641 // This is necessary for x86 where the CPU might not support all the 642 // features the autodetected CPU name lists in the target. For example, 643 // not all Sandybridge processors support AVX. 644 if (getMCPU() == "native") { 645 StringMap<bool> HostFeatures; 646 if (sys::getHostCPUFeatures(HostFeatures)) 647 for (const auto &[Feature, IsEnabled] : HostFeatures) 648 Features.AddFeature(Feature, IsEnabled); 649 } 650 651 for (auto const &MAttr : getMAttrs()) 652 Features.AddFeature(MAttr); 653 654 return Features.getFeatures(); 655 } 656 657 void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) { 658 B.addAttribute(Name, Val ? "true" : "false"); 659 } 660 661 #define HANDLE_BOOL_ATTR(CL, AttrName) \ 662 do { \ 663 if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName)) \ 664 renderBoolStringAttr(NewAttrs, AttrName, *CL); \ 665 } while (0) 666 667 /// Set function attributes of function \p F based on CPU, Features, and command 668 /// line flags. 669 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features, 670 Function &F) { 671 auto &Ctx = F.getContext(); 672 AttributeList Attrs = F.getAttributes(); 673 AttrBuilder NewAttrs(Ctx); 674 675 if (!CPU.empty() && !F.hasFnAttribute("target-cpu")) 676 NewAttrs.addAttribute("target-cpu", CPU); 677 if (!Features.empty()) { 678 // Append the command line features to any that are already on the function. 679 StringRef OldFeatures = 680 F.getFnAttribute("target-features").getValueAsString(); 681 if (OldFeatures.empty()) 682 NewAttrs.addAttribute("target-features", Features); 683 else { 684 SmallString<256> Appended(OldFeatures); 685 Appended.push_back(','); 686 Appended.append(Features); 687 NewAttrs.addAttribute("target-features", Appended); 688 } 689 } 690 if (FramePointerUsageView->getNumOccurrences() > 0 && 691 !F.hasFnAttribute("frame-pointer")) { 692 if (getFramePointerUsage() == FramePointerKind::All) 693 NewAttrs.addAttribute("frame-pointer", "all"); 694 else if (getFramePointerUsage() == FramePointerKind::NonLeaf) 695 NewAttrs.addAttribute("frame-pointer", "non-leaf"); 696 else if (getFramePointerUsage() == FramePointerKind::None) 697 NewAttrs.addAttribute("frame-pointer", "none"); 698 } 699 if (DisableTailCallsView->getNumOccurrences() > 0) 700 NewAttrs.addAttribute("disable-tail-calls", 701 toStringRef(getDisableTailCalls())); 702 if (getStackRealign()) 703 NewAttrs.addAttribute("stackrealign"); 704 705 HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math"); 706 HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math"); 707 HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math"); 708 HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math"); 709 HANDLE_BOOL_ATTR(EnableApproxFuncFPMathView, "approx-func-fp-math"); 710 711 if (DenormalFPMathView->getNumOccurrences() > 0 && 712 !F.hasFnAttribute("denormal-fp-math")) { 713 DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); 714 715 // FIXME: Command line flag should expose separate input/output modes. 716 NewAttrs.addAttribute("denormal-fp-math", 717 DenormalMode(DenormKind, DenormKind).str()); 718 } 719 720 if (DenormalFP32MathView->getNumOccurrences() > 0 && 721 !F.hasFnAttribute("denormal-fp-math-f32")) { 722 // FIXME: Command line flag should expose separate input/output modes. 723 DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math(); 724 725 NewAttrs.addAttribute( 726 "denormal-fp-math-f32", 727 DenormalMode(DenormKind, DenormKind).str()); 728 } 729 730 if (TrapFuncNameView->getNumOccurrences() > 0) 731 for (auto &B : F) 732 for (auto &I : B) 733 if (auto *Call = dyn_cast<CallInst>(&I)) 734 if (const auto *F = Call->getCalledFunction()) 735 if (F->getIntrinsicID() == Intrinsic::debugtrap || 736 F->getIntrinsicID() == Intrinsic::trap) 737 Call->addFnAttr( 738 Attribute::get(Ctx, "trap-func-name", getTrapFuncName())); 739 740 // Let NewAttrs override Attrs. 741 F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs)); 742 } 743 744 /// Set function attributes of functions in Module M based on CPU, 745 /// Features, and command line flags. 746 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features, 747 Module &M) { 748 for (Function &F : M) 749 setFunctionAttributes(CPU, Features, F); 750 } 751 752 Expected<std::unique_ptr<TargetMachine>> 753 codegen::createTargetMachineForTriple(StringRef TargetTriple, 754 CodeGenOptLevel OptLevel) { 755 Triple TheTriple(TargetTriple); 756 std::string Error; 757 const auto *TheTarget = 758 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); 759 if (!TheTarget) 760 return createStringError(inconvertibleErrorCode(), Error); 761 auto *Target = TheTarget->createTargetMachine( 762 TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(), 763 codegen::InitTargetOptionsFromCodeGenFlags(TheTriple), 764 codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(), 765 OptLevel); 766 if (!Target) 767 return createStringError(inconvertibleErrorCode(), 768 Twine("could not allocate target machine for ") + 769 TargetTriple); 770 return std::unique_ptr<TargetMachine>(Target); 771 } 772