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