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