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