brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.5 KiB · 8f92ee3 Raw
859 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains codegen-specific flags that are shared between different10// command line tools. The tools "llc" and "opt" both use this file to prevent11// flag duplication.12//13//===----------------------------------------------------------------------===//14 15#include "llvm/CodeGen/CommandFlags.h"16#include "llvm/ADT/SmallString.h"17#include "llvm/ADT/Statistic.h"18#include "llvm/ADT/StringExtras.h"19#include "llvm/ADT/StringRef.h"20#include "llvm/IR/Instructions.h"21#include "llvm/IR/Intrinsics.h"22#include "llvm/IR/Module.h"23#include "llvm/MC/MCTargetOptionsCommandFlags.h"24#include "llvm/MC/TargetRegistry.h"25#include "llvm/Support/CommandLine.h"26#include "llvm/Support/FileSystem.h"27#include "llvm/Support/MemoryBuffer.h"28#include "llvm/Support/Path.h"29#include "llvm/Support/WithColor.h"30#include "llvm/Support/raw_ostream.h"31#include "llvm/Target/TargetMachine.h"32#include "llvm/TargetParser/Host.h"33#include "llvm/TargetParser/SubtargetFeature.h"34#include "llvm/TargetParser/Triple.h"35#include <cassert>36#include <memory>37#include <optional>38#include <system_error>39 40using namespace llvm;41 42#define CGOPT(TY, NAME)                                                        \43  static cl::opt<TY> *NAME##View;                                              \44  TY codegen::get##NAME() {                                                    \45    assert(NAME##View && "Flag not registered.");                              \46    return *NAME##View;                                                        \47  }48 49#define CGLIST(TY, NAME)                                                       \50  static cl::list<TY> *NAME##View;                                             \51  std::vector<TY> codegen::get##NAME() {                                       \52    assert(NAME##View && "Flag not registered.");                              \53    return *NAME##View;                                                        \54  }55 56// Temporary macro for incremental transition to std::optional.57#define CGOPT_EXP(TY, NAME)                                                    \58  CGOPT(TY, NAME)                                                              \59  std::optional<TY> codegen::getExplicit##NAME() {                             \60    if (NAME##View->getNumOccurrences()) {                                     \61      TY res = *NAME##View;                                                    \62      return res;                                                              \63    }                                                                          \64    return std::nullopt;                                                       \65  }66 67CGOPT(std::string, MArch)68CGOPT(std::string, MCPU)69CGLIST(std::string, MAttrs)70CGOPT_EXP(Reloc::Model, RelocModel)71CGOPT(ThreadModel::Model, ThreadModel)72CGOPT_EXP(CodeModel::Model, CodeModel)73CGOPT_EXP(uint64_t, LargeDataThreshold)74CGOPT(ExceptionHandling, ExceptionModel)75CGOPT_EXP(CodeGenFileType, FileType)76CGOPT(FramePointerKind, FramePointerUsage)77CGOPT(bool, EnableNoInfsFPMath)78CGOPT(bool, EnableNoNaNsFPMath)79CGOPT(bool, EnableNoSignedZerosFPMath)80CGOPT(bool, EnableNoTrappingFPMath)81CGOPT(bool, EnableAIXExtendedAltivecABI)82CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath)83CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)84CGOPT(bool, EnableHonorSignDependentRoundingFPMath)85CGOPT(FloatABI::ABIType, FloatABIForCalls)86CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)87CGOPT(SwiftAsyncFramePointerMode, SwiftAsyncFramePointer)88CGOPT(bool, DontPlaceZerosInBSS)89CGOPT(bool, EnableGuaranteedTailCallOpt)90CGOPT(bool, DisableTailCalls)91CGOPT(bool, StackSymbolOrdering)92CGOPT(bool, StackRealign)93CGOPT(std::string, TrapFuncName)94CGOPT(bool, UseCtors)95CGOPT(bool, DisableIntegratedAS)96CGOPT_EXP(bool, DataSections)97CGOPT_EXP(bool, FunctionSections)98CGOPT(bool, IgnoreXCOFFVisibility)99CGOPT(bool, XCOFFTracebackTable)100CGOPT(bool, EnableBBAddrMap)101CGOPT(std::string, BBSections)102CGOPT(unsigned, TLSSize)103CGOPT_EXP(bool, EmulatedTLS)104CGOPT_EXP(bool, EnableTLSDESC)105CGOPT(bool, UniqueSectionNames)106CGOPT(bool, UniqueBasicBlockSectionNames)107CGOPT(bool, SeparateNamedSections)108CGOPT(EABI, EABIVersion)109CGOPT(DebuggerKind, DebuggerTuningOpt)110CGOPT(VectorLibrary, VectorLibrary)111CGOPT(bool, EnableStackSizeSection)112CGOPT(bool, EnableAddrsig)113CGOPT(bool, EnableCallGraphSection)114CGOPT(bool, EmitCallSiteInfo)115CGOPT(bool, EnableMachineFunctionSplitter)116CGOPT(bool, EnableStaticDataPartitioning)117CGOPT(bool, EnableDebugEntryValues)118CGOPT(bool, ForceDwarfFrameSection)119CGOPT(bool, XRayFunctionIndex)120CGOPT(bool, DebugStrictDwarf)121CGOPT(unsigned, AlignLoops)122CGOPT(bool, JMCInstrument)123CGOPT(bool, XCOFFReadOnlyPointers)124CGOPT(codegen::SaveStatsMode, SaveStats)125 126#define CGBINDOPT(NAME)                                                        \127  do {                                                                         \128    NAME##View = std::addressof(NAME);                                         \129  } while (0)130 131codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {132  static cl::opt<std::string> MArch(133      "march", cl::desc("Architecture to generate code for (see --version)"));134  CGBINDOPT(MArch);135 136  static cl::opt<std::string> MCPU(137      "mcpu", cl::desc("Target a specific cpu type (-mcpu=help for details)"),138      cl::value_desc("cpu-name"), cl::init(""));139  CGBINDOPT(MCPU);140 141  static cl::list<std::string> MAttrs(142      "mattr", cl::CommaSeparated,143      cl::desc("Target specific attributes (-mattr=help for details)"),144      cl::value_desc("a1,+a2,-a3,..."));145  CGBINDOPT(MAttrs);146 147  static cl::opt<Reloc::Model> RelocModel(148      "relocation-model", cl::desc("Choose relocation model"),149      cl::values(150          clEnumValN(Reloc::Static, "static", "Non-relocatable code"),151          clEnumValN(Reloc::PIC_, "pic",152                     "Fully relocatable, position independent code"),153          clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",154                     "Relocatable external references, non-relocatable code"),155          clEnumValN(156              Reloc::ROPI, "ropi",157              "Code and read-only data relocatable, accessed PC-relative"),158          clEnumValN(159              Reloc::RWPI, "rwpi",160              "Read-write data relocatable, accessed relative to static base"),161          clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",162                     "Combination of ropi and rwpi")));163  CGBINDOPT(RelocModel);164 165  static cl::opt<ThreadModel::Model> ThreadModel(166      "thread-model", cl::desc("Choose threading model"),167      cl::init(ThreadModel::POSIX),168      cl::values(169          clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),170          clEnumValN(ThreadModel::Single, "single", "Single thread model")));171  CGBINDOPT(ThreadModel);172 173  static cl::opt<CodeModel::Model> CodeModel(174      "code-model", cl::desc("Choose code model"),175      cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),176                 clEnumValN(CodeModel::Small, "small", "Small code model"),177                 clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),178                 clEnumValN(CodeModel::Medium, "medium", "Medium code model"),179                 clEnumValN(CodeModel::Large, "large", "Large code model")));180  CGBINDOPT(CodeModel);181 182  static cl::opt<uint64_t> LargeDataThreshold(183      "large-data-threshold",184      cl::desc("Choose large data threshold for x86_64 medium code model"),185      cl::init(0));186  CGBINDOPT(LargeDataThreshold);187 188  static cl::opt<ExceptionHandling> ExceptionModel(189      "exception-model", cl::desc("exception model"),190      cl::init(ExceptionHandling::None),191      cl::values(192          clEnumValN(ExceptionHandling::None, "default",193                     "default exception handling model"),194          clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",195                     "DWARF-like CFI based exception handling"),196          clEnumValN(ExceptionHandling::SjLj, "sjlj",197                     "SjLj exception handling"),198          clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),199          clEnumValN(ExceptionHandling::WinEH, "wineh",200                     "Windows exception model"),201          clEnumValN(ExceptionHandling::Wasm, "wasm",202                     "WebAssembly exception handling")));203  CGBINDOPT(ExceptionModel);204 205  static cl::opt<CodeGenFileType> FileType(206      "filetype", cl::init(CodeGenFileType::AssemblyFile),207      cl::desc(208          "Choose a file type (not all types are supported by all targets):"),209      cl::values(clEnumValN(CodeGenFileType::AssemblyFile, "asm",210                            "Emit an assembly ('.s') file"),211                 clEnumValN(CodeGenFileType::ObjectFile, "obj",212                            "Emit a native object ('.o') file"),213                 clEnumValN(CodeGenFileType::Null, "null",214                            "Emit nothing, for performance testing")));215  CGBINDOPT(FileType);216 217  static cl::opt<FramePointerKind> FramePointerUsage(218      "frame-pointer",219      cl::desc("Specify frame pointer elimination optimization"),220      cl::init(FramePointerKind::None),221      cl::values(222          clEnumValN(FramePointerKind::All, "all",223                     "Disable frame pointer elimination"),224          clEnumValN(FramePointerKind::NonLeaf, "non-leaf",225                     "Disable frame pointer elimination for non-leaf frame but "226                     "reserve the register in leaf functions"),227          clEnumValN(FramePointerKind::NonLeafNoReserve, "non-leaf-no-reserve",228                     "Disable frame pointer elimination for non-leaf frame"),229          clEnumValN(FramePointerKind::Reserved, "reserved",230                     "Enable frame pointer elimination, but reserve the frame "231                     "pointer register"),232          clEnumValN(FramePointerKind::None, "none",233                     "Enable frame pointer elimination")));234  CGBINDOPT(FramePointerUsage);235 236  static cl::opt<bool> EnableNoInfsFPMath(237      "enable-no-infs-fp-math",238      cl::desc("Enable FP math optimizations that assume no +-Infs"),239      cl::init(false));240  CGBINDOPT(EnableNoInfsFPMath);241 242  static cl::opt<bool> EnableNoNaNsFPMath(243      "enable-no-nans-fp-math",244      cl::desc("Enable FP math optimizations that assume no NaNs"),245      cl::init(false));246  CGBINDOPT(EnableNoNaNsFPMath);247 248  static cl::opt<bool> EnableNoSignedZerosFPMath(249      "enable-no-signed-zeros-fp-math",250      cl::desc("Enable FP math optimizations that assume "251               "the sign of 0 is insignificant"),252      cl::init(false));253  CGBINDOPT(EnableNoSignedZerosFPMath);254 255  static cl::opt<bool> EnableNoTrappingFPMath(256      "enable-no-trapping-fp-math",257      cl::desc("Enable setting the FP exceptions build "258               "attribute not to use exceptions"),259      cl::init(false));260  CGBINDOPT(EnableNoTrappingFPMath);261 262  static const auto DenormFlagEnumOptions = cl::values(263      clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"),264      clEnumValN(DenormalMode::PreserveSign, "preserve-sign",265                 "the sign of a  flushed-to-zero number is preserved "266                 "in the sign of 0"),267      clEnumValN(DenormalMode::PositiveZero, "positive-zero",268                 "denormals are flushed to positive zero"),269      clEnumValN(DenormalMode::Dynamic, "dynamic",270                 "denormals have unknown treatment"));271 272  // FIXME: Doesn't have way to specify separate input and output modes.273  static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath(274    "denormal-fp-math",275    cl::desc("Select which denormal numbers the code is permitted to require"),276    cl::init(DenormalMode::IEEE),277    DenormFlagEnumOptions);278  CGBINDOPT(DenormalFPMath);279 280  static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math(281    "denormal-fp-math-f32",282    cl::desc("Select which denormal numbers the code is permitted to require for float"),283    cl::init(DenormalMode::Invalid),284    DenormFlagEnumOptions);285  CGBINDOPT(DenormalFP32Math);286 287  static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(288      "enable-sign-dependent-rounding-fp-math", cl::Hidden,289      cl::desc("Force codegen to assume rounding mode can change dynamically"),290      cl::init(false));291  CGBINDOPT(EnableHonorSignDependentRoundingFPMath);292 293  static cl::opt<FloatABI::ABIType> FloatABIForCalls(294      "float-abi", cl::desc("Choose float ABI type"),295      cl::init(FloatABI::Default),296      cl::values(clEnumValN(FloatABI::Default, "default",297                            "Target default float ABI type"),298                 clEnumValN(FloatABI::Soft, "soft",299                            "Soft float ABI (implied by -soft-float)"),300                 clEnumValN(FloatABI::Hard, "hard",301                            "Hard float ABI (uses FP registers)")));302  CGBINDOPT(FloatABIForCalls);303 304  static cl::opt<FPOpFusion::FPOpFusionMode> FuseFPOps(305      "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),306      cl::init(FPOpFusion::Standard),307      cl::values(308          clEnumValN(FPOpFusion::Fast, "fast",309                     "Fuse FP ops whenever profitable"),310          clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),311          clEnumValN(FPOpFusion::Strict, "off",312                     "Only fuse FP ops when the result won't be affected.")));313  CGBINDOPT(FuseFPOps);314 315  static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer(316      "swift-async-fp",317      cl::desc("Determine when the Swift async frame pointer should be set"),318      cl::init(SwiftAsyncFramePointerMode::Always),319      cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto",320                            "Determine based on deployment target"),321                 clEnumValN(SwiftAsyncFramePointerMode::Always, "always",322                            "Always set the bit"),323                 clEnumValN(SwiftAsyncFramePointerMode::Never, "never",324                            "Never set the bit")));325  CGBINDOPT(SwiftAsyncFramePointer);326 327  static cl::opt<bool> DontPlaceZerosInBSS(328      "nozero-initialized-in-bss",329      cl::desc("Don't place zero-initialized symbols into bss section"),330      cl::init(false));331  CGBINDOPT(DontPlaceZerosInBSS);332 333  static cl::opt<bool> EnableAIXExtendedAltivecABI(334      "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),335      cl::init(false));336  CGBINDOPT(EnableAIXExtendedAltivecABI);337 338  static cl::opt<bool> EnableGuaranteedTailCallOpt(339      "tailcallopt",340      cl::desc(341          "Turn fastcc calls into tail calls by (potentially) changing ABI."),342      cl::init(false));343  CGBINDOPT(EnableGuaranteedTailCallOpt);344 345  static cl::opt<bool> DisableTailCalls(346      "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false));347  CGBINDOPT(DisableTailCalls);348 349  static cl::opt<bool> StackSymbolOrdering(350      "stack-symbol-ordering", cl::desc("Order local stack symbols."),351      cl::init(true));352  CGBINDOPT(StackSymbolOrdering);353 354  static cl::opt<bool> StackRealign(355      "stackrealign",356      cl::desc("Force align the stack to the minimum alignment"),357      cl::init(false));358  CGBINDOPT(StackRealign);359 360  static cl::opt<std::string> TrapFuncName(361      "trap-func", cl::Hidden,362      cl::desc("Emit a call to trap function rather than a trap instruction"),363      cl::init(""));364  CGBINDOPT(TrapFuncName);365 366  static cl::opt<bool> UseCtors("use-ctors",367                                cl::desc("Use .ctors instead of .init_array."),368                                cl::init(false));369  CGBINDOPT(UseCtors);370 371  static cl::opt<bool> DataSections(372      "data-sections", cl::desc("Emit data into separate sections"),373      cl::init(false));374  CGBINDOPT(DataSections);375 376  static cl::opt<bool> FunctionSections(377      "function-sections", cl::desc("Emit functions into separate sections"),378      cl::init(false));379  CGBINDOPT(FunctionSections);380 381  static cl::opt<bool> IgnoreXCOFFVisibility(382      "ignore-xcoff-visibility",383      cl::desc("Not emit the visibility attribute for asm in AIX OS or give "384               "all symbols 'unspecified' visibility in XCOFF object file"),385      cl::init(false));386  CGBINDOPT(IgnoreXCOFFVisibility);387 388  static cl::opt<bool> XCOFFTracebackTable(389      "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),390      cl::init(true));391  CGBINDOPT(XCOFFTracebackTable);392 393  static cl::opt<bool> EnableBBAddrMap(394      "basic-block-address-map",395      cl::desc("Emit the basic block address map section"), cl::init(false));396  CGBINDOPT(EnableBBAddrMap);397 398  static cl::opt<std::string> BBSections(399      "basic-block-sections",400      cl::desc("Emit basic blocks into separate sections"),401      cl::value_desc("all | <function list (file)> | labels | none"),402      cl::init("none"));403  CGBINDOPT(BBSections);404 405  static cl::opt<unsigned> TLSSize(406      "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));407  CGBINDOPT(TLSSize);408 409  static cl::opt<bool> EmulatedTLS(410      "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));411  CGBINDOPT(EmulatedTLS);412 413  static cl::opt<bool> EnableTLSDESC(414      "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"),415      cl::init(false));416  CGBINDOPT(EnableTLSDESC);417 418  static cl::opt<bool> UniqueSectionNames(419      "unique-section-names", cl::desc("Give unique names to every section"),420      cl::init(true));421  CGBINDOPT(UniqueSectionNames);422 423  static cl::opt<bool> UniqueBasicBlockSectionNames(424      "unique-basic-block-section-names",425      cl::desc("Give unique names to every basic block section"),426      cl::init(false));427  CGBINDOPT(UniqueBasicBlockSectionNames);428 429  static cl::opt<bool> SeparateNamedSections(430      "separate-named-sections",431      cl::desc("Use separate unique sections for named sections"),432      cl::init(false));433  CGBINDOPT(SeparateNamedSections);434 435  static cl::opt<EABI> EABIVersion(436      "meabi", cl::desc("Set EABI type (default depends on triple):"),437      cl::init(EABI::Default),438      cl::values(439          clEnumValN(EABI::Default, "default", "Triple default EABI version"),440          clEnumValN(EABI::EABI4, "4", "EABI version 4"),441          clEnumValN(EABI::EABI5, "5", "EABI version 5"),442          clEnumValN(EABI::GNU, "gnu", "EABI GNU")));443  CGBINDOPT(EABIVersion);444 445  static cl::opt<DebuggerKind> DebuggerTuningOpt(446      "debugger-tune", cl::desc("Tune debug info for a particular debugger"),447      cl::init(DebuggerKind::Default),448      cl::values(449          clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),450          clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),451          clEnumValN(DebuggerKind::DBX, "dbx", "dbx"),452          clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));453  CGBINDOPT(DebuggerTuningOpt);454 455  static cl::opt<VectorLibrary> VectorLibrary(456      "vector-library", cl::Hidden, cl::desc("Vector functions library"),457      cl::init(VectorLibrary::NoLibrary),458      cl::values(459          clEnumValN(VectorLibrary::NoLibrary, "none",460                     "No vector functions library"),461          clEnumValN(VectorLibrary::Accelerate, "Accelerate",462                     "Accelerate framework"),463          clEnumValN(VectorLibrary::DarwinLibSystemM, "Darwin_libsystem_m",464                     "Darwin libsystem_m"),465          clEnumValN(VectorLibrary::LIBMVEC, "LIBMVEC",466                     "GLIBC Vector Math library"),467          clEnumValN(VectorLibrary::MASSV, "MASSV", "IBM MASS vector library"),468          clEnumValN(VectorLibrary::SVML, "SVML", "Intel SVML library"),469          clEnumValN(VectorLibrary::SLEEFGNUABI, "sleefgnuabi",470                     "SIMD Library for Evaluating Elementary Functions"),471          clEnumValN(VectorLibrary::ArmPL, "ArmPL",472                     "Arm Performance Libraries"),473          clEnumValN(VectorLibrary::AMDLIBM, "AMDLIBM",474                     "AMD vector math library")));475  CGBINDOPT(VectorLibrary);476 477  static cl::opt<bool> EnableStackSizeSection(478      "stack-size-section",479      cl::desc("Emit a section containing stack size metadata"),480      cl::init(false));481  CGBINDOPT(EnableStackSizeSection);482 483  static cl::opt<bool> EnableAddrsig(484      "addrsig", cl::desc("Emit an address-significance table"),485      cl::init(false));486  CGBINDOPT(EnableAddrsig);487 488  static cl::opt<bool> EnableCallGraphSection(489      "call-graph-section", cl::desc("Emit a call graph section"),490      cl::init(false));491  CGBINDOPT(EnableCallGraphSection);492 493  static cl::opt<bool> EmitCallSiteInfo(494      "emit-call-site-info",495      cl::desc(496          "Emit call site debug information, if debug information is enabled."),497      cl::init(false));498  CGBINDOPT(EmitCallSiteInfo);499 500  static cl::opt<bool> EnableDebugEntryValues(501      "debug-entry-values",502      cl::desc("Enable debug info for the debug entry values."),503      cl::init(false));504  CGBINDOPT(EnableDebugEntryValues);505 506  static cl::opt<bool> EnableMachineFunctionSplitter(507      "split-machine-functions",508      cl::desc("Split out cold basic blocks from machine functions based on "509               "profile information"),510      cl::init(false));511  CGBINDOPT(EnableMachineFunctionSplitter);512 513  static cl::opt<bool> EnableStaticDataPartitioning(514      "partition-static-data-sections",515      cl::desc("Partition data sections using profile information."),516      cl::init(false));517  CGBINDOPT(EnableStaticDataPartitioning);518 519  static cl::opt<bool> ForceDwarfFrameSection(520      "force-dwarf-frame-section",521      cl::desc("Always emit a debug frame section."), cl::init(false));522  CGBINDOPT(ForceDwarfFrameSection);523 524  static cl::opt<bool> XRayFunctionIndex("xray-function-index",525                                         cl::desc("Emit xray_fn_idx section"),526                                         cl::init(true));527  CGBINDOPT(XRayFunctionIndex);528 529  static cl::opt<bool> DebugStrictDwarf(530      "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false));531  CGBINDOPT(DebugStrictDwarf);532 533  static cl::opt<unsigned> AlignLoops("align-loops",534                                      cl::desc("Default alignment for loops"));535  CGBINDOPT(AlignLoops);536 537  static cl::opt<bool> JMCInstrument(538      "enable-jmc-instrument",539      cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"),540      cl::init(false));541  CGBINDOPT(JMCInstrument);542 543  static cl::opt<bool> XCOFFReadOnlyPointers(544      "mxcoff-roptr",545      cl::desc("When set to true, const objects with relocatable address "546               "values are put into the RO data section."),547      cl::init(false));548  CGBINDOPT(XCOFFReadOnlyPointers);549 550  static cl::opt<bool> DisableIntegratedAS(551      "no-integrated-as", cl::desc("Disable integrated assembler"),552      cl::init(false));553  CGBINDOPT(DisableIntegratedAS);554 555  mc::RegisterMCTargetOptionsFlags();556}557 558codegen::RegisterSaveStatsFlag::RegisterSaveStatsFlag() {559  static cl::opt<SaveStatsMode> SaveStats(560      "save-stats",561      cl::desc(562          "Save LLVM statistics to a file in the current directory"563          "(`-save-stats`/`-save-stats=cwd`) or the directory of the output"564          "file (`-save-stats=obj`). (default: cwd)"),565      cl::values(clEnumValN(SaveStatsMode::Cwd, "cwd",566                            "Save to the current working directory"),567                 clEnumValN(SaveStatsMode::Cwd, "", ""),568                 clEnumValN(SaveStatsMode::Obj, "obj",569                            "Save to the output file directory")),570      cl::init(SaveStatsMode::None), cl::ValueOptional);571  CGBINDOPT(SaveStats);572}573 574llvm::BasicBlockSection575codegen::getBBSectionsMode(llvm::TargetOptions &Options) {576  if (getBBSections() == "all")577    return BasicBlockSection::All;578  else if (getBBSections() == "none")579    return BasicBlockSection::None;580  else {581    ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =582        MemoryBuffer::getFile(getBBSections());583    if (!MBOrErr) {584      errs() << "Error loading basic block sections function list file: "585             << MBOrErr.getError().message() << "\n";586    } else {587      Options.BBSectionsFuncListBuf = std::move(*MBOrErr);588    }589    return BasicBlockSection::List;590  }591}592 593// Common utility function tightly tied to the options listed here. Initializes594// a TargetOptions object with CodeGen flags and returns it.595TargetOptions596codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {597  TargetOptions Options;598  Options.AllowFPOpFusion = getFuseFPOps();599  Options.NoInfsFPMath = getEnableNoInfsFPMath();600  Options.NoNaNsFPMath = getEnableNoNaNsFPMath();601  Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath();602  Options.NoTrappingFPMath = getEnableNoTrappingFPMath();603 604  DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();605 606  // FIXME: Should have separate input and output flags607  Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind));608 609  Options.HonorSignDependentRoundingFPMathOption =610      getEnableHonorSignDependentRoundingFPMath();611  if (getFloatABIForCalls() != FloatABI::Default)612    Options.FloatABIType = getFloatABIForCalls();613  Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();614  Options.NoZerosInBSS = getDontPlaceZerosInBSS();615  Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();616  Options.StackSymbolOrdering = getStackSymbolOrdering();617  Options.UseInitArray = !getUseCtors();618  Options.DisableIntegratedAS = getDisableIntegratedAS();619  Options.DataSections =620      getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections());621  Options.FunctionSections = getFunctionSections();622  Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();623  Options.XCOFFTracebackTable = getXCOFFTracebackTable();624  Options.BBAddrMap = getEnableBBAddrMap();625  Options.BBSections = getBBSectionsMode(Options);626  Options.UniqueSectionNames = getUniqueSectionNames();627  Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();628  Options.SeparateNamedSections = getSeparateNamedSections();629  Options.TLSSize = getTLSSize();630  Options.EmulatedTLS =631      getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS());632  Options.EnableTLSDESC =633      getExplicitEnableTLSDESC().value_or(TheTriple.hasDefaultTLSDESC());634  Options.ExceptionModel = getExceptionModel();635  Options.VecLib = getVectorLibrary();636  Options.EmitStackSizeSection = getEnableStackSizeSection();637  Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();638  Options.EnableStaticDataPartitioning = getEnableStaticDataPartitioning();639  Options.EmitAddrsig = getEnableAddrsig();640  Options.EmitCallGraphSection = getEnableCallGraphSection();641  Options.EmitCallSiteInfo = getEmitCallSiteInfo();642  Options.EnableDebugEntryValues = getEnableDebugEntryValues();643  Options.ForceDwarfFrameSection = getForceDwarfFrameSection();644  Options.XRayFunctionIndex = getXRayFunctionIndex();645  Options.DebugStrictDwarf = getDebugStrictDwarf();646  Options.LoopAlignment = getAlignLoops();647  Options.JMCInstrument = getJMCInstrument();648  Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers();649 650  Options.MCOptions = mc::InitMCTargetOptionsFromFlags();651 652  Options.ThreadModel = getThreadModel();653  Options.EABIVersion = getEABIVersion();654  Options.DebuggerTuning = getDebuggerTuningOpt();655  Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer();656  return Options;657}658 659std::string codegen::getCPUStr() {660  // If user asked for the 'native' CPU, autodetect here. If autodection fails,661  // this will set the CPU to an empty string which tells the target to662  // pick a basic default.663  if (getMCPU() == "native")664    return std::string(sys::getHostCPUName());665 666  return getMCPU();667}668 669std::string codegen::getFeaturesStr() {670  SubtargetFeatures Features;671 672  // If user asked for the 'native' CPU, we need to autodetect features.673  // This is necessary for x86 where the CPU might not support all the674  // features the autodetected CPU name lists in the target. For example,675  // not all Sandybridge processors support AVX.676  if (getMCPU() == "native")677    for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())678      Features.AddFeature(Feature, IsEnabled);679 680  for (auto const &MAttr : getMAttrs())681    Features.AddFeature(MAttr);682 683  return Features.getString();684}685 686std::vector<std::string> codegen::getFeatureList() {687  SubtargetFeatures Features;688 689  // If user asked for the 'native' CPU, we need to autodetect features.690  // This is necessary for x86 where the CPU might not support all the691  // features the autodetected CPU name lists in the target. For example,692  // not all Sandybridge processors support AVX.693  if (getMCPU() == "native")694    for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())695      Features.AddFeature(Feature, IsEnabled);696 697  for (auto const &MAttr : getMAttrs())698    Features.AddFeature(MAttr);699 700  return Features.getFeatures();701}702 703void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {704  B.addAttribute(Name, Val ? "true" : "false");705}706 707#define HANDLE_BOOL_ATTR(CL, AttrName)                                         \708  do {                                                                         \709    if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName))            \710      renderBoolStringAttr(NewAttrs, AttrName, *CL);                           \711  } while (0)712 713/// Set function attributes of function \p F based on CPU, Features, and command714/// line flags.715void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,716                                    Function &F) {717  auto &Ctx = F.getContext();718  AttributeList Attrs = F.getAttributes();719  AttrBuilder NewAttrs(Ctx);720 721  if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))722    NewAttrs.addAttribute("target-cpu", CPU);723  if (!Features.empty()) {724    // Append the command line features to any that are already on the function.725    StringRef OldFeatures =726        F.getFnAttribute("target-features").getValueAsString();727    if (OldFeatures.empty())728      NewAttrs.addAttribute("target-features", Features);729    else {730      SmallString<256> Appended(OldFeatures);731      Appended.push_back(',');732      Appended.append(Features);733      NewAttrs.addAttribute("target-features", Appended);734    }735  }736  if (FramePointerUsageView->getNumOccurrences() > 0 &&737      !F.hasFnAttribute("frame-pointer")) {738    if (getFramePointerUsage() == FramePointerKind::All)739      NewAttrs.addAttribute("frame-pointer", "all");740    else if (getFramePointerUsage() == FramePointerKind::NonLeaf)741      NewAttrs.addAttribute("frame-pointer", "non-leaf");742    else if (getFramePointerUsage() == FramePointerKind::NonLeafNoReserve)743      NewAttrs.addAttribute("frame-pointer", "non-leaf-no-reserve");744    else if (getFramePointerUsage() == FramePointerKind::Reserved)745      NewAttrs.addAttribute("frame-pointer", "reserved");746    else if (getFramePointerUsage() == FramePointerKind::None)747      NewAttrs.addAttribute("frame-pointer", "none");748  }749  if (DisableTailCallsView->getNumOccurrences() > 0)750    NewAttrs.addAttribute("disable-tail-calls",751                          toStringRef(getDisableTailCalls()));752  if (getStackRealign())753    NewAttrs.addAttribute("stackrealign");754 755  HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");756  HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");757  HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");758 759  if (DenormalFPMathView->getNumOccurrences() > 0 &&760      !F.hasFnAttribute("denormal-fp-math")) {761    DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();762 763    // FIXME: Command line flag should expose separate input/output modes.764    NewAttrs.addAttribute("denormal-fp-math",765                          DenormalMode(DenormKind, DenormKind).str());766  }767 768  if (DenormalFP32MathView->getNumOccurrences() > 0 &&769      !F.hasFnAttribute("denormal-fp-math-f32")) {770    // FIXME: Command line flag should expose separate input/output modes.771    DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math();772 773    NewAttrs.addAttribute(774      "denormal-fp-math-f32",775      DenormalMode(DenormKind, DenormKind).str());776  }777 778  if (TrapFuncNameView->getNumOccurrences() > 0)779    for (auto &B : F)780      for (auto &I : B)781        if (auto *Call = dyn_cast<CallInst>(&I))782          if (const auto *F = Call->getCalledFunction())783            if (F->getIntrinsicID() == Intrinsic::debugtrap ||784                F->getIntrinsicID() == Intrinsic::trap)785              Call->addFnAttr(786                  Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));787 788  // Let NewAttrs override Attrs.789  F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs));790}791 792/// Set function attributes of functions in Module M based on CPU,793/// Features, and command line flags.794void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,795                                    Module &M) {796  for (Function &F : M)797    setFunctionAttributes(CPU, Features, F);798}799 800Expected<std::unique_ptr<TargetMachine>>801codegen::createTargetMachineForTriple(StringRef TargetTriple,802                                      CodeGenOptLevel OptLevel) {803  Triple TheTriple(TargetTriple);804  std::string Error;805  const auto *TheTarget =806      TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);807  if (!TheTarget)808    return createStringError(inconvertibleErrorCode(), Error);809  auto *Target = TheTarget->createTargetMachine(810      TheTriple, codegen::getCPUStr(), codegen::getFeaturesStr(),811      codegen::InitTargetOptionsFromCodeGenFlags(TheTriple),812      codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(),813      OptLevel);814  if (!Target)815    return createStringError(inconvertibleErrorCode(),816                             Twine("could not allocate target machine for ") +817                                 TargetTriple);818  return std::unique_ptr<TargetMachine>(Target);819}820 821void codegen::MaybeEnableStatistics() {822  if (getSaveStats() == SaveStatsMode::None)823    return;824 825  llvm::EnableStatistics(false);826}827 828int codegen::MaybeSaveStatistics(StringRef OutputFilename, StringRef ToolName) {829  auto SaveStatsValue = getSaveStats();830  if (SaveStatsValue == codegen::SaveStatsMode::None)831    return 0;832 833  SmallString<128> StatsFilename;834  if (SaveStatsValue == codegen::SaveStatsMode::Obj) {835    StatsFilename = OutputFilename;836    llvm::sys::path::remove_filename(StatsFilename);837  } else {838    assert(SaveStatsValue == codegen::SaveStatsMode::Cwd &&839           "Should have been a valid --save-stats value");840  }841 842  auto BaseName = llvm::sys::path::filename(OutputFilename);843  llvm::sys::path::append(StatsFilename, BaseName);844  llvm::sys::path::replace_extension(StatsFilename, "stats");845 846  auto FileFlags = llvm::sys::fs::OF_TextWithCRLF;847  std::error_code EC;848  auto StatsOS =849      std::make_unique<llvm::raw_fd_ostream>(StatsFilename, EC, FileFlags);850  if (EC) {851    WithColor::error(errs(), ToolName)852        << "Unable to open statistics file: " << EC.message() << "\n";853    return 1;854  }855 856  llvm::PrintStatisticsJSON(*StatsOS);857  return 0;858}859