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