xref: /llvm-project/llvm/lib/CodeGen/CommandFlags.cpp (revision e63ea9d6f7b1d15f4819e6af8ee9452046e1548c)
1 //===-- CommandFlags.cpp - Command Line Flags Interface ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains codegen-specific flags that are shared between different
10 // command line tools. The tools "llc" and "opt" both use this file to prevent
11 // flag duplication.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/CodeGen/CommandFlags.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/Intrinsics.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/MC/MCTargetOptionsCommandFlags.h"
21 #include "llvm/MC/TargetRegistry.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/MemoryBuffer.h"
24 #include "llvm/Target/TargetMachine.h"
25 #include "llvm/TargetParser/Host.h"
26 #include "llvm/TargetParser/SubtargetFeature.h"
27 #include "llvm/TargetParser/Triple.h"
28 #include <optional>
29 
30 using namespace llvm;
31 
32 #define CGOPT(TY, NAME)                                                        \
33   static cl::opt<TY> *NAME##View;                                              \
34   TY codegen::get##NAME() {                                                    \
35     assert(NAME##View && "RegisterCodeGenFlags not created.");                 \
36     return *NAME##View;                                                        \
37   }
38 
39 #define CGLIST(TY, NAME)                                                       \
40   static cl::list<TY> *NAME##View;                                             \
41   std::vector<TY> codegen::get##NAME() {                                       \
42     assert(NAME##View && "RegisterCodeGenFlags not created.");                 \
43     return *NAME##View;                                                        \
44   }
45 
46 // Temporary macro for incremental transition to std::optional.
47 #define CGOPT_EXP(TY, NAME)                                                    \
48   CGOPT(TY, NAME)                                                              \
49   std::optional<TY> codegen::getExplicit##NAME() {                             \
50     if (NAME##View->getNumOccurrences()) {                                     \
51       TY res = *NAME##View;                                                    \
52       return res;                                                              \
53     }                                                                          \
54     return std::nullopt;                                                       \
55   }
56 
57 CGOPT(std::string, MArch)
58 CGOPT(std::string, MCPU)
59 CGLIST(std::string, MAttrs)
60 CGOPT_EXP(Reloc::Model, RelocModel)
61 CGOPT(ThreadModel::Model, ThreadModel)
62 CGOPT_EXP(CodeModel::Model, CodeModel)
63 CGOPT_EXP(uint64_t, LargeDataThreshold)
64 CGOPT(ExceptionHandling, ExceptionModel)
65 CGOPT_EXP(CodeGenFileType, FileType)
66 CGOPT(FramePointerKind, FramePointerUsage)
67 CGOPT(bool, EnableUnsafeFPMath)
68 CGOPT(bool, EnableNoInfsFPMath)
69 CGOPT(bool, EnableNoNaNsFPMath)
70 CGOPT(bool, EnableNoSignedZerosFPMath)
71 CGOPT(bool, EnableApproxFuncFPMath)
72 CGOPT(bool, EnableNoTrappingFPMath)
73 CGOPT(bool, EnableAIXExtendedAltivecABI)
74 CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath)
75 CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)
76 CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
77 CGOPT(FloatABI::ABIType, FloatABIForCalls)
78 CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)
79 CGOPT(SwiftAsyncFramePointerMode, SwiftAsyncFramePointer)
80 CGOPT(bool, DontPlaceZerosInBSS)
81 CGOPT(bool, EnableGuaranteedTailCallOpt)
82 CGOPT(bool, DisableTailCalls)
83 CGOPT(bool, StackSymbolOrdering)
84 CGOPT(bool, StackRealign)
85 CGOPT(std::string, TrapFuncName)
86 CGOPT(bool, UseCtors)
87 CGOPT(bool, DisableIntegratedAS)
88 CGOPT(bool, RelaxELFRelocations)
89 CGOPT_EXP(bool, DataSections)
90 CGOPT_EXP(bool, FunctionSections)
91 CGOPT(bool, IgnoreXCOFFVisibility)
92 CGOPT(bool, XCOFFTracebackTable)
93 CGOPT(bool, EnableBBAddrMap)
94 CGOPT(std::string, BBSections)
95 CGOPT(unsigned, TLSSize)
96 CGOPT_EXP(bool, EmulatedTLS)
97 CGOPT_EXP(bool, EnableTLSDESC)
98 CGOPT(bool, UniqueSectionNames)
99 CGOPT(bool, UniqueBasicBlockSectionNames)
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::None, "none",
215                      "Enable frame pointer elimination")));
216   CGBINDOPT(FramePointerUsage);
217 
218   static cl::opt<bool> EnableUnsafeFPMath(
219       "enable-unsafe-fp-math",
220       cl::desc("Enable optimizations that may decrease FP precision"),
221       cl::init(false));
222   CGBINDOPT(EnableUnsafeFPMath);
223 
224   static cl::opt<bool> EnableNoInfsFPMath(
225       "enable-no-infs-fp-math",
226       cl::desc("Enable FP math optimizations that assume no +-Infs"),
227       cl::init(false));
228   CGBINDOPT(EnableNoInfsFPMath);
229 
230   static cl::opt<bool> EnableNoNaNsFPMath(
231       "enable-no-nans-fp-math",
232       cl::desc("Enable FP math optimizations that assume no NaNs"),
233       cl::init(false));
234   CGBINDOPT(EnableNoNaNsFPMath);
235 
236   static cl::opt<bool> EnableNoSignedZerosFPMath(
237       "enable-no-signed-zeros-fp-math",
238       cl::desc("Enable FP math optimizations that assume "
239                "the sign of 0 is insignificant"),
240       cl::init(false));
241   CGBINDOPT(EnableNoSignedZerosFPMath);
242 
243   static cl::opt<bool> EnableApproxFuncFPMath(
244       "enable-approx-func-fp-math",
245       cl::desc("Enable FP math optimizations that assume approx func"),
246       cl::init(false));
247   CGBINDOPT(EnableApproxFuncFPMath);
248 
249   static cl::opt<bool> EnableNoTrappingFPMath(
250       "enable-no-trapping-fp-math",
251       cl::desc("Enable setting the FP exceptions build "
252                "attribute not to use exceptions"),
253       cl::init(false));
254   CGBINDOPT(EnableNoTrappingFPMath);
255 
256   static const auto DenormFlagEnumOptions = cl::values(
257       clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"),
258       clEnumValN(DenormalMode::PreserveSign, "preserve-sign",
259                  "the sign of a  flushed-to-zero number is preserved "
260                  "in the sign of 0"),
261       clEnumValN(DenormalMode::PositiveZero, "positive-zero",
262                  "denormals are flushed to positive zero"),
263       clEnumValN(DenormalMode::Dynamic, "dynamic",
264                  "denormals have unknown treatment"));
265 
266   // FIXME: Doesn't have way to specify separate input and output modes.
267   static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath(
268     "denormal-fp-math",
269     cl::desc("Select which denormal numbers the code is permitted to require"),
270     cl::init(DenormalMode::IEEE),
271     DenormFlagEnumOptions);
272   CGBINDOPT(DenormalFPMath);
273 
274   static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math(
275     "denormal-fp-math-f32",
276     cl::desc("Select which denormal numbers the code is permitted to require for float"),
277     cl::init(DenormalMode::Invalid),
278     DenormFlagEnumOptions);
279   CGBINDOPT(DenormalFP32Math);
280 
281   static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
282       "enable-sign-dependent-rounding-fp-math", cl::Hidden,
283       cl::desc("Force codegen to assume rounding mode can change dynamically"),
284       cl::init(false));
285   CGBINDOPT(EnableHonorSignDependentRoundingFPMath);
286 
287   static cl::opt<FloatABI::ABIType> FloatABIForCalls(
288       "float-abi", cl::desc("Choose float ABI type"),
289       cl::init(FloatABI::Default),
290       cl::values(clEnumValN(FloatABI::Default, "default",
291                             "Target default float ABI type"),
292                  clEnumValN(FloatABI::Soft, "soft",
293                             "Soft float ABI (implied by -soft-float)"),
294                  clEnumValN(FloatABI::Hard, "hard",
295                             "Hard float ABI (uses FP registers)")));
296   CGBINDOPT(FloatABIForCalls);
297 
298   static cl::opt<FPOpFusion::FPOpFusionMode> FuseFPOps(
299       "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
300       cl::init(FPOpFusion::Standard),
301       cl::values(
302           clEnumValN(FPOpFusion::Fast, "fast",
303                      "Fuse FP ops whenever profitable"),
304           clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
305           clEnumValN(FPOpFusion::Strict, "off",
306                      "Only fuse FP ops when the result won't be affected.")));
307   CGBINDOPT(FuseFPOps);
308 
309   static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer(
310       "swift-async-fp",
311       cl::desc("Determine when the Swift async frame pointer should be set"),
312       cl::init(SwiftAsyncFramePointerMode::Always),
313       cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto",
314                             "Determine based on deployment target"),
315                  clEnumValN(SwiftAsyncFramePointerMode::Always, "always",
316                             "Always set the bit"),
317                  clEnumValN(SwiftAsyncFramePointerMode::Never, "never",
318                             "Never set the bit")));
319   CGBINDOPT(SwiftAsyncFramePointer);
320 
321   static cl::opt<bool> DontPlaceZerosInBSS(
322       "nozero-initialized-in-bss",
323       cl::desc("Don't place zero-initialized symbols into bss section"),
324       cl::init(false));
325   CGBINDOPT(DontPlaceZerosInBSS);
326 
327   static cl::opt<bool> EnableAIXExtendedAltivecABI(
328       "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),
329       cl::init(false));
330   CGBINDOPT(EnableAIXExtendedAltivecABI);
331 
332   static cl::opt<bool> EnableGuaranteedTailCallOpt(
333       "tailcallopt",
334       cl::desc(
335           "Turn fastcc calls into tail calls by (potentially) changing ABI."),
336       cl::init(false));
337   CGBINDOPT(EnableGuaranteedTailCallOpt);
338 
339   static cl::opt<bool> DisableTailCalls(
340       "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false));
341   CGBINDOPT(DisableTailCalls);
342 
343   static cl::opt<bool> StackSymbolOrdering(
344       "stack-symbol-ordering", cl::desc("Order local stack symbols."),
345       cl::init(true));
346   CGBINDOPT(StackSymbolOrdering);
347 
348   static cl::opt<bool> StackRealign(
349       "stackrealign",
350       cl::desc("Force align the stack to the minimum alignment"),
351       cl::init(false));
352   CGBINDOPT(StackRealign);
353 
354   static cl::opt<std::string> TrapFuncName(
355       "trap-func", cl::Hidden,
356       cl::desc("Emit a call to trap function rather than a trap instruction"),
357       cl::init(""));
358   CGBINDOPT(TrapFuncName);
359 
360   static cl::opt<bool> UseCtors("use-ctors",
361                                 cl::desc("Use .ctors instead of .init_array."),
362                                 cl::init(false));
363   CGBINDOPT(UseCtors);
364 
365   static cl::opt<bool> RelaxELFRelocations(
366       "x86-relax-relocations",
367       cl::desc(
368           "Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
369       cl::init(true));
370   CGBINDOPT(RelaxELFRelocations);
371 
372   static cl::opt<bool> DataSections(
373       "data-sections", cl::desc("Emit data into separate sections"),
374       cl::init(false));
375   CGBINDOPT(DataSections);
376 
377   static cl::opt<bool> FunctionSections(
378       "function-sections", cl::desc("Emit functions into separate sections"),
379       cl::init(false));
380   CGBINDOPT(FunctionSections);
381 
382   static cl::opt<bool> IgnoreXCOFFVisibility(
383       "ignore-xcoff-visibility",
384       cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
385                "all symbols 'unspecified' visibility in XCOFF object file"),
386       cl::init(false));
387   CGBINDOPT(IgnoreXCOFFVisibility);
388 
389   static cl::opt<bool> XCOFFTracebackTable(
390       "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
391       cl::init(true));
392   CGBINDOPT(XCOFFTracebackTable);
393 
394   static cl::opt<bool> EnableBBAddrMap(
395       "basic-block-address-map",
396       cl::desc("Emit the basic block address map section"), cl::init(false));
397   CGBINDOPT(EnableBBAddrMap);
398 
399   static cl::opt<std::string> BBSections(
400       "basic-block-sections",
401       cl::desc("Emit basic blocks into separate sections"),
402       cl::value_desc("all | <function list (file)> | labels | none"),
403       cl::init("none"));
404   CGBINDOPT(BBSections);
405 
406   static cl::opt<unsigned> TLSSize(
407       "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
408   CGBINDOPT(TLSSize);
409 
410   static cl::opt<bool> EmulatedTLS(
411       "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
412   CGBINDOPT(EmulatedTLS);
413 
414   static cl::opt<bool> EnableTLSDESC(
415       "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"),
416       cl::init(false));
417   CGBINDOPT(EnableTLSDESC);
418 
419   static cl::opt<bool> UniqueSectionNames(
420       "unique-section-names", cl::desc("Give unique names to every section"),
421       cl::init(true));
422   CGBINDOPT(UniqueSectionNames);
423 
424   static cl::opt<bool> UniqueBasicBlockSectionNames(
425       "unique-basic-block-section-names",
426       cl::desc("Give unique names to every basic block section"),
427       cl::init(false));
428   CGBINDOPT(UniqueBasicBlockSectionNames);
429 
430   static cl::opt<EABI> EABIVersion(
431       "meabi", cl::desc("Set EABI type (default depends on triple):"),
432       cl::init(EABI::Default),
433       cl::values(
434           clEnumValN(EABI::Default, "default", "Triple default EABI version"),
435           clEnumValN(EABI::EABI4, "4", "EABI version 4"),
436           clEnumValN(EABI::EABI5, "5", "EABI version 5"),
437           clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
438   CGBINDOPT(EABIVersion);
439 
440   static cl::opt<DebuggerKind> DebuggerTuningOpt(
441       "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
442       cl::init(DebuggerKind::Default),
443       cl::values(
444           clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
445           clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
446           clEnumValN(DebuggerKind::DBX, "dbx", "dbx"),
447           clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
448   CGBINDOPT(DebuggerTuningOpt);
449 
450   static cl::opt<bool> EnableStackSizeSection(
451       "stack-size-section",
452       cl::desc("Emit a section containing stack size metadata"),
453       cl::init(false));
454   CGBINDOPT(EnableStackSizeSection);
455 
456   static cl::opt<bool> EnableAddrsig(
457       "addrsig", cl::desc("Emit an address-significance table"),
458       cl::init(false));
459   CGBINDOPT(EnableAddrsig);
460 
461   static cl::opt<bool> EmitCallSiteInfo(
462       "emit-call-site-info",
463       cl::desc(
464           "Emit call site debug information, if debug information is enabled."),
465       cl::init(false));
466   CGBINDOPT(EmitCallSiteInfo);
467 
468   static cl::opt<bool> EnableDebugEntryValues(
469       "debug-entry-values",
470       cl::desc("Enable debug info for the debug entry values."),
471       cl::init(false));
472   CGBINDOPT(EnableDebugEntryValues);
473 
474   static cl::opt<bool> EnableMachineFunctionSplitter(
475       "split-machine-functions",
476       cl::desc("Split out cold basic blocks from machine functions based on "
477                "profile information"),
478       cl::init(false));
479   CGBINDOPT(EnableMachineFunctionSplitter);
480 
481   static cl::opt<bool> ForceDwarfFrameSection(
482       "force-dwarf-frame-section",
483       cl::desc("Always emit a debug frame section."), cl::init(false));
484   CGBINDOPT(ForceDwarfFrameSection);
485 
486   static cl::opt<bool> XRayFunctionIndex("xray-function-index",
487                                          cl::desc("Emit xray_fn_idx section"),
488                                          cl::init(true));
489   CGBINDOPT(XRayFunctionIndex);
490 
491   static cl::opt<bool> DebugStrictDwarf(
492       "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false));
493   CGBINDOPT(DebugStrictDwarf);
494 
495   static cl::opt<unsigned> AlignLoops("align-loops",
496                                       cl::desc("Default alignment for loops"));
497   CGBINDOPT(AlignLoops);
498 
499   static cl::opt<bool> JMCInstrument(
500       "enable-jmc-instrument",
501       cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"),
502       cl::init(false));
503   CGBINDOPT(JMCInstrument);
504 
505   static cl::opt<bool> XCOFFReadOnlyPointers(
506       "mxcoff-roptr",
507       cl::desc("When set to true, const objects with relocatable address "
508                "values are put into the RO data section."),
509       cl::init(false));
510   CGBINDOPT(XCOFFReadOnlyPointers);
511 
512   static cl::opt<bool> DisableIntegratedAS(
513       "no-integrated-as", cl::desc("Disable integrated assembler"),
514       cl::init(false));
515   CGBINDOPT(DisableIntegratedAS);
516 
517 #undef CGBINDOPT
518 
519   mc::RegisterMCTargetOptionsFlags();
520 }
521 
522 llvm::BasicBlockSection
523 codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
524   if (getBBSections() == "all")
525     return BasicBlockSection::All;
526   else if (getBBSections() == "labels")
527     return BasicBlockSection::Labels;
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.RelaxELFRelocations = getRelaxELFRelocations();
572   Options.DataSections =
573       getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections());
574   Options.FunctionSections = getFunctionSections();
575   Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
576   Options.XCOFFTracebackTable = getXCOFFTracebackTable();
577   Options.BBAddrMap = getEnableBBAddrMap();
578   Options.BBSections = getBBSectionsMode(Options);
579   Options.UniqueSectionNames = getUniqueSectionNames();
580   Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
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     StringMap<bool> HostFeatures;
627     if (sys::getHostCPUFeatures(HostFeatures))
628       for (const auto &[Feature, IsEnabled] : HostFeatures)
629         Features.AddFeature(Feature, IsEnabled);
630   }
631 
632   for (auto const &MAttr : getMAttrs())
633     Features.AddFeature(MAttr);
634 
635   return Features.getString();
636 }
637 
638 std::vector<std::string> codegen::getFeatureList() {
639   SubtargetFeatures Features;
640 
641   // If user asked for the 'native' CPU, we need to autodetect features.
642   // This is necessary for x86 where the CPU might not support all the
643   // features the autodetected CPU name lists in the target. For example,
644   // not all Sandybridge processors support AVX.
645   if (getMCPU() == "native") {
646     StringMap<bool> HostFeatures;
647     if (sys::getHostCPUFeatures(HostFeatures))
648       for (const auto &[Feature, IsEnabled] : HostFeatures)
649         Features.AddFeature(Feature, IsEnabled);
650   }
651 
652   for (auto const &MAttr : getMAttrs())
653     Features.AddFeature(MAttr);
654 
655   return Features.getFeatures();
656 }
657 
658 void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
659   B.addAttribute(Name, Val ? "true" : "false");
660 }
661 
662 #define HANDLE_BOOL_ATTR(CL, AttrName)                                         \
663   do {                                                                         \
664     if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName))            \
665       renderBoolStringAttr(NewAttrs, AttrName, *CL);                           \
666   } while (0)
667 
668 /// Set function attributes of function \p F based on CPU, Features, and command
669 /// line flags.
670 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
671                                     Function &F) {
672   auto &Ctx = F.getContext();
673   AttributeList Attrs = F.getAttributes();
674   AttrBuilder NewAttrs(Ctx);
675 
676   if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
677     NewAttrs.addAttribute("target-cpu", CPU);
678   if (!Features.empty()) {
679     // Append the command line features to any that are already on the function.
680     StringRef OldFeatures =
681         F.getFnAttribute("target-features").getValueAsString();
682     if (OldFeatures.empty())
683       NewAttrs.addAttribute("target-features", Features);
684     else {
685       SmallString<256> Appended(OldFeatures);
686       Appended.push_back(',');
687       Appended.append(Features);
688       NewAttrs.addAttribute("target-features", Appended);
689     }
690   }
691   if (FramePointerUsageView->getNumOccurrences() > 0 &&
692       !F.hasFnAttribute("frame-pointer")) {
693     if (getFramePointerUsage() == FramePointerKind::All)
694       NewAttrs.addAttribute("frame-pointer", "all");
695     else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
696       NewAttrs.addAttribute("frame-pointer", "non-leaf");
697     else if (getFramePointerUsage() == FramePointerKind::None)
698       NewAttrs.addAttribute("frame-pointer", "none");
699   }
700   if (DisableTailCallsView->getNumOccurrences() > 0)
701     NewAttrs.addAttribute("disable-tail-calls",
702                           toStringRef(getDisableTailCalls()));
703   if (getStackRealign())
704     NewAttrs.addAttribute("stackrealign");
705 
706   HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math");
707   HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");
708   HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");
709   HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");
710   HANDLE_BOOL_ATTR(EnableApproxFuncFPMathView, "approx-func-fp-math");
711 
712   if (DenormalFPMathView->getNumOccurrences() > 0 &&
713       !F.hasFnAttribute("denormal-fp-math")) {
714     DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
715 
716     // FIXME: Command line flag should expose separate input/output modes.
717     NewAttrs.addAttribute("denormal-fp-math",
718                           DenormalMode(DenormKind, DenormKind).str());
719   }
720 
721   if (DenormalFP32MathView->getNumOccurrences() > 0 &&
722       !F.hasFnAttribute("denormal-fp-math-f32")) {
723     // FIXME: Command line flag should expose separate input/output modes.
724     DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math();
725 
726     NewAttrs.addAttribute(
727       "denormal-fp-math-f32",
728       DenormalMode(DenormKind, DenormKind).str());
729   }
730 
731   if (TrapFuncNameView->getNumOccurrences() > 0)
732     for (auto &B : F)
733       for (auto &I : B)
734         if (auto *Call = dyn_cast<CallInst>(&I))
735           if (const auto *F = Call->getCalledFunction())
736             if (F->getIntrinsicID() == Intrinsic::debugtrap ||
737                 F->getIntrinsicID() == Intrinsic::trap)
738               Call->addFnAttr(
739                   Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));
740 
741   // Let NewAttrs override Attrs.
742   F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs));
743 }
744 
745 /// Set function attributes of functions in Module M based on CPU,
746 /// Features, and command line flags.
747 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
748                                     Module &M) {
749   for (Function &F : M)
750     setFunctionAttributes(CPU, Features, F);
751 }
752 
753 Expected<std::unique_ptr<TargetMachine>>
754 codegen::createTargetMachineForTriple(StringRef TargetTriple,
755                                       CodeGenOptLevel OptLevel) {
756   Triple TheTriple(TargetTriple);
757   std::string Error;
758   const auto *TheTarget =
759       TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
760   if (!TheTarget)
761     return createStringError(inconvertibleErrorCode(), Error);
762   auto *Target = TheTarget->createTargetMachine(
763       TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(),
764       codegen::InitTargetOptionsFromCodeGenFlags(TheTriple),
765       codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(),
766       OptLevel);
767   if (!Target)
768     return createStringError(inconvertibleErrorCode(),
769                              Twine("could not allocate target machine for ") +
770                                  TargetTriple);
771   return std::unique_ptr<TargetMachine>(Target);
772 }
773