xref: /llvm-project/llvm/lib/CodeGen/CommandFlags.cpp (revision a3319371970b599ef65ef1567c440fbdc3a330f4)
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_EXP(bool, DataSections)
89 CGOPT_EXP(bool, FunctionSections)
90 CGOPT(bool, IgnoreXCOFFVisibility)
91 CGOPT(bool, XCOFFTracebackTable)
92 CGOPT(bool, EnableBBAddrMap)
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> DataSections(
365       "data-sections", cl::desc("Emit data into separate sections"),
366       cl::init(false));
367   CGBINDOPT(DataSections);
368 
369   static cl::opt<bool> FunctionSections(
370       "function-sections", cl::desc("Emit functions into separate sections"),
371       cl::init(false));
372   CGBINDOPT(FunctionSections);
373 
374   static cl::opt<bool> IgnoreXCOFFVisibility(
375       "ignore-xcoff-visibility",
376       cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
377                "all symbols 'unspecified' visibility in XCOFF object file"),
378       cl::init(false));
379   CGBINDOPT(IgnoreXCOFFVisibility);
380 
381   static cl::opt<bool> XCOFFTracebackTable(
382       "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
383       cl::init(true));
384   CGBINDOPT(XCOFFTracebackTable);
385 
386   static cl::opt<bool> EnableBBAddrMap(
387       "basic-block-address-map",
388       cl::desc("Emit the basic block address map section"), cl::init(false));
389   CGBINDOPT(EnableBBAddrMap);
390 
391   static cl::opt<std::string> BBSections(
392       "basic-block-sections",
393       cl::desc("Emit basic blocks into separate sections"),
394       cl::value_desc("all | <function list (file)> | labels | none"),
395       cl::init("none"));
396   CGBINDOPT(BBSections);
397 
398   static cl::opt<unsigned> TLSSize(
399       "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
400   CGBINDOPT(TLSSize);
401 
402   static cl::opt<bool> EmulatedTLS(
403       "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
404   CGBINDOPT(EmulatedTLS);
405 
406   static cl::opt<bool> EnableTLSDESC(
407       "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"),
408       cl::init(false));
409   CGBINDOPT(EnableTLSDESC);
410 
411   static cl::opt<bool> UniqueSectionNames(
412       "unique-section-names", cl::desc("Give unique names to every section"),
413       cl::init(true));
414   CGBINDOPT(UniqueSectionNames);
415 
416   static cl::opt<bool> UniqueBasicBlockSectionNames(
417       "unique-basic-block-section-names",
418       cl::desc("Give unique names to every basic block section"),
419       cl::init(false));
420   CGBINDOPT(UniqueBasicBlockSectionNames);
421 
422   static cl::opt<EABI> EABIVersion(
423       "meabi", cl::desc("Set EABI type (default depends on triple):"),
424       cl::init(EABI::Default),
425       cl::values(
426           clEnumValN(EABI::Default, "default", "Triple default EABI version"),
427           clEnumValN(EABI::EABI4, "4", "EABI version 4"),
428           clEnumValN(EABI::EABI5, "5", "EABI version 5"),
429           clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
430   CGBINDOPT(EABIVersion);
431 
432   static cl::opt<DebuggerKind> DebuggerTuningOpt(
433       "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
434       cl::init(DebuggerKind::Default),
435       cl::values(
436           clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
437           clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
438           clEnumValN(DebuggerKind::DBX, "dbx", "dbx"),
439           clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
440   CGBINDOPT(DebuggerTuningOpt);
441 
442   static cl::opt<bool> EnableStackSizeSection(
443       "stack-size-section",
444       cl::desc("Emit a section containing stack size metadata"),
445       cl::init(false));
446   CGBINDOPT(EnableStackSizeSection);
447 
448   static cl::opt<bool> EnableAddrsig(
449       "addrsig", cl::desc("Emit an address-significance table"),
450       cl::init(false));
451   CGBINDOPT(EnableAddrsig);
452 
453   static cl::opt<bool> EmitCallSiteInfo(
454       "emit-call-site-info",
455       cl::desc(
456           "Emit call site debug information, if debug information is enabled."),
457       cl::init(false));
458   CGBINDOPT(EmitCallSiteInfo);
459 
460   static cl::opt<bool> EnableDebugEntryValues(
461       "debug-entry-values",
462       cl::desc("Enable debug info for the debug entry values."),
463       cl::init(false));
464   CGBINDOPT(EnableDebugEntryValues);
465 
466   static cl::opt<bool> EnableMachineFunctionSplitter(
467       "split-machine-functions",
468       cl::desc("Split out cold basic blocks from machine functions based on "
469                "profile information"),
470       cl::init(false));
471   CGBINDOPT(EnableMachineFunctionSplitter);
472 
473   static cl::opt<bool> ForceDwarfFrameSection(
474       "force-dwarf-frame-section",
475       cl::desc("Always emit a debug frame section."), cl::init(false));
476   CGBINDOPT(ForceDwarfFrameSection);
477 
478   static cl::opt<bool> XRayFunctionIndex("xray-function-index",
479                                          cl::desc("Emit xray_fn_idx section"),
480                                          cl::init(true));
481   CGBINDOPT(XRayFunctionIndex);
482 
483   static cl::opt<bool> DebugStrictDwarf(
484       "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false));
485   CGBINDOPT(DebugStrictDwarf);
486 
487   static cl::opt<unsigned> AlignLoops("align-loops",
488                                       cl::desc("Default alignment for loops"));
489   CGBINDOPT(AlignLoops);
490 
491   static cl::opt<bool> JMCInstrument(
492       "enable-jmc-instrument",
493       cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"),
494       cl::init(false));
495   CGBINDOPT(JMCInstrument);
496 
497   static cl::opt<bool> XCOFFReadOnlyPointers(
498       "mxcoff-roptr",
499       cl::desc("When set to true, const objects with relocatable address "
500                "values are put into the RO data section."),
501       cl::init(false));
502   CGBINDOPT(XCOFFReadOnlyPointers);
503 
504   static cl::opt<bool> DisableIntegratedAS(
505       "no-integrated-as", cl::desc("Disable integrated assembler"),
506       cl::init(false));
507   CGBINDOPT(DisableIntegratedAS);
508 
509 #undef CGBINDOPT
510 
511   mc::RegisterMCTargetOptionsFlags();
512 }
513 
514 llvm::BasicBlockSection
515 codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
516   if (getBBSections() == "all")
517     return BasicBlockSection::All;
518   else if (getBBSections() == "labels")
519     return BasicBlockSection::Labels;
520   else if (getBBSections() == "none")
521     return BasicBlockSection::None;
522   else {
523     ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
524         MemoryBuffer::getFile(getBBSections());
525     if (!MBOrErr) {
526       errs() << "Error loading basic block sections function list file: "
527              << MBOrErr.getError().message() << "\n";
528     } else {
529       Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
530     }
531     return BasicBlockSection::List;
532   }
533 }
534 
535 // Common utility function tightly tied to the options listed here. Initializes
536 // a TargetOptions object with CodeGen flags and returns it.
537 TargetOptions
538 codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
539   TargetOptions Options;
540   Options.AllowFPOpFusion = getFuseFPOps();
541   Options.UnsafeFPMath = getEnableUnsafeFPMath();
542   Options.NoInfsFPMath = getEnableNoInfsFPMath();
543   Options.NoNaNsFPMath = getEnableNoNaNsFPMath();
544   Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath();
545   Options.ApproxFuncFPMath = getEnableApproxFuncFPMath();
546   Options.NoTrappingFPMath = getEnableNoTrappingFPMath();
547 
548   DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
549 
550   // FIXME: Should have separate input and output flags
551   Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind));
552 
553   Options.HonorSignDependentRoundingFPMathOption =
554       getEnableHonorSignDependentRoundingFPMath();
555   if (getFloatABIForCalls() != FloatABI::Default)
556     Options.FloatABIType = getFloatABIForCalls();
557   Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();
558   Options.NoZerosInBSS = getDontPlaceZerosInBSS();
559   Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();
560   Options.StackSymbolOrdering = getStackSymbolOrdering();
561   Options.UseInitArray = !getUseCtors();
562   Options.DisableIntegratedAS = getDisableIntegratedAS();
563   Options.DataSections =
564       getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections());
565   Options.FunctionSections = getFunctionSections();
566   Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
567   Options.XCOFFTracebackTable = getXCOFFTracebackTable();
568   Options.BBAddrMap = getEnableBBAddrMap();
569   Options.BBSections = getBBSectionsMode(Options);
570   Options.UniqueSectionNames = getUniqueSectionNames();
571   Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
572   Options.TLSSize = getTLSSize();
573   Options.EmulatedTLS =
574       getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS());
575   Options.EnableTLSDESC =
576       getExplicitEnableTLSDESC().value_or(TheTriple.hasDefaultTLSDESC());
577   Options.ExceptionModel = getExceptionModel();
578   Options.EmitStackSizeSection = getEnableStackSizeSection();
579   Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
580   Options.EmitAddrsig = getEnableAddrsig();
581   Options.EmitCallSiteInfo = getEmitCallSiteInfo();
582   Options.EnableDebugEntryValues = getEnableDebugEntryValues();
583   Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
584   Options.XRayFunctionIndex = getXRayFunctionIndex();
585   Options.DebugStrictDwarf = getDebugStrictDwarf();
586   Options.LoopAlignment = getAlignLoops();
587   Options.JMCInstrument = getJMCInstrument();
588   Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers();
589 
590   Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
591 
592   Options.ThreadModel = getThreadModel();
593   Options.EABIVersion = getEABIVersion();
594   Options.DebuggerTuning = getDebuggerTuningOpt();
595   Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer();
596   return Options;
597 }
598 
599 std::string codegen::getCPUStr() {
600   // If user asked for the 'native' CPU, autodetect here. If autodection fails,
601   // this will set the CPU to an empty string which tells the target to
602   // pick a basic default.
603   if (getMCPU() == "native")
604     return std::string(sys::getHostCPUName());
605 
606   return getMCPU();
607 }
608 
609 std::string codegen::getFeaturesStr() {
610   SubtargetFeatures Features;
611 
612   // If user asked for the 'native' CPU, we need to autodetect features.
613   // This is necessary for x86 where the CPU might not support all the
614   // features the autodetected CPU name lists in the target. For example,
615   // not all Sandybridge processors support AVX.
616   if (getMCPU() == "native") {
617     StringMap<bool> HostFeatures;
618     if (sys::getHostCPUFeatures(HostFeatures))
619       for (const auto &[Feature, IsEnabled] : HostFeatures)
620         Features.AddFeature(Feature, IsEnabled);
621   }
622 
623   for (auto const &MAttr : getMAttrs())
624     Features.AddFeature(MAttr);
625 
626   return Features.getString();
627 }
628 
629 std::vector<std::string> codegen::getFeatureList() {
630   SubtargetFeatures Features;
631 
632   // If user asked for the 'native' CPU, we need to autodetect features.
633   // This is necessary for x86 where the CPU might not support all the
634   // features the autodetected CPU name lists in the target. For example,
635   // not all Sandybridge processors support AVX.
636   if (getMCPU() == "native") {
637     StringMap<bool> HostFeatures;
638     if (sys::getHostCPUFeatures(HostFeatures))
639       for (const auto &[Feature, IsEnabled] : HostFeatures)
640         Features.AddFeature(Feature, IsEnabled);
641   }
642 
643   for (auto const &MAttr : getMAttrs())
644     Features.AddFeature(MAttr);
645 
646   return Features.getFeatures();
647 }
648 
649 void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
650   B.addAttribute(Name, Val ? "true" : "false");
651 }
652 
653 #define HANDLE_BOOL_ATTR(CL, AttrName)                                         \
654   do {                                                                         \
655     if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName))            \
656       renderBoolStringAttr(NewAttrs, AttrName, *CL);                           \
657   } while (0)
658 
659 /// Set function attributes of function \p F based on CPU, Features, and command
660 /// line flags.
661 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
662                                     Function &F) {
663   auto &Ctx = F.getContext();
664   AttributeList Attrs = F.getAttributes();
665   AttrBuilder NewAttrs(Ctx);
666 
667   if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
668     NewAttrs.addAttribute("target-cpu", CPU);
669   if (!Features.empty()) {
670     // Append the command line features to any that are already on the function.
671     StringRef OldFeatures =
672         F.getFnAttribute("target-features").getValueAsString();
673     if (OldFeatures.empty())
674       NewAttrs.addAttribute("target-features", Features);
675     else {
676       SmallString<256> Appended(OldFeatures);
677       Appended.push_back(',');
678       Appended.append(Features);
679       NewAttrs.addAttribute("target-features", Appended);
680     }
681   }
682   if (FramePointerUsageView->getNumOccurrences() > 0 &&
683       !F.hasFnAttribute("frame-pointer")) {
684     if (getFramePointerUsage() == FramePointerKind::All)
685       NewAttrs.addAttribute("frame-pointer", "all");
686     else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
687       NewAttrs.addAttribute("frame-pointer", "non-leaf");
688     else if (getFramePointerUsage() == FramePointerKind::None)
689       NewAttrs.addAttribute("frame-pointer", "none");
690   }
691   if (DisableTailCallsView->getNumOccurrences() > 0)
692     NewAttrs.addAttribute("disable-tail-calls",
693                           toStringRef(getDisableTailCalls()));
694   if (getStackRealign())
695     NewAttrs.addAttribute("stackrealign");
696 
697   HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math");
698   HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");
699   HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");
700   HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");
701   HANDLE_BOOL_ATTR(EnableApproxFuncFPMathView, "approx-func-fp-math");
702 
703   if (DenormalFPMathView->getNumOccurrences() > 0 &&
704       !F.hasFnAttribute("denormal-fp-math")) {
705     DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
706 
707     // FIXME: Command line flag should expose separate input/output modes.
708     NewAttrs.addAttribute("denormal-fp-math",
709                           DenormalMode(DenormKind, DenormKind).str());
710   }
711 
712   if (DenormalFP32MathView->getNumOccurrences() > 0 &&
713       !F.hasFnAttribute("denormal-fp-math-f32")) {
714     // FIXME: Command line flag should expose separate input/output modes.
715     DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math();
716 
717     NewAttrs.addAttribute(
718       "denormal-fp-math-f32",
719       DenormalMode(DenormKind, DenormKind).str());
720   }
721 
722   if (TrapFuncNameView->getNumOccurrences() > 0)
723     for (auto &B : F)
724       for (auto &I : B)
725         if (auto *Call = dyn_cast<CallInst>(&I))
726           if (const auto *F = Call->getCalledFunction())
727             if (F->getIntrinsicID() == Intrinsic::debugtrap ||
728                 F->getIntrinsicID() == Intrinsic::trap)
729               Call->addFnAttr(
730                   Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));
731 
732   // Let NewAttrs override Attrs.
733   F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs));
734 }
735 
736 /// Set function attributes of functions in Module M based on CPU,
737 /// Features, and command line flags.
738 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
739                                     Module &M) {
740   for (Function &F : M)
741     setFunctionAttributes(CPU, Features, F);
742 }
743 
744 Expected<std::unique_ptr<TargetMachine>>
745 codegen::createTargetMachineForTriple(StringRef TargetTriple,
746                                       CodeGenOptLevel OptLevel) {
747   Triple TheTriple(TargetTriple);
748   std::string Error;
749   const auto *TheTarget =
750       TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
751   if (!TheTarget)
752     return createStringError(inconvertibleErrorCode(), Error);
753   auto *Target = TheTarget->createTargetMachine(
754       TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(),
755       codegen::InitTargetOptionsFromCodeGenFlags(TheTriple),
756       codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(),
757       OptLevel);
758   if (!Target)
759     return createStringError(inconvertibleErrorCode(),
760                              Twine("could not allocate target machine for ") +
761                                  TargetTriple);
762   return std::unique_ptr<TargetMachine>(Target);
763 }
764