xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/CommandFlags.cpp (revision 6b96bb739548a8b8c2b13bd46234f70a29be12fb)
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(bool, DontPlaceZerosInBSS)
69  CGOPT(bool, EnableGuaranteedTailCallOpt)
70  CGOPT(bool, DisableTailCalls)
71  CGOPT(bool, StackSymbolOrdering)
72  CGOPT(bool, StackRealign)
73  CGOPT(std::string, TrapFuncName)
74  CGOPT(bool, UseCtors)
75  CGOPT(bool, RelaxELFRelocations)
76  CGOPT_EXP(bool, DataSections)
77  CGOPT_EXP(bool, FunctionSections)
78  CGOPT(bool, IgnoreXCOFFVisibility)
79  CGOPT(bool, XCOFFTracebackTable)
80  CGOPT(std::string, BBSections)
81  CGOPT(unsigned, TLSSize)
82  CGOPT(bool, EmulatedTLS)
83  CGOPT(bool, UniqueSectionNames)
84  CGOPT(bool, UniqueBasicBlockSectionNames)
85  CGOPT(EABI, EABIVersion)
86  CGOPT(DebuggerKind, DebuggerTuningOpt)
87  CGOPT(bool, EnableStackSizeSection)
88  CGOPT(bool, EnableAddrsig)
89  CGOPT(bool, EmitCallSiteInfo)
90  CGOPT(bool, EnableMachineFunctionSplitter)
91  CGOPT(bool, EnableDebugEntryValues)
92  CGOPT(bool, PseudoProbeForProfiling)
93  CGOPT(bool, ValueTrackingVariableLocations)
94  CGOPT(bool, ForceDwarfFrameSection)
95  CGOPT(bool, XRayOmitFunctionIndex)
96  CGOPT(bool, DebugStrictDwarf)
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<bool> DontPlaceZerosInBSS(
281        "nozero-initialized-in-bss",
282        cl::desc("Don't place zero-initialized symbols into bss section"),
283        cl::init(false));
284    CGBINDOPT(DontPlaceZerosInBSS);
285  
286    static cl::opt<bool> EnableAIXExtendedAltivecABI(
287        "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),
288        cl::init(false));
289    CGBINDOPT(EnableAIXExtendedAltivecABI);
290  
291    static cl::opt<bool> EnableGuaranteedTailCallOpt(
292        "tailcallopt",
293        cl::desc(
294            "Turn fastcc calls into tail calls by (potentially) changing ABI."),
295        cl::init(false));
296    CGBINDOPT(EnableGuaranteedTailCallOpt);
297  
298    static cl::opt<bool> DisableTailCalls(
299        "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false));
300    CGBINDOPT(DisableTailCalls);
301  
302    static cl::opt<bool> StackSymbolOrdering(
303        "stack-symbol-ordering", cl::desc("Order local stack symbols."),
304        cl::init(true));
305    CGBINDOPT(StackSymbolOrdering);
306  
307    static cl::opt<bool> StackRealign(
308        "stackrealign",
309        cl::desc("Force align the stack to the minimum alignment"),
310        cl::init(false));
311    CGBINDOPT(StackRealign);
312  
313    static cl::opt<std::string> TrapFuncName(
314        "trap-func", cl::Hidden,
315        cl::desc("Emit a call to trap function rather than a trap instruction"),
316        cl::init(""));
317    CGBINDOPT(TrapFuncName);
318  
319    static cl::opt<bool> UseCtors("use-ctors",
320                                  cl::desc("Use .ctors instead of .init_array."),
321                                  cl::init(false));
322    CGBINDOPT(UseCtors);
323  
324    static cl::opt<bool> RelaxELFRelocations(
325        "relax-elf-relocations",
326        cl::desc(
327            "Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
328        cl::init(false));
329    CGBINDOPT(RelaxELFRelocations);
330  
331    static cl::opt<bool> DataSections(
332        "data-sections", cl::desc("Emit data into separate sections"),
333        cl::init(false));
334    CGBINDOPT(DataSections);
335  
336    static cl::opt<bool> FunctionSections(
337        "function-sections", cl::desc("Emit functions into separate sections"),
338        cl::init(false));
339    CGBINDOPT(FunctionSections);
340  
341    static cl::opt<bool> IgnoreXCOFFVisibility(
342        "ignore-xcoff-visibility",
343        cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
344                 "all symbols 'unspecified' visibility in XCOFF object file"),
345        cl::init(false));
346    CGBINDOPT(IgnoreXCOFFVisibility);
347  
348    static cl::opt<bool> XCOFFTracebackTable(
349        "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
350        cl::init(true));
351    CGBINDOPT(XCOFFTracebackTable);
352  
353    static cl::opt<std::string> BBSections(
354        "basic-block-sections",
355        cl::desc("Emit basic blocks into separate sections"),
356        cl::value_desc("all | <function list (file)> | labels | none"),
357        cl::init("none"));
358    CGBINDOPT(BBSections);
359  
360    static cl::opt<unsigned> TLSSize(
361        "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
362    CGBINDOPT(TLSSize);
363  
364    static cl::opt<bool> EmulatedTLS(
365        "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
366    CGBINDOPT(EmulatedTLS);
367  
368    static cl::opt<bool> UniqueSectionNames(
369        "unique-section-names", cl::desc("Give unique names to every section"),
370        cl::init(true));
371    CGBINDOPT(UniqueSectionNames);
372  
373    static cl::opt<bool> UniqueBasicBlockSectionNames(
374        "unique-basic-block-section-names",
375        cl::desc("Give unique names to every basic block section"),
376        cl::init(false));
377    CGBINDOPT(UniqueBasicBlockSectionNames);
378  
379    static cl::opt<EABI> EABIVersion(
380        "meabi", cl::desc("Set EABI type (default depends on triple):"),
381        cl::init(EABI::Default),
382        cl::values(
383            clEnumValN(EABI::Default, "default", "Triple default EABI version"),
384            clEnumValN(EABI::EABI4, "4", "EABI version 4"),
385            clEnumValN(EABI::EABI5, "5", "EABI version 5"),
386            clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
387    CGBINDOPT(EABIVersion);
388  
389    static cl::opt<DebuggerKind> DebuggerTuningOpt(
390        "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
391        cl::init(DebuggerKind::Default),
392        cl::values(
393            clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
394            clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
395            clEnumValN(DebuggerKind::DBX, "dbx", "dbx"),
396            clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
397    CGBINDOPT(DebuggerTuningOpt);
398  
399    static cl::opt<bool> EnableStackSizeSection(
400        "stack-size-section",
401        cl::desc("Emit a section containing stack size metadata"),
402        cl::init(false));
403    CGBINDOPT(EnableStackSizeSection);
404  
405    static cl::opt<bool> EnableAddrsig(
406        "addrsig", cl::desc("Emit an address-significance table"),
407        cl::init(false));
408    CGBINDOPT(EnableAddrsig);
409  
410    static cl::opt<bool> EmitCallSiteInfo(
411        "emit-call-site-info",
412        cl::desc(
413            "Emit call site debug information, if debug information is enabled."),
414        cl::init(false));
415    CGBINDOPT(EmitCallSiteInfo);
416  
417    static cl::opt<bool> EnableDebugEntryValues(
418        "debug-entry-values",
419        cl::desc("Enable debug info for the debug entry values."),
420        cl::init(false));
421    CGBINDOPT(EnableDebugEntryValues);
422  
423    static cl::opt<bool> PseudoProbeForProfiling(
424        "pseudo-probe-for-profiling", cl::desc("Emit pseudo probes for AutoFDO"),
425        cl::init(false));
426    CGBINDOPT(PseudoProbeForProfiling);
427  
428    static cl::opt<bool> ValueTrackingVariableLocations(
429        "experimental-debug-variable-locations",
430        cl::desc("Use experimental new value-tracking variable locations"),
431        cl::init(false));
432    CGBINDOPT(ValueTrackingVariableLocations);
433  
434    static cl::opt<bool> EnableMachineFunctionSplitter(
435        "split-machine-functions",
436        cl::desc("Split out cold basic blocks from machine functions based on "
437                 "profile information"),
438        cl::init(false));
439    CGBINDOPT(EnableMachineFunctionSplitter);
440  
441    static cl::opt<bool> ForceDwarfFrameSection(
442        "force-dwarf-frame-section",
443        cl::desc("Always emit a debug frame section."), cl::init(false));
444    CGBINDOPT(ForceDwarfFrameSection);
445  
446    static cl::opt<bool> XRayOmitFunctionIndex(
447        "no-xray-index", cl::desc("Don't emit xray_fn_idx section"),
448        cl::init(false));
449    CGBINDOPT(XRayOmitFunctionIndex);
450  
451    static cl::opt<bool> DebugStrictDwarf(
452        "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false));
453    CGBINDOPT(DebugStrictDwarf);
454  
455  #undef CGBINDOPT
456  
457    mc::RegisterMCTargetOptionsFlags();
458  }
459  
460  llvm::BasicBlockSection
461  codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
462    if (getBBSections() == "all")
463      return BasicBlockSection::All;
464    else if (getBBSections() == "labels")
465      return BasicBlockSection::Labels;
466    else if (getBBSections() == "none")
467      return BasicBlockSection::None;
468    else {
469      ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
470          MemoryBuffer::getFile(getBBSections());
471      if (!MBOrErr) {
472        errs() << "Error loading basic block sections function list file: "
473               << MBOrErr.getError().message() << "\n";
474      } else {
475        Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
476      }
477      return BasicBlockSection::List;
478    }
479  }
480  
481  // Common utility function tightly tied to the options listed here. Initializes
482  // a TargetOptions object with CodeGen flags and returns it.
483  TargetOptions
484  codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
485    TargetOptions Options;
486    Options.AllowFPOpFusion = getFuseFPOps();
487    Options.UnsafeFPMath = getEnableUnsafeFPMath();
488    Options.NoInfsFPMath = getEnableNoInfsFPMath();
489    Options.NoNaNsFPMath = getEnableNoNaNsFPMath();
490    Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath();
491    Options.NoTrappingFPMath = getEnableNoTrappingFPMath();
492  
493    DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
494  
495    // FIXME: Should have separate input and output flags
496    Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind));
497  
498    Options.HonorSignDependentRoundingFPMathOption =
499        getEnableHonorSignDependentRoundingFPMath();
500    if (getFloatABIForCalls() != FloatABI::Default)
501      Options.FloatABIType = getFloatABIForCalls();
502    Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();
503    Options.NoZerosInBSS = getDontPlaceZerosInBSS();
504    Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();
505    Options.StackSymbolOrdering = getStackSymbolOrdering();
506    Options.UseInitArray = !getUseCtors();
507    Options.RelaxELFRelocations = getRelaxELFRelocations();
508    Options.DataSections =
509        getExplicitDataSections().getValueOr(TheTriple.hasDefaultDataSections());
510    Options.FunctionSections = getFunctionSections();
511    Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
512    Options.XCOFFTracebackTable = getXCOFFTracebackTable();
513    Options.BBSections = getBBSectionsMode(Options);
514    Options.UniqueSectionNames = getUniqueSectionNames();
515    Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
516    Options.TLSSize = getTLSSize();
517    Options.EmulatedTLS = getEmulatedTLS();
518    Options.ExplicitEmulatedTLS = EmulatedTLSView->getNumOccurrences() > 0;
519    Options.ExceptionModel = getExceptionModel();
520    Options.EmitStackSizeSection = getEnableStackSizeSection();
521    Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
522    Options.EmitAddrsig = getEnableAddrsig();
523    Options.EmitCallSiteInfo = getEmitCallSiteInfo();
524    Options.EnableDebugEntryValues = getEnableDebugEntryValues();
525    Options.PseudoProbeForProfiling = getPseudoProbeForProfiling();
526    Options.ValueTrackingVariableLocations = getValueTrackingVariableLocations();
527    Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
528    Options.XRayOmitFunctionIndex = getXRayOmitFunctionIndex();
529    Options.DebugStrictDwarf = getDebugStrictDwarf();
530  
531    Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
532  
533    Options.ThreadModel = getThreadModel();
534    Options.EABIVersion = getEABIVersion();
535    Options.DebuggerTuning = getDebuggerTuningOpt();
536  
537    return Options;
538  }
539  
540  std::string codegen::getCPUStr() {
541    // If user asked for the 'native' CPU, autodetect here. If autodection fails,
542    // this will set the CPU to an empty string which tells the target to
543    // pick a basic default.
544    if (getMCPU() == "native")
545      return std::string(sys::getHostCPUName());
546  
547    return getMCPU();
548  }
549  
550  std::string codegen::getFeaturesStr() {
551    SubtargetFeatures Features;
552  
553    // If user asked for the 'native' CPU, we need to autodetect features.
554    // This is necessary for x86 where the CPU might not support all the
555    // features the autodetected CPU name lists in the target. For example,
556    // not all Sandybridge processors support AVX.
557    if (getMCPU() == "native") {
558      StringMap<bool> HostFeatures;
559      if (sys::getHostCPUFeatures(HostFeatures))
560        for (auto &F : HostFeatures)
561          Features.AddFeature(F.first(), F.second);
562    }
563  
564    for (auto const &MAttr : getMAttrs())
565      Features.AddFeature(MAttr);
566  
567    return Features.getString();
568  }
569  
570  std::vector<std::string> codegen::getFeatureList() {
571    SubtargetFeatures Features;
572  
573    // If user asked for the 'native' CPU, we need to autodetect features.
574    // This is necessary for x86 where the CPU might not support all the
575    // features the autodetected CPU name lists in the target. For example,
576    // not all Sandybridge processors support AVX.
577    if (getMCPU() == "native") {
578      StringMap<bool> HostFeatures;
579      if (sys::getHostCPUFeatures(HostFeatures))
580        for (auto &F : HostFeatures)
581          Features.AddFeature(F.first(), F.second);
582    }
583  
584    for (auto const &MAttr : getMAttrs())
585      Features.AddFeature(MAttr);
586  
587    return Features.getFeatures();
588  }
589  
590  void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
591    B.addAttribute(Name, Val ? "true" : "false");
592  }
593  
594  #define HANDLE_BOOL_ATTR(CL, AttrName)                                         \
595    do {                                                                         \
596      if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName))            \
597        renderBoolStringAttr(NewAttrs, AttrName, *CL);                           \
598    } while (0)
599  
600  /// Set function attributes of function \p F based on CPU, Features, and command
601  /// line flags.
602  void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
603                                      Function &F) {
604    auto &Ctx = F.getContext();
605    AttributeList Attrs = F.getAttributes();
606    AttrBuilder NewAttrs;
607  
608    if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
609      NewAttrs.addAttribute("target-cpu", CPU);
610    if (!Features.empty()) {
611      // Append the command line features to any that are already on the function.
612      StringRef OldFeatures =
613          F.getFnAttribute("target-features").getValueAsString();
614      if (OldFeatures.empty())
615        NewAttrs.addAttribute("target-features", Features);
616      else {
617        SmallString<256> Appended(OldFeatures);
618        Appended.push_back(',');
619        Appended.append(Features);
620        NewAttrs.addAttribute("target-features", Appended);
621      }
622    }
623    if (FramePointerUsageView->getNumOccurrences() > 0 &&
624        !F.hasFnAttribute("frame-pointer")) {
625      if (getFramePointerUsage() == FramePointerKind::All)
626        NewAttrs.addAttribute("frame-pointer", "all");
627      else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
628        NewAttrs.addAttribute("frame-pointer", "non-leaf");
629      else if (getFramePointerUsage() == FramePointerKind::None)
630        NewAttrs.addAttribute("frame-pointer", "none");
631    }
632    if (DisableTailCallsView->getNumOccurrences() > 0)
633      NewAttrs.addAttribute("disable-tail-calls",
634                            toStringRef(getDisableTailCalls()));
635    if (getStackRealign())
636      NewAttrs.addAttribute("stackrealign");
637  
638    HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math");
639    HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");
640    HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");
641    HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");
642  
643    if (DenormalFPMathView->getNumOccurrences() > 0 &&
644        !F.hasFnAttribute("denormal-fp-math")) {
645      DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
646  
647      // FIXME: Command line flag should expose separate input/output modes.
648      NewAttrs.addAttribute("denormal-fp-math",
649                            DenormalMode(DenormKind, DenormKind).str());
650    }
651  
652    if (DenormalFP32MathView->getNumOccurrences() > 0 &&
653        !F.hasFnAttribute("denormal-fp-math-f32")) {
654      // FIXME: Command line flag should expose separate input/output modes.
655      DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math();
656  
657      NewAttrs.addAttribute(
658        "denormal-fp-math-f32",
659        DenormalMode(DenormKind, DenormKind).str());
660    }
661  
662    if (TrapFuncNameView->getNumOccurrences() > 0)
663      for (auto &B : F)
664        for (auto &I : B)
665          if (auto *Call = dyn_cast<CallInst>(&I))
666            if (const auto *F = Call->getCalledFunction())
667              if (F->getIntrinsicID() == Intrinsic::debugtrap ||
668                  F->getIntrinsicID() == Intrinsic::trap)
669                Call->addAttribute(
670                    AttributeList::FunctionIndex,
671                    Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));
672  
673    // Let NewAttrs override Attrs.
674    F.setAttributes(
675        Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
676  }
677  
678  /// Set function attributes of functions in Module M based on CPU,
679  /// Features, and command line flags.
680  void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
681                                      Module &M) {
682    for (Function &F : M)
683      setFunctionAttributes(CPU, Features, F);
684  }
685