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