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