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::Reserved, "reserved", 215 "Enable frame pointer elimination, but reserve the frame " 216 "pointer register"), 217 clEnumValN(FramePointerKind::None, "none", 218 "Enable frame pointer elimination"))); 219 CGBINDOPT(FramePointerUsage); 220 221 static cl::opt<bool> EnableUnsafeFPMath( 222 "enable-unsafe-fp-math", 223 cl::desc("Enable optimizations that may decrease FP precision"), 224 cl::init(false)); 225 CGBINDOPT(EnableUnsafeFPMath); 226 227 static cl::opt<bool> EnableNoInfsFPMath( 228 "enable-no-infs-fp-math", 229 cl::desc("Enable FP math optimizations that assume no +-Infs"), 230 cl::init(false)); 231 CGBINDOPT(EnableNoInfsFPMath); 232 233 static cl::opt<bool> EnableNoNaNsFPMath( 234 "enable-no-nans-fp-math", 235 cl::desc("Enable FP math optimizations that assume no NaNs"), 236 cl::init(false)); 237 CGBINDOPT(EnableNoNaNsFPMath); 238 239 static cl::opt<bool> EnableNoSignedZerosFPMath( 240 "enable-no-signed-zeros-fp-math", 241 cl::desc("Enable FP math optimizations that assume " 242 "the sign of 0 is insignificant"), 243 cl::init(false)); 244 CGBINDOPT(EnableNoSignedZerosFPMath); 245 246 static cl::opt<bool> EnableApproxFuncFPMath( 247 "enable-approx-func-fp-math", 248 cl::desc("Enable FP math optimizations that assume approx func"), 249 cl::init(false)); 250 CGBINDOPT(EnableApproxFuncFPMath); 251 252 static cl::opt<bool> EnableNoTrappingFPMath( 253 "enable-no-trapping-fp-math", 254 cl::desc("Enable setting the FP exceptions build " 255 "attribute not to use exceptions"), 256 cl::init(false)); 257 CGBINDOPT(EnableNoTrappingFPMath); 258 259 static const auto DenormFlagEnumOptions = cl::values( 260 clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"), 261 clEnumValN(DenormalMode::PreserveSign, "preserve-sign", 262 "the sign of a flushed-to-zero number is preserved " 263 "in the sign of 0"), 264 clEnumValN(DenormalMode::PositiveZero, "positive-zero", 265 "denormals are flushed to positive zero"), 266 clEnumValN(DenormalMode::Dynamic, "dynamic", 267 "denormals have unknown treatment")); 268 269 // FIXME: Doesn't have way to specify separate input and output modes. 270 static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath( 271 "denormal-fp-math", 272 cl::desc("Select which denormal numbers the code is permitted to require"), 273 cl::init(DenormalMode::IEEE), 274 DenormFlagEnumOptions); 275 CGBINDOPT(DenormalFPMath); 276 277 static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math( 278 "denormal-fp-math-f32", 279 cl::desc("Select which denormal numbers the code is permitted to require for float"), 280 cl::init(DenormalMode::Invalid), 281 DenormFlagEnumOptions); 282 CGBINDOPT(DenormalFP32Math); 283 284 static cl::opt<bool> EnableHonorSignDependentRoundingFPMath( 285 "enable-sign-dependent-rounding-fp-math", cl::Hidden, 286 cl::desc("Force codegen to assume rounding mode can change dynamically"), 287 cl::init(false)); 288 CGBINDOPT(EnableHonorSignDependentRoundingFPMath); 289 290 static cl::opt<FloatABI::ABIType> FloatABIForCalls( 291 "float-abi", cl::desc("Choose float ABI type"), 292 cl::init(FloatABI::Default), 293 cl::values(clEnumValN(FloatABI::Default, "default", 294 "Target default float ABI type"), 295 clEnumValN(FloatABI::Soft, "soft", 296 "Soft float ABI (implied by -soft-float)"), 297 clEnumValN(FloatABI::Hard, "hard", 298 "Hard float ABI (uses FP registers)"))); 299 CGBINDOPT(FloatABIForCalls); 300 301 static cl::opt<FPOpFusion::FPOpFusionMode> FuseFPOps( 302 "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"), 303 cl::init(FPOpFusion::Standard), 304 cl::values( 305 clEnumValN(FPOpFusion::Fast, "fast", 306 "Fuse FP ops whenever profitable"), 307 clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."), 308 clEnumValN(FPOpFusion::Strict, "off", 309 "Only fuse FP ops when the result won't be affected."))); 310 CGBINDOPT(FuseFPOps); 311 312 static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer( 313 "swift-async-fp", 314 cl::desc("Determine when the Swift async frame pointer should be set"), 315 cl::init(SwiftAsyncFramePointerMode::Always), 316 cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto", 317 "Determine based on deployment target"), 318 clEnumValN(SwiftAsyncFramePointerMode::Always, "always", 319 "Always set the bit"), 320 clEnumValN(SwiftAsyncFramePointerMode::Never, "never", 321 "Never set the bit"))); 322 CGBINDOPT(SwiftAsyncFramePointer); 323 324 static cl::opt<bool> DontPlaceZerosInBSS( 325 "nozero-initialized-in-bss", 326 cl::desc("Don't place zero-initialized symbols into bss section"), 327 cl::init(false)); 328 CGBINDOPT(DontPlaceZerosInBSS); 329 330 static cl::opt<bool> EnableAIXExtendedAltivecABI( 331 "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."), 332 cl::init(false)); 333 CGBINDOPT(EnableAIXExtendedAltivecABI); 334 335 static cl::opt<bool> EnableGuaranteedTailCallOpt( 336 "tailcallopt", 337 cl::desc( 338 "Turn fastcc calls into tail calls by (potentially) changing ABI."), 339 cl::init(false)); 340 CGBINDOPT(EnableGuaranteedTailCallOpt); 341 342 static cl::opt<bool> DisableTailCalls( 343 "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false)); 344 CGBINDOPT(DisableTailCalls); 345 346 static cl::opt<bool> StackSymbolOrdering( 347 "stack-symbol-ordering", cl::desc("Order local stack symbols."), 348 cl::init(true)); 349 CGBINDOPT(StackSymbolOrdering); 350 351 static cl::opt<bool> StackRealign( 352 "stackrealign", 353 cl::desc("Force align the stack to the minimum alignment"), 354 cl::init(false)); 355 CGBINDOPT(StackRealign); 356 357 static cl::opt<std::string> TrapFuncName( 358 "trap-func", cl::Hidden, 359 cl::desc("Emit a call to trap function rather than a trap instruction"), 360 cl::init("")); 361 CGBINDOPT(TrapFuncName); 362 363 static cl::opt<bool> UseCtors("use-ctors", 364 cl::desc("Use .ctors instead of .init_array."), 365 cl::init(false)); 366 CGBINDOPT(UseCtors); 367 368 static cl::opt<bool> DataSections( 369 "data-sections", cl::desc("Emit data into separate sections"), 370 cl::init(false)); 371 CGBINDOPT(DataSections); 372 373 static cl::opt<bool> FunctionSections( 374 "function-sections", cl::desc("Emit functions into separate sections"), 375 cl::init(false)); 376 CGBINDOPT(FunctionSections); 377 378 static cl::opt<bool> IgnoreXCOFFVisibility( 379 "ignore-xcoff-visibility", 380 cl::desc("Not emit the visibility attribute for asm in AIX OS or give " 381 "all symbols 'unspecified' visibility in XCOFF object file"), 382 cl::init(false)); 383 CGBINDOPT(IgnoreXCOFFVisibility); 384 385 static cl::opt<bool> XCOFFTracebackTable( 386 "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"), 387 cl::init(true)); 388 CGBINDOPT(XCOFFTracebackTable); 389 390 static cl::opt<bool> EnableBBAddrMap( 391 "basic-block-address-map", 392 cl::desc("Emit the basic block address map section"), cl::init(false)); 393 CGBINDOPT(EnableBBAddrMap); 394 395 static cl::opt<std::string> BBSections( 396 "basic-block-sections", 397 cl::desc("Emit basic blocks into separate sections"), 398 cl::value_desc("all | <function list (file)> | labels | none"), 399 cl::init("none")); 400 CGBINDOPT(BBSections); 401 402 static cl::opt<unsigned> TLSSize( 403 "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0)); 404 CGBINDOPT(TLSSize); 405 406 static cl::opt<bool> EmulatedTLS( 407 "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false)); 408 CGBINDOPT(EmulatedTLS); 409 410 static cl::opt<bool> EnableTLSDESC( 411 "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"), 412 cl::init(false)); 413 CGBINDOPT(EnableTLSDESC); 414 415 static cl::opt<bool> UniqueSectionNames( 416 "unique-section-names", cl::desc("Give unique names to every section"), 417 cl::init(true)); 418 CGBINDOPT(UniqueSectionNames); 419 420 static cl::opt<bool> UniqueBasicBlockSectionNames( 421 "unique-basic-block-section-names", 422 cl::desc("Give unique names to every basic block section"), 423 cl::init(false)); 424 CGBINDOPT(UniqueBasicBlockSectionNames); 425 426 static cl::opt<bool> SeparateNamedSections( 427 "separate-named-sections", 428 cl::desc("Use separate unique sections for named sections"), 429 cl::init(false)); 430 CGBINDOPT(SeparateNamedSections); 431 432 static cl::opt<EABI> EABIVersion( 433 "meabi", cl::desc("Set EABI type (default depends on triple):"), 434 cl::init(EABI::Default), 435 cl::values( 436 clEnumValN(EABI::Default, "default", "Triple default EABI version"), 437 clEnumValN(EABI::EABI4, "4", "EABI version 4"), 438 clEnumValN(EABI::EABI5, "5", "EABI version 5"), 439 clEnumValN(EABI::GNU, "gnu", "EABI GNU"))); 440 CGBINDOPT(EABIVersion); 441 442 static cl::opt<DebuggerKind> DebuggerTuningOpt( 443 "debugger-tune", cl::desc("Tune debug info for a particular debugger"), 444 cl::init(DebuggerKind::Default), 445 cl::values( 446 clEnumValN(DebuggerKind::GDB, "gdb", "gdb"), 447 clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"), 448 clEnumValN(DebuggerKind::DBX, "dbx", "dbx"), 449 clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)"))); 450 CGBINDOPT(DebuggerTuningOpt); 451 452 static cl::opt<bool> EnableStackSizeSection( 453 "stack-size-section", 454 cl::desc("Emit a section containing stack size metadata"), 455 cl::init(false)); 456 CGBINDOPT(EnableStackSizeSection); 457 458 static cl::opt<bool> EnableAddrsig( 459 "addrsig", cl::desc("Emit an address-significance table"), 460 cl::init(false)); 461 CGBINDOPT(EnableAddrsig); 462 463 static cl::opt<bool> EmitCallSiteInfo( 464 "emit-call-site-info", 465 cl::desc( 466 "Emit call site debug information, if debug information is enabled."), 467 cl::init(false)); 468 CGBINDOPT(EmitCallSiteInfo); 469 470 static cl::opt<bool> EnableDebugEntryValues( 471 "debug-entry-values", 472 cl::desc("Enable debug info for the debug entry values."), 473 cl::init(false)); 474 CGBINDOPT(EnableDebugEntryValues); 475 476 static cl::opt<bool> EnableMachineFunctionSplitter( 477 "split-machine-functions", 478 cl::desc("Split out cold basic blocks from machine functions based on " 479 "profile information"), 480 cl::init(false)); 481 CGBINDOPT(EnableMachineFunctionSplitter); 482 483 static cl::opt<bool> ForceDwarfFrameSection( 484 "force-dwarf-frame-section", 485 cl::desc("Always emit a debug frame section."), cl::init(false)); 486 CGBINDOPT(ForceDwarfFrameSection); 487 488 static cl::opt<bool> XRayFunctionIndex("xray-function-index", 489 cl::desc("Emit xray_fn_idx section"), 490 cl::init(true)); 491 CGBINDOPT(XRayFunctionIndex); 492 493 static cl::opt<bool> DebugStrictDwarf( 494 "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false)); 495 CGBINDOPT(DebugStrictDwarf); 496 497 static cl::opt<unsigned> AlignLoops("align-loops", 498 cl::desc("Default alignment for loops")); 499 CGBINDOPT(AlignLoops); 500 501 static cl::opt<bool> JMCInstrument( 502 "enable-jmc-instrument", 503 cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"), 504 cl::init(false)); 505 CGBINDOPT(JMCInstrument); 506 507 static cl::opt<bool> XCOFFReadOnlyPointers( 508 "mxcoff-roptr", 509 cl::desc("When set to true, const objects with relocatable address " 510 "values are put into the RO data section."), 511 cl::init(false)); 512 CGBINDOPT(XCOFFReadOnlyPointers); 513 514 static cl::opt<bool> DisableIntegratedAS( 515 "no-integrated-as", cl::desc("Disable integrated assembler"), 516 cl::init(false)); 517 CGBINDOPT(DisableIntegratedAS); 518 519 #undef CGBINDOPT 520 521 mc::RegisterMCTargetOptionsFlags(); 522 } 523 524 llvm::BasicBlockSection 525 codegen::getBBSectionsMode(llvm::TargetOptions &Options) { 526 if (getBBSections() == "all") 527 return BasicBlockSection::All; 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.DataSections = 572 getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections()); 573 Options.FunctionSections = getFunctionSections(); 574 Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility(); 575 Options.XCOFFTracebackTable = getXCOFFTracebackTable(); 576 Options.BBAddrMap = getEnableBBAddrMap(); 577 Options.BBSections = getBBSectionsMode(Options); 578 Options.UniqueSectionNames = getUniqueSectionNames(); 579 Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames(); 580 Options.SeparateNamedSections = getSeparateNamedSections(); 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 for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures()) 627 Features.AddFeature(Feature, IsEnabled); 628 629 for (auto const &MAttr : getMAttrs()) 630 Features.AddFeature(MAttr); 631 632 return Features.getString(); 633 } 634 635 std::vector<std::string> codegen::getFeatureList() { 636 SubtargetFeatures Features; 637 638 // If user asked for the 'native' CPU, we need to autodetect features. 639 // This is necessary for x86 where the CPU might not support all the 640 // features the autodetected CPU name lists in the target. For example, 641 // not all Sandybridge processors support AVX. 642 if (getMCPU() == "native") 643 for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures()) 644 Features.AddFeature(Feature, IsEnabled); 645 646 for (auto const &MAttr : getMAttrs()) 647 Features.AddFeature(MAttr); 648 649 return Features.getFeatures(); 650 } 651 652 void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) { 653 B.addAttribute(Name, Val ? "true" : "false"); 654 } 655 656 #define HANDLE_BOOL_ATTR(CL, AttrName) \ 657 do { \ 658 if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName)) \ 659 renderBoolStringAttr(NewAttrs, AttrName, *CL); \ 660 } while (0) 661 662 /// Set function attributes of function \p F based on CPU, Features, and command 663 /// line flags. 664 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features, 665 Function &F) { 666 auto &Ctx = F.getContext(); 667 AttributeList Attrs = F.getAttributes(); 668 AttrBuilder NewAttrs(Ctx); 669 670 if (!CPU.empty() && !F.hasFnAttribute("target-cpu")) 671 NewAttrs.addAttribute("target-cpu", CPU); 672 if (!Features.empty()) { 673 // Append the command line features to any that are already on the function. 674 StringRef OldFeatures = 675 F.getFnAttribute("target-features").getValueAsString(); 676 if (OldFeatures.empty()) 677 NewAttrs.addAttribute("target-features", Features); 678 else { 679 SmallString<256> Appended(OldFeatures); 680 Appended.push_back(','); 681 Appended.append(Features); 682 NewAttrs.addAttribute("target-features", Appended); 683 } 684 } 685 if (FramePointerUsageView->getNumOccurrences() > 0 && 686 !F.hasFnAttribute("frame-pointer")) { 687 if (getFramePointerUsage() == FramePointerKind::All) 688 NewAttrs.addAttribute("frame-pointer", "all"); 689 else if (getFramePointerUsage() == FramePointerKind::NonLeaf) 690 NewAttrs.addAttribute("frame-pointer", "non-leaf"); 691 else if (getFramePointerUsage() == FramePointerKind::Reserved) 692 NewAttrs.addAttribute("frame-pointer", "reserved"); 693 else if (getFramePointerUsage() == FramePointerKind::None) 694 NewAttrs.addAttribute("frame-pointer", "none"); 695 } 696 if (DisableTailCallsView->getNumOccurrences() > 0) 697 NewAttrs.addAttribute("disable-tail-calls", 698 toStringRef(getDisableTailCalls())); 699 if (getStackRealign()) 700 NewAttrs.addAttribute("stackrealign"); 701 702 HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math"); 703 HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math"); 704 HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math"); 705 HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math"); 706 HANDLE_BOOL_ATTR(EnableApproxFuncFPMathView, "approx-func-fp-math"); 707 708 if (DenormalFPMathView->getNumOccurrences() > 0 && 709 !F.hasFnAttribute("denormal-fp-math")) { 710 DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); 711 712 // FIXME: Command line flag should expose separate input/output modes. 713 NewAttrs.addAttribute("denormal-fp-math", 714 DenormalMode(DenormKind, DenormKind).str()); 715 } 716 717 if (DenormalFP32MathView->getNumOccurrences() > 0 && 718 !F.hasFnAttribute("denormal-fp-math-f32")) { 719 // FIXME: Command line flag should expose separate input/output modes. 720 DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math(); 721 722 NewAttrs.addAttribute( 723 "denormal-fp-math-f32", 724 DenormalMode(DenormKind, DenormKind).str()); 725 } 726 727 if (TrapFuncNameView->getNumOccurrences() > 0) 728 for (auto &B : F) 729 for (auto &I : B) 730 if (auto *Call = dyn_cast<CallInst>(&I)) 731 if (const auto *F = Call->getCalledFunction()) 732 if (F->getIntrinsicID() == Intrinsic::debugtrap || 733 F->getIntrinsicID() == Intrinsic::trap) 734 Call->addFnAttr( 735 Attribute::get(Ctx, "trap-func-name", getTrapFuncName())); 736 737 // Let NewAttrs override Attrs. 738 F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs)); 739 } 740 741 /// Set function attributes of functions in Module M based on CPU, 742 /// Features, and command line flags. 743 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features, 744 Module &M) { 745 for (Function &F : M) 746 setFunctionAttributes(CPU, Features, F); 747 } 748 749 Expected<std::unique_ptr<TargetMachine>> 750 codegen::createTargetMachineForTriple(StringRef TargetTriple, 751 CodeGenOptLevel OptLevel) { 752 Triple TheTriple(TargetTriple); 753 std::string Error; 754 const auto *TheTarget = 755 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); 756 if (!TheTarget) 757 return createStringError(inconvertibleErrorCode(), Error); 758 auto *Target = TheTarget->createTargetMachine( 759 TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(), 760 codegen::InitTargetOptionsFromCodeGenFlags(TheTriple), 761 codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(), 762 OptLevel); 763 if (!Target) 764 return createStringError(inconvertibleErrorCode(), 765 Twine("could not allocate target machine for ") + 766 TargetTriple); 767 return std::unique_ptr<TargetMachine>(Target); 768 } 769