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