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