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