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